Coverage Report

Created: 2026-07-24 07:44

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
    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.25M
{
240
4.25M
    set_dev_proc(dev, initialize_device, pdf14_initialize_device);
241
4.25M
    set_dev_proc(dev, open_device, pdf14_open);
242
4.25M
    set_dev_proc(dev, output_page, pdf14_output_page);
243
4.25M
    set_dev_proc(dev, close_device, pdf14_close);
244
4.25M
    set_dev_proc(dev, map_rgb_color, encode_color);
245
4.25M
    set_dev_proc(dev, map_color_rgb, decode_color);
246
4.25M
    set_dev_proc(dev, fill_rectangle, pdf14_fill_rectangle);
247
4.25M
    set_dev_proc(dev, copy_mono, pdf14_copy_mono);
248
4.25M
    set_dev_proc(dev, get_params, gx_forward_get_params);
249
4.25M
    set_dev_proc(dev, put_params, pdf14_put_params);
250
4.25M
    set_dev_proc(dev, copy_alpha, pdf14_copy_alpha);
251
4.25M
    set_dev_proc(dev, fill_path, pdf14_fill_path);
252
4.25M
    set_dev_proc(dev, stroke_path, pdf14_stroke_path);
253
4.25M
    set_dev_proc(dev, fill_mask, pdf14_fill_mask);
254
4.25M
    set_dev_proc(dev, begin_typed_image, pdf14_begin_typed_image);
255
4.25M
    set_dev_proc(dev, composite, pdf14_composite);
256
4.25M
    set_dev_proc(dev, text_begin, pdf14_text_begin);
257
4.25M
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
258
4.25M
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
259
4.25M
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
260
4.25M
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
261
4.25M
    set_dev_proc(dev, discard_transparency_layer, pdf14_discard_trans_layer);
262
4.25M
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
263
4.25M
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
264
4.25M
    set_dev_proc(dev, encode_color, encode_color);
265
4.25M
    set_dev_proc(dev, decode_color, decode_color);
266
4.25M
    set_dev_proc(dev, fill_rectangle_hl_color, pdf14_fill_rectangle_hl_color);
267
4.25M
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
268
4.25M
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
269
4.25M
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
270
4.25M
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
271
4.25M
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
272
4.25M
    set_dev_proc(dev, copy_planes, pdf14_copy_planes);
273
4.25M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
274
4.25M
    set_dev_proc(dev, strip_tile_rect_devn, pdf14_strip_tile_rect_devn);
275
4.25M
    set_dev_proc(dev, copy_alpha_hl_color, pdf14_copy_alpha_hl_color);
276
4.25M
    set_dev_proc(dev, fill_stroke_path, pdf14_fill_stroke_path);
277
4.25M
}
278
279
static void
280
pdf14_Gray_initialize_device_procs(gx_device *dev)
281
1.26M
{
282
1.26M
    pdf14_procs_initialize(dev,
283
1.26M
                           gx_default_DevGray_get_color_mapping_procs,
284
1.26M
                           gx_default_DevGray_get_color_comp_index,
285
1.26M
                           pdf14_encode_color,
286
1.26M
                           pdf14_decode_color);
287
1.26M
}
288
289
static void
290
pdf14_RGB_initialize_device_procs(gx_device *dev)
291
2.57M
{
292
2.57M
    pdf14_procs_initialize(dev,
293
2.57M
                           gx_default_DevRGB_get_color_mapping_procs,
294
2.57M
                           gx_default_DevRGB_get_color_comp_index,
295
2.57M
                           pdf14_encode_color,
296
2.57M
                           pdf14_decode_color);
297
2.57M
}
298
299
static void
300
pdf14_CMYK_initialize_device_procs(gx_device *dev)
301
199k
{
302
199k
    pdf14_procs_initialize(dev,
303
199k
                           gx_default_DevCMYK_get_color_mapping_procs,
304
199k
                           gx_default_DevCMYK_get_color_comp_index,
305
199k
                           pdf14_encode_color,
306
199k
                           pdf14_decode_color);
307
199k
}
308
309
static void
310
pdf14_CMYKspot_initialize_device_procs(gx_device *dev)
311
157k
{
312
157k
    pdf14_procs_initialize(dev,
313
157k
                           pdf14_cmykspot_get_color_mapping_procs,
314
157k
                           pdf14_cmykspot_get_color_comp_index,
315
157k
                           pdf14_encode_color,
316
157k
                           pdf14_decode_color);
317
157k
}
318
319
static void
320
pdf14_RGBspot_initialize_device_procs(gx_device *dev)
321
58.9k
{
322
58.9k
    pdf14_procs_initialize(dev,
323
58.9k
                           pdf14_rgbspot_get_color_mapping_procs,
324
58.9k
                           pdf14_rgbspot_get_color_comp_index,
325
58.9k
                           pdf14_encode_color,
326
58.9k
                           pdf14_decode_color);
327
58.9k
}
328
329
static void
330
pdf14_Grayspot_initialize_device_procs(gx_device *dev)
331
0
{
332
0
    pdf14_procs_initialize(dev,
333
0
                           pdf14_grayspot_get_color_mapping_procs,
334
0
                           pdf14_grayspot_get_color_comp_index,
335
0
                           pdf14_encode_color,
336
0
                           pdf14_decode_color);
337
0
}
338
339
static void
340
pdf14_custom_initialize_device_procs(gx_device *dev)
341
0
{
342
0
    pdf14_procs_initialize(dev,
343
0
                           gx_forward_get_color_mapping_procs,
344
0
                           gx_forward_get_color_comp_index,
345
0
                           gx_forward_encode_color,
346
0
                           gx_forward_decode_color);
347
0
}
348
349
static struct_proc_finalize(pdf14_device_finalize);
350
351
gs_private_st_composite_use_final(st_pdf14_device, pdf14_device, "pdf14_device",
352
                                  pdf14_device_enum_ptrs, pdf14_device_reloc_ptrs,
353
                          pdf14_device_finalize);
354
355
static int pdf14_put_image(gx_device * dev, gs_gstate * pgs,
356
                                                        gx_device * target);
357
static int pdf14_cmykspot_put_image(gx_device * dev, gs_gstate * pgs,
358
                                                        gx_device * target);
359
static int pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs,
360
                                                        gx_device * target);
361
362
/* Alter pdf14 device color model based upon group or softmask. This occurs
363
   post clist or in immediate rendering case. Data stored with buffer */
364
static pdf14_group_color_t* pdf14_push_color_model(gx_device *dev,
365
                              gs_transparency_color_t group_color, int64_t icc_hashcode,
366
                              cmm_profile_t *iccprofile, bool is_mask);
367
static void pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color);
368
369
/* Alter clist writer device color model based upon group or softmask. Data
370
   stored in the device color model stack */
371
static int pdf14_clist_push_color_model(gx_device* dev, gx_device* cdev, gs_gstate* pgs,
372
    const gs_pdf14trans_t* pdf14pct, gs_memory_t* mem, bool is_mask);
373
static int pdf14_clist_pop_color_model(gx_device* dev, gs_gstate* pgs);
374
375
/* Used for cleaning up the stack if things go wrong */
376
static void pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs);
377
378
static const pdf14_procs_t gray_pdf14_procs = {
379
    pdf14_unpack_additive,
380
    pdf14_put_image,
381
    pdf14_unpack16_additive
382
};
383
384
static const pdf14_procs_t rgb_pdf14_procs = {
385
    pdf14_unpack_additive,
386
    pdf14_put_image,
387
    pdf14_unpack16_additive
388
};
389
390
static const pdf14_procs_t cmyk_pdf14_procs = {
391
    pdf14_unpack_subtractive,
392
    pdf14_put_image,
393
    pdf14_unpack16_subtractive
394
};
395
396
static const pdf14_procs_t cmykspot_pdf14_procs = {
397
    pdf14_unpack_custom,  /* should never be used since we will use devn values */
398
    pdf14_cmykspot_put_image,
399
    pdf14_unpack16_custom /* should never be used since we will use devn values */
400
};
401
402
static const pdf14_procs_t rgbspot_pdf14_procs = {
403
    pdf14_unpack_rgb_mix,
404
    pdf14_cmykspot_put_image,
405
    pdf14_unpack16_rgb_mix
406
};
407
408
static const pdf14_procs_t grayspot_pdf14_procs = {
409
    pdf14_unpack_gray_mix,
410
    pdf14_cmykspot_put_image,
411
    pdf14_unpack16_gray_mix
412
};
413
414
static const pdf14_procs_t custom_pdf14_procs = {
415
    pdf14_unpack_custom,
416
    pdf14_custom_put_image,
417
    pdf14_unpack16_custom
418
};
419
420
static const pdf14_nonseparable_blending_procs_t gray_blending_procs = {
421
    art_blend_luminosity_custom_8,
422
    art_blend_saturation_custom_8,
423
    art_blend_luminosity_custom_16,
424
    art_blend_saturation_custom_16
425
};
426
427
static const pdf14_nonseparable_blending_procs_t rgb_blending_procs = {
428
    art_blend_luminosity_rgb_8,
429
    art_blend_saturation_rgb_8,
430
    art_blend_luminosity_rgb_16,
431
    art_blend_saturation_rgb_16
432
};
433
434
static const pdf14_nonseparable_blending_procs_t cmyk_blending_procs = {
435
    art_blend_luminosity_cmyk_8,
436
    art_blend_saturation_cmyk_8,
437
    art_blend_luminosity_cmyk_16,
438
    art_blend_saturation_cmyk_16
439
};
440
441
static const pdf14_nonseparable_blending_procs_t rgbspot_blending_procs = {
442
    art_blend_luminosity_rgb_8,
443
    art_blend_saturation_rgb_8,
444
    art_blend_luminosity_rgb_16,
445
    art_blend_saturation_rgb_16
446
};
447
448
static const pdf14_nonseparable_blending_procs_t grayspot_blending_procs = {
449
    art_blend_luminosity_custom_8,
450
    art_blend_saturation_custom_8,
451
    art_blend_luminosity_custom_16,
452
    art_blend_saturation_custom_16
453
};
454
455
static const pdf14_nonseparable_blending_procs_t custom_blending_procs = {
456
    art_blend_luminosity_custom_8,
457
    art_blend_saturation_custom_8,
458
    art_blend_luminosity_custom_16,
459
    art_blend_saturation_custom_16
460
};
461
462
const pdf14_device gs_pdf14_Gray_device = {
463
    std_device_std_color_full_body_type(pdf14_device,
464
                                        pdf14_Gray_initialize_device_procs,
465
                                        "pdf14gray",
466
                                        &st_pdf14_device,
467
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 8,
468
                                        0, 0, 0, 0, 0, 0),
469
    { 0 },      /* Procs */
470
    NULL,     /* target */
471
    { 0 },      /* devn_params - not used */
472
    &gray_pdf14_procs,
473
    &gray_blending_procs,
474
    1
475
};
476
477
const pdf14_device gs_pdf14_RGB_device = {
478
    std_device_color_stype_body(pdf14_device,
479
                                pdf14_RGB_initialize_device_procs,
480
                                "pdf14RGB",
481
                                &st_pdf14_device,
482
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
483
    { 0 },      /* Procs */
484
    NULL,     /* target */
485
    { 0 },      /* devn_params - not used */
486
    &rgb_pdf14_procs,
487
    &rgb_blending_procs,
488
    3
489
};
490
491
const pdf14_device gs_pdf14_CMYK_device = {
492
    std_device_std_color_full_body_type(pdf14_device,
493
                                        pdf14_CMYK_initialize_device_procs,
494
                                        "pdf14cmyk",
495
                                        &st_pdf14_device,
496
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
497
                                        0, 0, 0, 0, 0, 0),
498
    { 0 },      /* Procs */
499
    NULL,     /* target */
500
    { 0 },      /* devn_params - not used */
501
    &cmyk_pdf14_procs,
502
    &cmyk_blending_procs,
503
    4
504
};
505
506
const pdf14_device gs_pdf14_CMYKspot_device = {
507
    std_device_part1_(pdf14_device,
508
                      pdf14_CMYKspot_initialize_device_procs,
509
                      "pdf14cmykspot",
510
                      &st_pdf14_device,
511
                      open_init_closed),
512
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
513
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
514
    offset_margin_values(0, 0, 0, 0, 0, 0),
515
    std_device_part3_(),
516
    { 0 },      /* Procs */
517
    NULL,     /* target */
518
    /* DeviceN parameters */
519
    { 8,      /* Not used - Bits per color */
520
      DeviceCMYKComponents, /* Names of color model colorants */
521
      4,      /* Number colorants for CMYK */
522
      0,      /* MaxSeparations has not been specified */
523
      -1,     /* PageSpotColors has not been specified */
524
      {0},      /* SeparationNames */
525
      0,      /* SeparationOrder names */
526
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
527
    },
528
    &cmykspot_pdf14_procs,
529
    &cmyk_blending_procs,
530
    4
531
};
532
533
const pdf14_device gs_pdf14_RGBspot_device = {
534
    std_device_part1_(pdf14_device,
535
                      pdf14_RGBspot_initialize_device_procs,
536
                      "pdf14rgbspot",
537
                      &st_pdf14_device,
538
                      open_init_closed),
539
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
540
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
541
    offset_margin_values(0, 0, 0, 0, 0, 0),
542
    std_device_part3_(),
543
    { 0 },      /* Procs */
544
    NULL,     /* target */
545
                    /* DeviceN parameters */
546
    { 8,      /* Not used - Bits per color */
547
    0,              /* Names of color model colorants */
548
    3,          /* Number colorants for RGB */
549
    0,          /* MaxSeparations has not been specified */
550
    -1,         /* PageSpotColors has not been specified */
551
    { 0 },      /* SeparationNames */
552
    0,          /* SeparationOrder names */
553
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
554
    },
555
    &rgbspot_pdf14_procs,
556
    &rgbspot_blending_procs,
557
    3
558
};
559
560
const pdf14_device gs_pdf14_Grayspot_device = {
561
    std_device_part1_(pdf14_device,
562
                      pdf14_Grayspot_initialize_device_procs,
563
                      "pdf14grayspot",
564
                      &st_pdf14_device,
565
                      open_init_closed),
566
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
567
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
568
    offset_margin_values(0, 0, 0, 0, 0, 0),
569
    std_device_part3_(),
570
    { 0 },      /* Procs */
571
    NULL,     /* target */
572
                    /* DeviceN parameters */
573
    { 8,      /* Not used - Bits per color */
574
    0,              /* Names of color model colorants */
575
    3,          /* Number colorants for RGB */
576
    0,          /* MaxSeparations has not been specified */
577
    -1,         /* PageSpotColors has not been specified */
578
    { 0 },      /* SeparationNames */
579
    0,          /* SeparationOrder names */
580
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
581
    },
582
    &grayspot_pdf14_procs,
583
    &grayspot_blending_procs,
584
    1
585
};
586
587
/*
588
 * The 'custom' PDF 1.4 compositor device is for working with those devices
589
 * which support spot colors but do not have a CMYK process color model.
590
 *
591
 * This causes some problems with the Hue, Saturation, Color, and Luminosity
592
 * blending modes.  These blending modes are 'non separable' and depend upon
593
 * knowing the details of the blending color space.  However we use the
594
 * process color model of the output device for our blending color space.
595
 * With an unknown process color model, we have to fall back to some 'guesses'
596
 * about how to treat these blending modes.
597
 */
598
const pdf14_device gs_pdf14_custom_device = {
599
    std_device_part1_(pdf14_device,
600
                      pdf14_custom_initialize_device_procs,
601
                      "pdf14custom",
602
                      &st_pdf14_device,
603
                      open_init_closed),
604
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
605
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
606
    offset_margin_values(0, 0, 0, 0, 0, 0),
607
    std_device_part3_(),
608
    { 0 },      /* Procs */
609
    NULL,     /* target */
610
    /* DeviceN parameters */
611
    { 8,      /* Not used - Bits per color */
612
      DeviceCMYKComponents, /* Names of color model colorants */
613
      4,      /* Number colorants for CMYK */
614
      0,      /* MaxSeparations has not been specified */
615
      -1,     /* PageSpotColors has not been specified */
616
      {0},      /* SeparationNames */
617
      0,      /* SeparationOrder names */
618
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
619
    },
620
    &custom_pdf14_procs,
621
    &custom_blending_procs,
622
    4
623
};
624
625
/* Devices used for pdf14-accum-* device, one for  each image colorspace, */
626
/* Gray, RGB, CMYK, DeviceN. Before calling gdev_prn_open, the following  */
627
/* are set from the target device: width, height, xdpi, ydpi, MaxBitmap.  */
628
629
static dev_proc_print_page(no_print_page);
630
static  dev_proc_ret_devn_params(pdf14_accum_ret_devn_params);
631
static  dev_proc_get_color_comp_index(pdf14_accum_get_color_comp_index);
632
static  dev_proc_get_color_mapping_procs(pdf14_accum_get_color_mapping_procs);
633
static  dev_proc_update_spot_equivalent_colors(pdf14_accum_update_spot_equivalent_colors);
634
635
static int
636
no_print_page(gx_device_printer *pdev, gp_file *prn_stream)
637
0
{
638
0
    return_error(gs_error_unknownerror);
639
0
}
640
641
struct gx_device_pdf14_accum_s {
642
    gx_devn_prn_device_common;
643
    gx_device *save_p14dev;   /* the non-clist pdf14 deivce saved for after accum */
644
};
645
typedef struct gx_device_pdf14_accum_s gx_device_pdf14_accum;
646
647
int
648
pdf14_accum_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size)
649
5.56M
{
650
5.56M
    gx_device_pdf14_accum *adev = (gx_device_pdf14_accum *)pdev;
651
652
5.56M
    if (dev_spec_op == gxdso_device_child) {
653
1.92k
        gxdso_device_child_request *req = (gxdso_device_child_request *)data;
654
1.92k
        if (size < sizeof(*req))
655
0
            return gs_error_unknownerror;
656
1.92k
        req->target = adev->save_p14dev;
657
1.92k
        req->n = 0;
658
1.92k
        return 0;
659
1.92k
    }
660
661
5.55M
    return gdev_prn_dev_spec_op(pdev, dev_spec_op, data, size);
662
5.56M
}
663
664
gs_private_st_suffix_add1_final(st_gx_devn_accum_device, gx_device_pdf14_accum,
665
        "gx_device_pdf14_accum", pdf14_accum_device_enum_ptrs, pdf14_accum_device_reloc_ptrs,
666
                          gx_devn_prn_device_finalize, st_gx_devn_prn_device, save_p14dev);
667
668
static void
669
pdf14_accum_Gray_initialize_device_procs(gx_device *dev)
670
672
{
671
672
    gdev_prn_initialize_device_procs_gray8(dev);
672
673
672
    set_dev_proc(dev, encode_color, gx_default_8bit_map_gray_color);
674
672
    set_dev_proc(dev, decode_color, gx_default_8bit_map_color_gray);
675
672
}
676
677
const gx_device_pdf14_accum pdf14_accum_Gray = {
678
    prn_device_stype_body(gx_device_pdf14_accum,
679
                          pdf14_accum_Gray_initialize_device_procs,
680
                          "pdf14-accum-Gray",
681
                          &st_gx_devn_accum_device,
682
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
683
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
684
                          1/*ncomp*/, 8/*depth*/, 255/*max_gray*/, 0/*max_color*/,
685
                          256/*dither_grays*/, 0/*dither_colors*/,
686
                          no_print_page),
687
    { 0 },      /* devn_params - not used */
688
    { 0 },      /* equivalent_cmyk_color_params - not used */
689
    0/*save_p14dev*/
690
};
691
692
static void
693
pdf14_accum_RGB_initialize_device_procs(gx_device *dev)
694
2.56k
{
695
2.56k
    gdev_prn_initialize_device_procs_rgb(dev);
696
2.56k
}
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
7.89M
                    for (i = 0; i < src_profile->num_comps; i++) {
868
5.92M
                        byte matte = maskbuf->matte[i]>>8;
869
5.92M
                        int val = src_curr_ptr[i * src_planestride] - matte;
870
5.92M
                        int temp = ((((val * 0xff) << 8) / matte_alpha) >> 8) + matte;
871
872
                        /* clip */
873
5.92M
                        if (temp > 0xff)
874
4.29M
                            src_curr_ptr[i * src_planestride] = 0xff;
875
1.62M
                        else if (temp < 0)
876
0
                            src_curr_ptr[i * src_planestride] = 0;
877
1.62M
                        else
878
1.62M
                            src_curr_ptr[i * src_planestride] = temp;
879
5.92M
                    }
880
1.97M
                }
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.5k
        byte *src_ptr;
950
10.5k
        byte *des_ptr;
951
952
10.5k
        *did_alloc = true;
953
10.5k
        des_rowstride = ((width + 3) & -4)<<deep;
954
10.5k
        des_planestride = height * des_rowstride;
955
10.5k
        des_n_planes = src_n_planes + diff - num_channels_to_lose;
956
10.5k
        des_n_chan = src_n_chan + diff;
957
10.5k
        des_data = gs_alloc_bytes(ctx->memory,
958
10.5k
                                  des_planestride * des_n_planes + CAL_SLOP,
959
10.5k
                                  "pdf14_transform_color_buffer");
960
10.5k
        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.5k
        src_ptr = src_data;
966
10.5k
        des_ptr = des_data;
967
114k
        for (j = 0; j < height; j++) {
968
208k
            for (k = 0; k < (src_n_planes - src_profile->num_comps); k++) {
969
104k
                memcpy(des_ptr + des_planestride * (k + des_profile->num_comps - num_channels_to_lose),
970
104k
                       src_ptr + src_planestride * (k + src_profile->num_comps),
971
104k
                       width<<deep);
972
104k
            }
973
103k
            src_ptr += src_rowstride;
974
103k
            des_ptr += des_rowstride;
975
103k
        }
976
10.5k
    } else
977
418
        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.5k
        gs_free_object(ctx->memory, output->data,
1016
10.5k
            "pdf14_transform_color_buffer");
1017
10.5k
        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.5k
        output->rect.p.x = x0;
1021
10.5k
        output->rect.p.y = y0;
1022
10.5k
        output->rect.q.x = x0 + width;
1023
10.5k
        output->rect.q.y = y0 + height;
1024
10.5k
    }
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.71k
{
1063
9.71k
    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.71k
    else
1067
9.71k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1068
9.71k
            des_profile, x0, y0, width, height, did_alloc, false, false, endian_swap, num_channels_to_lose);
1069
9.71k
}
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
2.77M
{
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
2.77M
    pdf14_buf *result;
1104
2.77M
    int64_t rowstride = ((size_t)((rect->q.x - rect->p.x + 3) & -4))<<deep;
1105
2.77M
    int64_t height = (rect->q.y - rect->p.y);
1106
2.77M
    int n_planes = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0) +
1107
2.77M
                   (has_tags ? 1 : 0);
1108
2.77M
    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
2.77M
    result = gs_alloc_struct(memory, pdf14_buf, &st_pdf14_buf,
1117
2.77M
                             "pdf14_buf_new");
1118
2.77M
    if (result == NULL)
1119
0
        return result;
1120
1121
2.77M
    result->memory = memory;
1122
2.77M
    result->backdrop = NULL;
1123
2.77M
    result->saved = NULL;
1124
2.77M
    result->isolated = false;
1125
2.77M
    result->knockout = false;
1126
2.77M
    result->has_alpha_g = has_alpha_g;
1127
2.77M
    result->has_shape = has_shape;
1128
2.77M
    result->has_tags = has_tags;
1129
2.77M
    result->rect = *rect;
1130
2.77M
    result->n_chan = n_chan;
1131
2.77M
    result->n_planes = n_planes;
1132
2.77M
    result->rowstride = rowstride;
1133
2.77M
    result->transfer_fn = NULL;
1134
2.77M
    result->is_ident = true;
1135
2.77M
    result->matte_num_comps = 0;
1136
2.77M
    result->matte = NULL;
1137
2.77M
    result->mask_stack = NULL;
1138
2.77M
    result->idle = idle;
1139
2.77M
    result->mask_id = 0;
1140
2.77M
    result->num_spots = num_spots;
1141
2.77M
    result->deep = deep;
1142
2.77M
    result->page_group = false;
1143
2.77M
    result->group_color_info = NULL;
1144
2.77M
    result->group_popped = false;
1145
1146
2.77M
    if (idle || height <= 0) {
1147
        /* Empty clipping - will skip all drawings. */
1148
1.27M
        result->planestride = 0;
1149
1.27M
        result->data = 0;
1150
1.49M
    } else {
1151
1.49M
        planestride = rowstride * height;
1152
1.49M
        result->planestride = planestride;
1153
1.49M
        result->data = gs_alloc_bytes(memory,
1154
1.49M
                                      planestride * n_planes + CAL_SLOP,
1155
1.49M
                                      "pdf14_buf_new");
1156
1.49M
        if (result->data == NULL) {
1157
0
            gs_free_object(memory, result, "pdf14_buf_new");
1158
0
            return NULL;
1159
0
        }
1160
1.49M
        if (has_alpha_g) {
1161
371k
            int alpha_g_plane = n_chan + (has_shape ? 1 : 0);
1162
            /* Memsetting by 0, so this copes with the deep case too */
1163
371k
            memset(result->data + alpha_g_plane * planestride, 0, planestride);
1164
371k
        }
1165
1.49M
        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.49M
    }
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
2.77M
    result->dirty.p.x = rect->q.x;
1176
2.77M
    result->dirty.p.y = rect->q.y;
1177
2.77M
    result->dirty.q.x = rect->p.x;
1178
2.77M
    result->dirty.q.y = rect->p.y;
1179
2.77M
    return result;
1180
2.77M
}
1181
1182
static  void
1183
pdf14_buf_free(pdf14_buf *buf)
1184
2.77M
{
1185
2.77M
    pdf14_group_color_t *group_color_info = buf->group_color_info;
1186
2.77M
    gs_memory_t *memory = buf->memory;
1187
1188
2.77M
    if (buf->mask_stack)
1189
2.77M
        rc_decrement(buf->mask_stack, "pdf14_buf_free");
1190
1191
2.77M
    gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free");
1192
2.77M
    gs_free_object(memory, buf->matte, "pdf14_buf_free");
1193
2.77M
    gs_free_object(memory, buf->data, "pdf14_buf_free");
1194
1195
5.54M
    while (group_color_info) {
1196
2.77M
       if (group_color_info->icc_profile != NULL) {
1197
2.77M
           gsicc_adjust_profile_rc(group_color_info->icc_profile, -1, "pdf14_buf_free");
1198
2.77M
       }
1199
2.77M
       buf->group_color_info = group_color_info->previous;
1200
2.77M
       gs_free_object(memory, group_color_info, "pdf14_buf_free");
1201
2.77M
       group_color_info = buf->group_color_info;
1202
2.77M
    }
1203
1204
2.77M
    gs_free_object(memory, buf->backdrop, "pdf14_buf_free");
1205
2.77M
    gs_free_object(memory, buf, "pdf14_buf_free");
1206
2.77M
}
1207
1208
static  pdf14_ctx *
1209
pdf14_ctx_new(gx_device *dev, bool deep)
1210
958k
{
1211
958k
    pdf14_ctx *result;
1212
958k
    gs_memory_t *memory = dev->memory->stable_memory;
1213
1214
958k
    result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx, "pdf14_ctx_new");
1215
958k
    if (result == NULL)
1216
0
        return result;
1217
958k
    result->stack = NULL;
1218
958k
    result->mask_stack = pdf14_mask_element_new(memory);
1219
958k
    if (result->mask_stack == NULL) {
1220
0
        gs_free_object(memory, result, "pdf14_ctx_new");
1221
0
        return NULL;
1222
0
    }
1223
958k
    result->memory = memory;
1224
958k
    result->smask_depth = 0;
1225
958k
    result->smask_blend = false;
1226
958k
    result->deep = deep;
1227
958k
    result->base_color = NULL;
1228
958k
    return result;
1229
958k
}
1230
1231
static  void
1232
pdf14_ctx_free(pdf14_ctx *ctx)
1233
958k
{
1234
958k
    pdf14_buf *buf, *next;
1235
1236
958k
    if (ctx->base_color) {
1237
495k
       gsicc_adjust_profile_rc(ctx->base_color->icc_profile, -1, "pdf14_ctx_free");
1238
495k
        gs_free_object(ctx->memory, ctx->base_color, "pdf14_ctx_free");
1239
495k
    }
1240
958k
    if (ctx->mask_stack) {
1241
        /* A mask was created but was not used in this band. */
1242
469k
        rc_decrement(ctx->mask_stack, "pdf14_ctx_free");
1243
469k
    }
1244
1.76M
    for (buf = ctx->stack; buf != NULL; buf = next) {
1245
809k
        next = buf->saved;
1246
809k
        pdf14_buf_free(buf);
1247
809k
    }
1248
958k
    gs_free_object (ctx->memory, ctx, "pdf14_ctx_free");
1249
958k
}
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
839k
{
1260
    /* Our new buffer is buf */
1261
839k
    pdf14_buf *buf = ctx->stack;
1262
1263
839k
    *is_backdrop = false;
1264
1265
839k
    if (buf != NULL) {
1266
        /* If the new buffer is isolated there is no backdrop */
1267
839k
        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
371k
        if (buf->saved != NULL && buf->saved->knockout) {
1273
            /* Per the spec, if we have a non-isolated group
1274
               in a knockout group the non-isolated group
1275
               uses the backdrop of its parent group (the knockout group)
1276
               as its own backdrop.  The non-isolated group must
1277
               go through the standard re-composition operation
1278
               to avoid the double application of the backdrop */
1279
14
            *is_backdrop = true;
1280
14
            return buf->saved;
1281
14
        }
1282
        /* This should be the non-isolated case where its parent is
1283
           not a knockout */
1284
371k
        if (buf->saved != NULL) {
1285
371k
            return buf->saved;
1286
371k
        }
1287
371k
    }
1288
0
    return NULL;
1289
839k
}
1290
1291
static pdf14_group_color_t*
1292
pdf14_make_base_group_color(gx_device* dev)
1293
495k
{
1294
495k
    pdf14_device* pdev = (pdf14_device*)dev;
1295
495k
    pdf14_group_color_t* group_color;
1296
495k
    bool deep = pdev->ctx->deep;
1297
495k
    bool has_tags = device_encodes_tags(dev);
1298
1299
495k
    if_debug0m('v', dev->memory, "[v]pdf14_make_base_group_color\n");
1300
1301
495k
    group_color = gs_alloc_struct(pdev->ctx->memory,
1302
495k
        pdf14_group_color_t, &st_pdf14_clr,
1303
495k
        "pdf14_make_base_group_color");
1304
1305
495k
    if (group_color == NULL)
1306
0
        return NULL;
1307
495k
    memset(group_color, 0, sizeof(pdf14_group_color_t));
1308
1309
495k
    group_color->num_std_colorants = pdev->num_std_colorants;
1310
495k
    group_color->blend_procs = pdev->blend_procs;
1311
495k
    group_color->polarity = pdev->color_info.polarity;
1312
495k
    group_color->num_components = pdev->color_info.num_components - has_tags;
1313
495k
    group_color->isadditive = pdev->ctx->additive;
1314
495k
    group_color->unpack_procs = pdev->pdf14_procs;
1315
495k
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
1316
495k
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
1317
495k
    group_color->depth = pdev->color_info.depth;
1318
495k
    group_color->decode = dev_proc(pdev, decode_color);
1319
495k
    group_color->encode = dev_proc(pdev, encode_color);
1320
495k
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
1321
495k
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
1322
495k
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
1323
495k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1324
495k
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
1325
495k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1326
495k
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
1327
495k
    group_color->icc_profile =
1328
495k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1329
495k
    gsicc_adjust_profile_rc(group_color->icc_profile, 1, "pdf14_make_base_group_color");
1330
1331
495k
    return group_color;
1332
495k
}
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
332M
{
1341
332M
    pdf14_device *pdev = (pdf14_device *)dev;
1342
332M
    bool has_tags = device_encodes_tags(dev);
1343
332M
    int n_chan = pdev->color_info.num_components - has_tags;
1344
332M
    bool additive = pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE;
1345
332M
    int num_spots = pdev->ctx->num_spots;
1346
332M
    pdf14_buf* buf;
1347
332M
    gs_memory_t* memory = dev->memory->stable_memory;
1348
1349
    /* Check for a blank idle group as a base group */
1350
332M
    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
332M
    if (pdev->ctx->stack != NULL)
1357
332M
        return 0;
1358
1359
332M
    if_debug2m('v', dev->memory, "[v]pdf14_initialize_ctx: width = %d, height = %d\n",
1360
440k
        dev->width, dev->height);
1361
1362
440k
    buf = pdf14_buf_new(&(pdev->ctx->rect), has_tags, false, false, false, n_chan + 1,
1363
440k
        num_spots, memory, pdev->ctx->deep);
1364
440k
    if (buf == NULL) {
1365
0
        return gs_error_VMerror;
1366
0
    }
1367
440k
    if_debug5m('v', memory,
1368
440k
        "[v]base buf: %d x %d, %d color channels, %d planes, deep=%d\n",
1369
440k
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes, pdev->ctx->deep);
1370
1371
440k
    memset(buf->data, 0, buf->planestride * (buf->n_planes - !!has_tags));
1372
440k
    buf->saved = NULL;
1373
440k
    pdev->ctx->stack = buf;
1374
440k
    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
440k
    buf->group_color_info = gs_alloc_struct(pdev->memory->stable_memory,
1379
440k
            pdf14_group_color_t, &st_pdf14_clr, "pdf14_initialize_ctx");
1380
440k
    if (buf->group_color_info == NULL)
1381
0
        return gs_error_VMerror;
1382
1383
440k
    if (pgs != NULL)
1384
225k
        buf->group_color_info->get_cmap_procs = pgs->get_cmap_procs;
1385
214k
    else
1386
214k
        buf->group_color_info->get_cmap_procs = pdf14_get_cmap_procs;
1387
1388
440k
    buf->group_color_info->group_color_mapping_procs =
1389
440k
        dev_proc(pdev, get_color_mapping_procs);
1390
440k
    buf->group_color_info->group_color_comp_index =
1391
440k
        dev_proc(pdev, get_color_comp_index);
1392
440k
    buf->group_color_info->blend_procs = pdev->blend_procs;
1393
440k
    buf->group_color_info->polarity = pdev->color_info.polarity;
1394
440k
    buf->group_color_info->num_components = pdev->color_info.num_components - has_tags;
1395
440k
    buf->group_color_info->isadditive = pdev->ctx->additive;
1396
440k
    buf->group_color_info->unpack_procs = pdev->pdf14_procs;
1397
440k
    buf->group_color_info->depth = pdev->color_info.depth;
1398
440k
    buf->group_color_info->max_color = pdev->color_info.max_color;
1399
440k
    buf->group_color_info->max_gray = pdev->color_info.max_gray;
1400
440k
    buf->group_color_info->encode = dev_proc(pdev, encode_color);
1401
440k
    buf->group_color_info->decode = dev_proc(pdev, decode_color);
1402
440k
    memcpy(&(buf->group_color_info->comp_bits), &(pdev->color_info.comp_bits),
1403
440k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1404
440k
    memcpy(&(buf->group_color_info->comp_shift), &(pdev->color_info.comp_shift),
1405
440k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1406
440k
    buf->group_color_info->previous = NULL;  /* used during clist writing */
1407
440k
    buf->group_color_info->icc_profile =
1408
440k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1409
440k
    if (buf->group_color_info->icc_profile != NULL)
1410
440k
        gsicc_adjust_profile_rc(buf->group_color_info->icc_profile, 1, "pdf14_initialize_ctx");
1411
1412
440k
    return 0;
1413
440k
}
1414
1415
static pdf14_group_color_t*
1416
pdf14_clone_group_color_info(gx_device* pdev, pdf14_group_color_t* src)
1417
15.7k
{
1418
15.7k
    pdf14_group_color_t* des = gs_alloc_struct(pdev->memory->stable_memory,
1419
15.7k
        pdf14_group_color_t, &st_pdf14_clr, "pdf14_clone_group_color_info");
1420
15.7k
    if (des == NULL)
1421
0
        return NULL;
1422
1423
15.7k
    memcpy(des, src, sizeof(pdf14_group_color_t));
1424
15.7k
    if (des->icc_profile != NULL)
1425
15.7k
        gsicc_adjust_profile_rc(des->icc_profile, 1, "pdf14_clone_group_color_info");
1426
15.7k
    des->previous = NULL;  /* used during clist writing for state stack */
1427
1428
15.7k
    return des;
1429
15.7k
}
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
1.97M
{
1440
1.97M
    pdf14_buf *tos = ctx->stack;
1441
1.97M
    pdf14_buf *buf, * pdf14_backdrop;
1442
1.97M
    bool has_shape = false;
1443
1.97M
    bool is_backdrop;
1444
1.97M
    int num_spots;
1445
1446
1.97M
    if_debug1m('v', ctx->memory,
1447
1.97M
               "[v]pdf14_push_transparency_group, idle = %d\n", idle);
1448
1449
1.97M
    if (tos != NULL)
1450
1.60M
        has_shape = tos->has_shape || tos->knockout;
1451
1452
1.97M
    if (ctx->smask_depth > 0)
1453
1.16k
        num_spots = 0;
1454
1.97M
    else
1455
1.97M
        num_spots = ctx->num_spots;
1456
1457
1458
1.97M
    buf = pdf14_buf_new(rect, ctx->has_tags, !isolated, has_shape, idle, numcomps + 1,
1459
1.97M
                        num_spots, ctx->memory, ctx->deep);
1460
1.97M
    if (buf == NULL)
1461
0
        return_error(gs_error_VMerror);
1462
1463
1.97M
    if_debug4m('v', ctx->memory,
1464
1.97M
        "[v]base buf: %d x %d, %d color channels, %d planes\n",
1465
1.97M
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes);
1466
1.97M
    buf->isolated = isolated;
1467
1.97M
    buf->knockout = knockout;
1468
1.97M
    buf->alpha = alpha;
1469
1.97M
    buf->shape = shape;
1470
1.97M
    buf->opacity = opacity;
1471
1.97M
    buf->blend_mode = blend_mode;
1472
1.97M
    buf->mask_id = mask_id;
1473
1.97M
    buf->mask_stack = ctx->mask_stack; /* Save because the group rendering may
1474
                                          set up another (nested) mask. */
1475
1.97M
    ctx->mask_stack = NULL; /* Clean the mask field for rendering this group.
1476
                            See pdf14_pop_transparency_group how to handle it. */
1477
1.97M
    buf->saved = tos;
1478
1.97M
    buf->group_color_info = group_color;
1479
1480
1.97M
    if (tos == NULL)
1481
369k
        buf->page_group = true;
1482
1483
1.97M
    ctx->stack = buf;
1484
1.97M
    if (buf->data == NULL)
1485
1.13M
        return 0;
1486
839k
    if (idle)
1487
0
        return 0;
1488
839k
    pdf14_backdrop = pdf14_find_backdrop_buf(ctx, &is_backdrop);
1489
1490
    /* Initializes buf->data with the backdrop or as opaque */
1491
839k
    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
467k
        memset(buf->data, 0, buf->planestride *
1495
467k
                                          (buf->n_chan +
1496
467k
                                           (buf->has_shape ? 1 : 0) +
1497
467k
                                           (buf->has_alpha_g ? 1 : 0)));
1498
467k
    } else {
1499
371k
        if (!cm_back_drop) {
1500
371k
            pdf14_preserve_backdrop(buf, pdf14_backdrop, is_backdrop
1501
#if RAW_DUMP
1502
                                    , ctx->memory
1503
#endif
1504
371k
                                    );
1505
371k
        } 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
371k
    }
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
839k
    if (buf->knockout && pdf14_backdrop != NULL) {
1522
32.3k
        buf->backdrop = gs_alloc_bytes(ctx->memory,
1523
32.3k
                                       buf->planestride * buf->n_planes + CAL_SLOP,
1524
32.3k
                                       "pdf14_push_transparency_group");
1525
32.3k
        if (buf->backdrop == NULL) {
1526
0
            return gs_throw(gs_error_VMerror, "Knockout backdrop allocation failed");
1527
0
        }
1528
1529
32.3k
        memcpy(buf->backdrop, buf->data,
1530
32.3k
               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
32.3k
    }
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
839k
    return 0;
1552
839k
}
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
1.97M
{
1559
1.97M
    pdf14_buf *tos = ctx->stack;
1560
1.97M
    pdf14_buf *nos = tos->saved;
1561
1.97M
    pdf14_mask_t *mask_stack = tos->mask_stack;
1562
1.97M
    pdf14_buf *maskbuf;
1563
1.97M
    int x0, x1, y0, y1;
1564
1.97M
    int nos_num_color_comp;
1565
1.97M
    bool no_icc_match;
1566
1.97M
    pdf14_device *pdev = (pdf14_device *)dev;
1567
1.97M
    bool overprint = pdev->overprint;
1568
1.97M
    gx_color_index drawn_comps = pdev->drawn_comps_stroke | pdev->drawn_comps_fill;
1569
1.97M
    bool has_matte = false;
1570
1.97M
    int code = 0;
1571
1572
#ifdef DEBUG
1573
    pdf14_debug_mask_stack_state(ctx);
1574
#endif
1575
1.97M
    maskbuf = (mask_stack == NULL) ? NULL : mask_stack->mask_buf;
1576
1.97M
    if (maskbuf != NULL && maskbuf->matte != NULL)
1577
2.87k
        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
1.97M
    if (nos == NULL && maskbuf == NULL) {
1589
368k
        tos->group_popped = true;
1590
368k
        return 0;
1591
368k
    }
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.60M
    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.60M
    if (nos->n_chan - 1 != nos->group_color_info->num_components ||
1638
1.60M
        tos->n_chan - 1 != tos_num_color_comp)
1639
0
        return_error(gs_error_Fatal);
1640
1641
1.60M
    nos_num_color_comp = nos->group_color_info->num_components - tos->num_spots;
1642
1.60M
    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.60M
    rect_intersect(tos->dirty, tos->rect);
1647
1.60M
    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.60M
    y0 = max(tos->dirty.p.y, nos->rect.p.y);
1651
1.60M
    y1 = min(tos->dirty.q.y, nos->rect.q.y);
1652
1.60M
    x0 = max(tos->dirty.p.x, nos->rect.p.x);
1653
1.60M
    x1 = min(tos->dirty.q.x, nos->rect.q.x);
1654
1.60M
    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.60M
    ctx->mask_stack = mask_stack;  /* Restore the mask saved by pdf14_push_transparency_group. */
1666
1.60M
    tos->mask_stack = NULL;        /* Clean the pointer sinse the mask ownership is now passed to ctx. */
1667
1.60M
    if (tos->idle)
1668
1.10M
        goto exit;
1669
497k
    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
497k
    if (nos->group_color_info->icc_profile != NULL) {
1689
497k
        no_icc_match = !gsicc_profiles_equal(nos->group_color_info->icc_profile, curr_icc_profile);
1690
497k
    } 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
497k
    if ((nos->group_color_info->group_color_mapping_procs != NULL &&
1697
497k
        nos_num_color_comp != tos_num_color_comp) || no_icc_match) {
1698
3.44k
        if (x0 < x1 && y0 < y1) {
1699
3.22k
            pdf14_buf *result;
1700
3.22k
            bool did_alloc; /* We don't care here */
1701
1702
3.22k
            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.01k
            } else {
1709
2.01k
                result = pdf14_transform_color_buffer_no_matte(pgs, ctx, dev,
1710
2.01k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1711
2.01k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1712
2.01k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false, false);
1713
2.01k
            }
1714
3.22k
            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.22k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1731
3.22k
                 nos->group_color_info->isadditive,
1732
3.22k
                 nos->group_color_info->blend_procs,
1733
3.22k
                 has_matte, false, drawn_comps, ctx->memory, dev);
1734
3.22k
        }
1735
493k
    } else {
1736
        /* Group color spaces are the same.  No color conversions needed */
1737
493k
        if (x0 < x1 && y0 < y1)
1738
285k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1739
285k
                                ctx->additive, pblend_procs, has_matte, overprint,
1740
285k
                                drawn_comps, ctx->memory, dev);
1741
493k
    }
1742
1.60M
exit:
1743
1.60M
    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.60M
    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
493
        ctx->smask_blend = true;
1751
493
    }
1752
1.60M
    if_debug1m('v', ctx->memory, "[v]pop buf, idle=%d\n", tos->idle);
1753
1.60M
    pdf14_buf_free(tos);
1754
1.60M
    if (code < 0)
1755
0
        return_error(code);
1756
1.60M
    return 0;
1757
1.60M
}
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
361k
{
1775
361k
    pdf14_buf *buf;
1776
361k
    int i;
1777
1778
361k
    if_debug2m('v', ctx->memory,
1779
361k
               "[v]pdf14_push_transparency_mask, idle=%d, replacing=%d\n",
1780
361k
               idle, replacing);
1781
361k
    ctx->smask_depth += 1;
1782
1783
361k
    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
361k
    buf = pdf14_buf_new(rect, false, false, false, idle, numcomps + 1, 0,
1795
361k
                        ctx->memory, ctx->deep);
1796
361k
    if (buf == NULL)
1797
0
        return_error(gs_error_VMerror);
1798
361k
    buf->alpha = bg_alpha;
1799
361k
    buf->is_ident = is_ident;
1800
    /* fill in, but these values aren't really used */
1801
361k
    buf->isolated = true;
1802
361k
    buf->knockout = false;
1803
361k
    buf->shape = 0xffff;
1804
361k
    buf->blend_mode = BLEND_MODE_Normal;
1805
361k
    buf->transfer_fn = transfer_fn;
1806
361k
    buf->matte_num_comps = Matte_components;
1807
361k
    buf->group_color_info = group_color;
1808
1809
361k
    if (Matte_components) {
1810
2.87k
        buf->matte = (uint16_t *)gs_alloc_bytes(ctx->memory, Matte_components * sizeof(uint16_t) + CAL_SLOP,
1811
2.87k
                                                "pdf14_push_transparency_mask");
1812
2.87k
        if (buf->matte == NULL)
1813
0
            return_error(gs_error_VMerror);
1814
11.5k
        for (i = 0; i < Matte_components; i++) {
1815
8.62k
            buf->matte[i] = (uint16_t) floor(Matte[i] * 65535.0 + 0.5);
1816
8.62k
        }
1817
2.87k
    }
1818
361k
    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
361k
    buf->mask_stack = ctx->mask_stack;
1824
361k
    if (buf->mask_stack)
1825
361k
        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
361k
    buf->saved = ctx->stack;
1838
361k
    ctx->stack = buf;
1839
    /* Soft Mask related information so we know how to
1840
       compute luminosity when we pop the soft mask */
1841
361k
    buf->SMask_SubType = subtype;
1842
361k
    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
219k
        if ( Background_components && GrayBackground != 0.0 ) {
1850
126
            if (buf->deep) {
1851
0
                uint16_t gray = (uint16_t) (65535.0 * GrayBackground);
1852
0
                gs_memset16(buf->data, gray, buf->planestride);
1853
                /* If we have a background component that was not black, then we
1854
                   need to set the alpha for this mask as if we had drawn in the
1855
                   entire soft mask buffer */
1856
0
                gs_memset16(buf->data + buf->planestride, 65535,
1857
0
                            buf->planestride *(buf->n_chan - 1));
1858
126
            } else {
1859
126
                unsigned char gray = (unsigned char) (255.0 * GrayBackground);
1860
126
                memset(buf->data, gray, buf->planestride);
1861
                /* If we have a background component that was not black, then we
1862
                   need to set the alpha for this mask as if we had drawn in the
1863
                   entire soft mask buffer */
1864
126
                memset(buf->data + buf->planestride, 255,
1865
126
                       buf->planestride * (buf->n_chan - 1));
1866
126
            }
1867
219k
        } else {
1868
            /* Compose mask with opaque background */
1869
219k
            memset(buf->data, 0, buf->planestride * buf->n_chan);
1870
219k
        }
1871
219k
    }
1872
361k
    return 0;
1873
361k
}
1874
1875
static  int
1876
pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev)
1877
361k
{
1878
361k
    pdf14_buf* tos = ctx->stack;
1879
361k
    pdf14_buf* nos = tos->saved;
1880
361k
    byte *new_data_buf;
1881
361k
    int icc_match;
1882
361k
    cmm_profile_t *des_profile = nos->group_color_info->icc_profile; /* If set, this should be a gray profile */
1883
361k
    cmm_profile_t *src_profile;
1884
361k
    gsicc_rendering_param_t rendering_params;
1885
361k
    gsicc_link_t *icc_link;
1886
361k
    gsicc_rendering_param_t render_cond;
1887
361k
    cmm_dev_profile_t *dev_profile;
1888
361k
    int code = 0;
1889
1890
361k
    dev_proc(dev, get_profile)(dev,  &dev_profile);
1891
361k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &src_profile,
1892
361k
                          &render_cond);
1893
361k
    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
361k
    if (des_profile != NULL && src_profile != NULL ) {
1898
361k
        icc_match = gsicc_profiles_equal(des_profile, src_profile);
1899
361k
    } else {
1900
0
        icc_match = -1;
1901
0
    }
1902
361k
    if_debug1m('v', ctx->memory, "[v]pdf14_pop_transparency_mask, idle=%d\n",
1903
361k
               tos->idle);
1904
361k
    ctx->stack = tos->saved;
1905
361k
    tos->saved = NULL;  /* To avoid issues with GC */
1906
361k
    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
93.7k
        rc_decrement(tos->mask_stack, "pdf14_pop_transparency_mask");
1914
93.7k
        tos->mask_stack = NULL;
1915
93.7k
    }
1916
1917
361k
    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
141k
        if (ctx->mask_stack != NULL) {
1924
37.7k
            rc_decrement(ctx->mask_stack, "pdf14_free_mask_stack");
1925
37.7k
            ctx->mask_stack = NULL;
1926
37.7k
        }
1927
141k
        if ((tos->alpha == 65535 && tos->is_ident) ||
1928
141k
            (!tos->is_ident && (tos->transfer_fn[tos->alpha>>8] == 255))) {
1929
4.68k
            pdf14_buf_free(tos);
1930
137k
        } else {
1931
            /* Assign as mask buffer */
1932
137k
            ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
1933
137k
            if (ctx->mask_stack == NULL)
1934
0
                return gs_note_error(gs_error_VMerror);
1935
137k
            ctx->mask_stack->mask_buf = tos;
1936
137k
        }
1937
141k
        ctx->smask_blend = false;  /* just in case */
1938
219k
    } else {
1939
        /* If we are already in the source space then there is no reason
1940
           to do the transformation */
1941
        /* Lets get this to a monochrome buffer and map it to a luminance only value */
1942
        /* This will reduce our memory.  We won't reuse the existing one, due */
1943
        /* Due to the fact that on certain systems we may have issues recovering */
1944
        /* the data after a resize */
1945
219k
        new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride + CAL_SLOP,
1946
219k
                                        "pdf14_pop_transparency_mask");
1947
219k
        if (new_data_buf == NULL)
1948
0
            return_error(gs_error_VMerror);
1949
        /* Initialize with 0.  Need to do this since in Smask_Luminosity_Mapping
1950
           we won't be filling everything during the remap if it had not been
1951
           written into by the PDF14 fill rect */
1952
219k
        memset(new_data_buf, 0, tos->planestride);
1953
        /* If the subtype was alpha, then just grab the alpha channel now
1954
           and we are all done */
1955
219k
        if (tos->SMask_SubType == TRANSPARENCY_MASK_Alpha) {
1956
36.5k
            ctx->smask_blend = false;  /* not used in this case */
1957
36.5k
            smask_copy(tos->rect.q.y - tos->rect.p.y,
1958
36.5k
                       (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
1959
36.5k
                       tos->rowstride,
1960
36.5k
                       (tos->data)+tos->planestride, new_data_buf);
1961
#if RAW_DUMP
1962
            /* Dump the current buffer to see what we have. */
1963
            dump_raw_buffer(ctx->memory,
1964
                            tos->rect.q.y-tos->rect.p.y,
1965
                            tos->rowstride>>tos->deep, 1,
1966
                            tos->planestride, tos->rowstride,
1967
                            "SMask_Pop_Alpha(Mask_Plane1)",tos->data,
1968
                            tos->deep);
1969
            global_index++;
1970
#endif
1971
183k
        } else {
1972
183k
            if (icc_match == 1 || tos->n_chan == 2) {
1973
#if RAW_DUMP
1974
                /* Dump the current buffer to see what we have. */
1975
                dump_raw_buffer(ctx->memory,
1976
                                tos->rect.q.y-tos->rect.p.y,
1977
                                tos->rowstride>>tos->deep, tos->n_planes,
1978
                                tos->planestride, tos->rowstride,
1979
                                "SMask_Pop_Lum(Mask_Plane0)",tos->data,
1980
                                tos->deep);
1981
                global_index++;
1982
#endif
1983
                /* There is no need to color convert.  Data is already gray scale.
1984
                   We just need to copy the gray plane.  However it is
1985
                   possible that the soft mask could have a soft mask which
1986
                   would end us up with some alpha blending information
1987
                   (Bug691803). In fact, according to the spec, the alpha
1988
                   blending has to occur.  See FTS test fts_26_2601.pdf
1989
                   for an example of this.  Softmask buffer is intialized
1990
                   with BG values.  It would be nice to keep track if buffer
1991
                   ever has a alpha value not 1 so that we could detect and
1992
                   avoid this blend if not needed. */
1993
183k
                smask_blend(tos->data, tos->rect.q.x - tos->rect.p.x,
1994
183k
                            tos->rect.q.y - tos->rect.p.y, tos->rowstride,
1995
183k
                            tos->planestride, tos->deep);
1996
#if RAW_DUMP
1997
                /* Dump the current buffer to see what we have. */
1998
                dump_raw_buffer(ctx->memory,
1999
                                tos->rect.q.y-tos->rect.p.y,
2000
                                tos->rowstride>>tos->deep, 1,
2001
                                tos->planestride, tos->rowstride,
2002
                                "SMask_Pop_Lum_Post_Blend",tos->data,
2003
                                tos->deep);
2004
                global_index++;
2005
#endif
2006
183k
                smask_copy(tos->rect.q.y - tos->rect.p.y,
2007
183k
                           (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2008
183k
                           tos->rowstride, tos->data, new_data_buf);
2009
183k
            } else {
2010
0
                if ( icc_match == -1 ) {
2011
                    /* The slow old fashioned way */
2012
0
                    smask_luminosity_mapping(tos->rect.q.y - tos->rect.p.y ,
2013
0
                        tos->rect.q.x - tos->rect.p.x,tos->n_chan,
2014
0
                        tos->rowstride, tos->planestride,
2015
0
                        tos->data,  new_data_buf, ctx->additive, tos->SMask_SubType,
2016
0
                        tos->deep
2017
#if RAW_DUMP
2018
                        , ctx->memory
2019
#endif
2020
0
                        );
2021
0
                } else {
2022
                    /* ICC case where we use the CMM */
2023
                    /* Request the ICC link for the transform that we will need to use */
2024
0
                    rendering_params.black_point_comp = gsBLACKPTCOMP_OFF;
2025
0
                    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
2026
0
                    rendering_params.override_icc = false;
2027
0
                    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
2028
0
                    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;
2029
0
                    rendering_params.cmm = gsCMM_DEFAULT;
2030
0
                    icc_link = gsicc_get_link_profile(pgs, dev, des_profile,
2031
0
                        src_profile, &rendering_params, pgs->memory, false);
2032
0
                    code = smask_icc(dev, tos->rect.q.y - tos->rect.p.y,
2033
0
                              tos->rect.q.x - tos->rect.p.x, tos->n_chan,
2034
0
                              tos->rowstride, tos->planestride,
2035
0
                              tos->data, new_data_buf, icc_link, tos->deep);
2036
                    /* Release the link */
2037
0
                    gsicc_release_link(icc_link);
2038
0
                }
2039
0
            }
2040
183k
        }
2041
        /* Free the old object, NULL test was above */
2042
219k
        gs_free_object(ctx->memory, tos->data, "pdf14_pop_transparency_mask");
2043
219k
        tos->data = new_data_buf;
2044
        /* Data is single channel now */
2045
219k
        tos->n_chan = 1;
2046
219k
        tos->n_planes = 1;
2047
        /* Assign as reference counted mask buffer */
2048
219k
        if (ctx->mask_stack != NULL) {
2049
            /* In this case, the source file is wacky as it already had a
2050
               softmask and now is getting a replacement. We need to clean
2051
               up the softmask stack before doing this free and creating
2052
               a new stack. Bug 693312 */
2053
56.1k
            rc_decrement(ctx->mask_stack, "pdf14_pop_transparency_mask(ctx->mask_stack)");
2054
56.1k
        }
2055
219k
        ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2056
219k
        if (ctx->mask_stack == NULL)
2057
0
            return gs_note_error(gs_error_VMerror);
2058
219k
        ctx->mask_stack->mask_buf = tos;
2059
219k
    }
2060
361k
    return code;
2061
361k
}
2062
2063
static void
2064
rc_pdf14_mask_element_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
2065
1.31M
{
2066
    /* Ending the mask buffer. */
2067
1.31M
    pdf14_mask_t *mask = (pdf14_mask_t *)ptr_in;
2068
    /* free the pdf14 buffer. */
2069
1.31M
    if (mask->mask_buf != NULL) {
2070
88.7k
        pdf14_buf_free(mask->mask_buf);
2071
88.7k
    }
2072
1.31M
    gs_free_object(mem, mask, "rc_pdf14_mask_element_free");
2073
1.31M
}
2074
2075
static pdf14_mask_t *
2076
pdf14_mask_element_new(gs_memory_t *memory)
2077
1.31M
{
2078
1.31M
    pdf14_mask_t *result;
2079
2080
1.31M
    result = gs_alloc_struct(memory, pdf14_mask_t, &st_pdf14_mask,
2081
1.31M
                             "pdf14_mask_element_new");
2082
1.31M
    if (result == NULL)
2083
0
        return NULL;
2084
2085
1.31M
    rc_init_free(result, memory, 1, rc_pdf14_mask_element_free);
2086
2087
1.31M
    result->mask_buf = NULL;
2088
1.31M
    result->memory = memory;
2089
1.31M
    result->previous = NULL;
2090
2091
1.31M
    return result;
2092
1.31M
}
2093
2094
static int
2095
pdf14_push_transparency_state(gx_device *dev, gs_gstate *pgs)
2096
0
{
2097
    /* We need to push the current soft mask.  We need to
2098
       be able to recover it if we draw a new one and
2099
       then obtain a Q operation ( a pop ) */
2100
2101
0
    pdf14_device *pdev = (pdf14_device *)dev;
2102
0
    pdf14_ctx *ctx = pdev->ctx;
2103
0
    pdf14_mask_t *new_mask;
2104
2105
0
    if_debug0m('v', ctx->memory, "pdf14_push_transparency_state\n");
2106
    /* We need to push the current mask buffer   */
2107
    /* Allocate a new element for the stack.
2108
       Don't do anything if there is no mask present.*/
2109
0
    if (ctx->mask_stack != NULL) {
2110
0
        new_mask = pdf14_mask_element_new(ctx->memory);
2111
0
        if (new_mask == NULL)
2112
0
            return gs_note_error(gs_error_VMerror);
2113
0
        new_mask->previous = ctx->mask_stack;
2114
0
        ctx->mask_stack = new_mask;
2115
0
    }
2116
#ifdef DEBUG
2117
    pdf14_debug_mask_stack_state(pdev->ctx);
2118
#endif
2119
0
    return 0;
2120
0
}
2121
2122
static int
2123
pdf14_pop_transparency_state(gx_device *dev, gs_gstate *pgs)
2124
2.42M
{
2125
    /* Pop the soft mask.  It is no longer needed. Likely due to
2126
       a Q that has occurred. */
2127
2.42M
    pdf14_device *pdev = (pdf14_device *)dev;
2128
2.42M
    pdf14_ctx *ctx = pdev->ctx;
2129
2.42M
    pdf14_mask_t *old_mask;
2130
2131
2.42M
    if_debug0m('v', ctx->memory, "pdf14_pop_transparency_state\n");
2132
    /* rc decrement the current link after we break it from
2133
       the list, then free the stack element.  Don't do
2134
       anything if there is no mask present. */
2135
2.42M
    if (ctx->mask_stack != NULL) {
2136
382k
        old_mask = ctx->mask_stack;
2137
382k
        ctx->mask_stack = ctx->mask_stack->previous;
2138
382k
        rc_decrement(old_mask, "pdf14_pop_transparency_state");
2139
        /* We need to have some special handling here for when we have nested
2140
           soft masks.  There may be a copy in the stack that we may need to
2141
           adjust. */
2142
382k
        if (ctx->smask_depth > 0) {
2143
233
            if (ctx->stack != NULL && ctx->stack->mask_stack != NULL) {
2144
222
                ctx->stack->mask_stack = ctx->mask_stack;
2145
222
            }
2146
233
        }
2147
382k
    }
2148
#ifdef DEBUG
2149
    pdf14_debug_mask_stack_state(pdev->ctx);
2150
#endif
2151
2.42M
    return 0;
2152
2.42M
}
2153
2154
static  int
2155
pdf14_open(gx_device *dev)
2156
958k
{
2157
958k
    pdf14_device *pdev = (pdf14_device *)dev;
2158
2159
    /* If we are reenabling the device dont create a new ctx. Bug 697456 */
2160
958k
    if (pdev->ctx == NULL) {
2161
958k
        bool has_tags = device_encodes_tags(dev);
2162
958k
        int bits_per_comp = (dev->color_info.depth / dev->color_info.num_components);
2163
958k
        pdev->ctx = pdf14_ctx_new(dev, bits_per_comp > 8);
2164
958k
        if (pdev->ctx == NULL)
2165
0
            return_error(gs_error_VMerror);
2166
2167
958k
        pdev->ctx->rect.p.x = 0;
2168
958k
        pdev->ctx->rect.p.y = 0;
2169
958k
        pdev->ctx->rect.q.x = dev->width;
2170
958k
        pdev->ctx->rect.q.y = dev->height;
2171
958k
        pdev->ctx->has_tags = has_tags;
2172
958k
        pdev->ctx->num_spots = pdev->color_info.num_components - has_tags - pdev->num_std_colorants;
2173
        /* This can happen because pdev->num_std_colorants is not updated when pdev->color_info.num_components
2174
         * is. I am not sure how to fix that. */
2175
958k
        if (pdev->ctx->num_spots < 0)
2176
0
            pdev->ctx->num_spots = 0;
2177
958k
        pdev->ctx->additive = (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE);
2178
958k
    }
2179
958k
    pdev->free_devicen = true;
2180
958k
    pdev->text_group = PDF14_TEXTGROUP_NO_BT;
2181
958k
    return 0;
2182
958k
}
2183
2184
static const gx_cm_color_map_procs pdf14_DeviceCMYKspot_procs = {
2185
    pdf14_gray_cs_to_cmyk_cm, pdf14_rgb_cs_to_cmyk_cm, pdf14_cmyk_cs_to_cmyk_cm
2186
};
2187
2188
static const gx_cm_color_map_procs pdf14_DeviceRGBspot_procs = {
2189
    pdf14_gray_cs_to_rgbspot_cm, pdf14_rgb_cs_to_rgbspot_cm, pdf14_cmyk_cs_to_rgbspot_cm
2190
};
2191
2192
static const gx_cm_color_map_procs pdf14_DeviceGrayspot_procs = {
2193
    pdf14_gray_cs_to_grayspot_cm, pdf14_rgb_cs_to_grayspot_cm, pdf14_cmyk_cs_to_grayspot_cm
2194
};
2195
2196
static const gx_cm_color_map_procs *
2197
pdf14_cmykspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2198
8.34M
{
2199
8.34M
    *tdev = dev;
2200
8.34M
    return &pdf14_DeviceCMYKspot_procs;
2201
8.34M
}
2202
2203
static const gx_cm_color_map_procs *
2204
pdf14_rgbspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2205
2.94M
{
2206
2.94M
    *tdev = dev;
2207
2.94M
    return &pdf14_DeviceRGBspot_procs;
2208
2.94M
}
2209
2210
static const gx_cm_color_map_procs *
2211
pdf14_grayspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2212
0
{
2213
0
    *tdev = dev;
2214
0
    return &pdf14_DeviceGrayspot_procs;
2215
0
}
2216
2217
static void
2218
be_rev_cpy(uint16_t *dst,const uint16_t *src,int n)
2219
0
{
2220
0
    for (; n != 0; n--) {
2221
0
        uint16_t in = *src++;
2222
0
        ((byte *)dst)[0] = in>>8;
2223
0
        ((byte *)dst)[1] = in;
2224
0
        dst++;
2225
0
    }
2226
0
}
2227
2228
/* Used to pass along information about the buffer created by the
2229
   pdf14 device.  This is used by the pattern accumulator when the
2230
   pattern contains transparency.  Note that if free_device is true then
2231
   we need to go ahead and get the buffer data copied and free up the
2232
   device.  This only occurs at the end of a pattern accumulation operation */
2233
int
2234
pdf14_get_buffer_information(const gx_device * dev,
2235
                             gx_pattern_trans_t *transbuff, gs_memory_t *mem,
2236
                             bool free_device)
2237
20.0k
{
2238
20.0k
    const pdf14_device * pdev = (pdf14_device *)dev;
2239
20.0k
    pdf14_buf *buf;
2240
20.0k
    gs_int_rect rect;
2241
20.0k
    int x1,y1,width,height;
2242
2243
20.0k
    if ( pdev->ctx == NULL){
2244
0
        return 0;  /* this can occur if the pattern is a clist */
2245
0
    }
2246
#ifdef DEBUG
2247
    pdf14_debug_mask_stack_state(pdev->ctx);
2248
#endif
2249
20.0k
    buf = pdev->ctx->stack;
2250
20.0k
    rect = buf->rect;
2251
20.0k
    transbuff->buf = (free_device ? NULL : buf);
2252
20.0k
    x1 = min(pdev->width, rect.q.x);
2253
20.0k
    y1 = min(pdev->height, rect.q.y);
2254
20.0k
    width = x1 - rect.p.x;
2255
20.0k
    height = y1 - rect.p.y;
2256
2257
20.0k
    transbuff->n_chan    = buf->n_chan;
2258
20.0k
    transbuff->has_tags  = buf->has_tags;
2259
20.0k
    transbuff->has_shape = buf->has_shape;
2260
20.0k
    transbuff->width     = buf->rect.q.x - buf->rect.p.x;
2261
20.0k
    transbuff->height    = buf->rect.q.y - buf->rect.p.y;
2262
20.0k
    transbuff->deep      = buf->deep;
2263
2264
20.0k
    if (width <= 0 || height <= 0 || buf->data == NULL) {
2265
6.89k
        transbuff->planestride = 0;
2266
6.89k
        transbuff->rowstride = 0;
2267
6.89k
        return 0;
2268
6.89k
    }
2269
2270
13.1k
    if (free_device) {
2271
4.34k
        transbuff->pdev14 = NULL;
2272
4.34k
        transbuff->rect = rect;
2273
4.34k
        if ((width < transbuff->width) || (height < transbuff->height)) {
2274
            /* If the bbox is smaller than the whole buffer than go ahead and
2275
               create a new one to use.  This can occur if we drew in a smaller
2276
               area than was specified by the transparency group rect. */
2277
0
            intptr_t rowstride = ((width + 3) & -4)<<buf->deep;
2278
0
            intptr_t planestride = rowstride * height;
2279
0
            int k, j;
2280
0
            byte *buff_ptr_src, *buff_ptr_des;
2281
2282
0
            transbuff->planestride = planestride;
2283
0
            transbuff->rowstride = rowstride;
2284
0
            transbuff->transbytes =
2285
0
                         gs_alloc_bytes(mem,
2286
0
                                        planestride *
2287
0
                                                (buf->n_chan +
2288
0
                                                 buf->has_tags ? 1 : 0) + CAL_SLOP,
2289
0
                                        "pdf14_get_buffer_information");
2290
0
            if (transbuff->transbytes == NULL)
2291
0
                return gs_error_VMerror;
2292
2293
0
            transbuff->mem = mem;
2294
0
            if (transbuff->deep) {
2295
0
                for (j = 0; j < transbuff->n_chan; j++) {
2296
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2297
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2298
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2299
0
                    for (k = 0; k < height; k++) {
2300
0
                        be_rev_cpy((uint16_t *)buff_ptr_des, (const uint16_t *)buff_ptr_src, rowstride>>1);
2301
0
                        buff_ptr_des += rowstride;
2302
0
                        buff_ptr_src += buf->rowstride;
2303
0
                    }
2304
0
                }
2305
0
            } else {
2306
0
                for (j = 0; j < transbuff->n_chan; j++) {
2307
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2308
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2309
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2310
0
                    for (k = 0; k < height; k++) {
2311
0
                        memcpy(buff_ptr_des, buff_ptr_src, rowstride);
2312
0
                        buff_ptr_des += rowstride;
2313
0
                        buff_ptr_src += buf->rowstride;
2314
0
                    }
2315
0
                }
2316
0
            }
2317
2318
4.34k
        } else {
2319
            /* The entire buffer is used.  Go ahead and grab the pointer and
2320
               clear the pointer in the pdf14 device data buffer so it is not
2321
               freed when we close the device */
2322
4.34k
            transbuff->planestride = buf->planestride;
2323
4.34k
            transbuff->rowstride = buf->rowstride;
2324
4.34k
            transbuff->transbytes = buf->data;
2325
4.34k
            transbuff->mem = buf->memory;
2326
4.34k
            buf->data = NULL;  /* So that the buffer is not freed */
2327
4.34k
            if (transbuff->deep) {
2328
                /* We have the data in native endian. We need it in big endian. Do an in-place conversion. */
2329
                /* FIXME: This is a nop on big endian machines. Is the compiler smart enough to spot that? */
2330
0
                uint16_t *buff_ptr;
2331
0
                int j, k, z;
2332
0
                intptr_t rowstride = transbuff->rowstride>>1;
2333
0
                intptr_t planestride = transbuff->planestride;
2334
0
                for (j = 0; j < transbuff->n_chan; j++) {
2335
0
                    buff_ptr = (uint16_t *)(transbuff->transbytes + j * planestride);
2336
0
                    for (k = 0; k < height; k++) {
2337
0
                        for (z = 0; z < width; z++) {
2338
0
                            uint16_t in = buff_ptr[z];
2339
0
                            ((byte *)(&buff_ptr[z]))[0] = in>>8;
2340
0
                            ((byte *)(&buff_ptr[z]))[1] = in;
2341
0
                        }
2342
0
                        buff_ptr += rowstride;
2343
0
                    }
2344
0
                }
2345
0
            }
2346
4.34k
        }
2347
#if RAW_DUMP
2348
        /* Dump the buffer that should be going into the pattern */;
2349
        dump_raw_buffer_be(buf->memory,
2350
                           height, width, transbuff->n_chan,
2351
                           transbuff->planestride, transbuff->rowstride,
2352
                           "pdf14_pattern_buff", transbuff->transbytes,
2353
                           transbuff->deep);
2354
        global_index++;
2355
#endif
2356
        /* Go ahead and free up the pdf14 device */
2357
4.34k
        dev_proc(dev, close_device)((gx_device *)dev);
2358
8.84k
    } else {
2359
        /* Here we are coming from one of the fill image / pattern / mask
2360
           operations */
2361
8.84k
        transbuff->pdev14 = dev;
2362
8.84k
        transbuff->planestride = buf->planestride;
2363
8.84k
        transbuff->rowstride = buf->rowstride;
2364
8.84k
        transbuff->transbytes = buf->data;
2365
8.84k
        transbuff->mem = buf->memory;
2366
8.84k
        transbuff->rect = rect;
2367
#if RAW_DUMP
2368
    /* Dump the buffer that should be going into the pattern */;
2369
        dump_raw_buffer(buf->memory,
2370
                        height, width, buf->n_chan,
2371
                        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2372
                        "pdf14_pattern_buff",
2373
                        buf->data,
2374
                        transbuff->deep);
2375
        global_index++;
2376
#endif
2377
8.84k
    }
2378
13.1k
    return 0;
2379
13.1k
}
2380
2381
typedef void (blend_image_row_proc_t) (const byte *gs_restrict buf_ptr,
2382
    intptr_t planestride, int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf);
2383
2384
2385
static int
2386
pdf14_put_image_color_convert(const pdf14_device* dev, gs_gstate* pgs, cmm_profile_t* src_profile,
2387
                        cmm_dev_profile_t* dev_target_profile, pdf14_buf** buf,
2388
                        byte** buf_ptr, bool was_blended, int x, int y, int width, int height, int num_channels_to_lose)
2389
7.70k
{
2390
7.70k
    pdf14_buf* cm_result = NULL;
2391
7.70k
    cmm_profile_t* des_profile;
2392
7.70k
    gsicc_rendering_param_t render_cond;
2393
7.70k
    bool did_alloc;
2394
7.70k
    bool endian_swap;
2395
2396
7.70k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_target_profile, &des_profile,
2397
7.70k
        &render_cond);
2398
2399
#if RAW_DUMP
2400
#if !ARCH_IS_BIG_ENDIAN
2401
    if (was_blended && (*buf)->deep)
2402
      dump_raw_buffer_be(dev->ctx->memory,
2403
          height, width, (*buf)->n_planes, (*buf)->planestride,
2404
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2405
    else
2406
#endif
2407
      dump_raw_buffer(dev->ctx->memory,
2408
          height, width, (*buf)->n_planes, (*buf)->planestride,
2409
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2410
    global_index++;
2411
#endif
2412
2413
    /* If we are doing a 16 bit buffer it will be big endian if we have already done the
2414
       blend, otherwise it will be native endian. GS expects its 16bit buffers to be BE
2415
       but for sanity pdf14 device maintains 16bit buffers in native format.  The CMM
2416
       will need to know if it is dealing with native or BE data. */
2417
7.70k
    if (was_blended && (*buf)->deep) {
2418
        /* Data is in BE.  If we are in a LE machine, CMM will need to swap for
2419
           color conversion */
2420
#if ARCH_IS_BIG_ENDIAN
2421
        endian_swap = false;
2422
#else
2423
0
        endian_swap = true;
2424
0
#endif
2425
7.70k
    } else {
2426
        /* Data is in native format. No swap needed for CMM */
2427
7.70k
        endian_swap = false;
2428
7.70k
    }
2429
2430
7.70k
    cm_result = pdf14_transform_color_buffer_no_matte(pgs, dev->ctx, (gx_device*) dev, *buf,
2431
7.70k
        *buf_ptr, src_profile, des_profile, x, y, width,
2432
7.70k
        height, &did_alloc, (*buf)->deep, endian_swap, num_channels_to_lose);
2433
2434
7.70k
    if (cm_result == NULL)
2435
0
        return_error(gs_error_VMerror);
2436
2437
    /* Update */
2438
7.70k
    *buf = cm_result;
2439
2440
    /* Make sure our buf_ptr is pointing to the proper location */
2441
7.70k
    if (did_alloc)
2442
7.70k
        *buf_ptr = cm_result->data;  /* Note the lack of offset */
2443
2444
#if RAW_DUMP
2445
    dump_raw_buffer(dev->ctx->memory,
2446
        height, width, (*buf)->n_planes, (*buf)->planestride,
2447
        (*buf)->rowstride, "pdf14_put_image_color_convert_post", *buf_ptr, (*buf)->deep);
2448
    global_index++;
2449
#endif
2450
7.70k
    return 0;
2451
7.70k
}
2452
2453
/**
2454
 * pdf14_put_image: Put rendered image to target device.
2455
 * @pdev: The PDF 1.4 rendering device.
2456
 * @pgs: State for image draw operation.
2457
 * @target: The target device.
2458
 *
2459
 * Puts the rendered image in @pdev's buffer to @target. This is called
2460
 * as part of the sequence of popping the PDF 1.4 device filter.
2461
 *
2462
 * Return code: negative on error.
2463
 **/
2464
static  int
2465
pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
2466
881k
{
2467
881k
    const pdf14_device * pdev = (pdf14_device *)dev;
2468
881k
    int code;
2469
881k
    gs_image1_t image;
2470
881k
    gx_image_enum_common_t *info;
2471
881k
    pdf14_buf *buf = pdev->ctx->stack;
2472
881k
    gs_int_rect rect;
2473
881k
    int y;
2474
881k
    int num_comp;
2475
881k
    byte *linebuf, *linebuf_unaligned;
2476
881k
    gs_color_space *pcs;
2477
881k
    int x1, y1, width, height;
2478
881k
    byte *buf_ptr;
2479
881k
    int num_rows_left;
2480
881k
    cmm_profile_t* src_profile = NULL;
2481
881k
    cmm_profile_t* des_profile = NULL;
2482
881k
    cmm_dev_profile_t *pdf14dev_profile;
2483
881k
    cmm_dev_profile_t *dev_target_profile;
2484
881k
    uint16_t bg;
2485
881k
    bool has_tags = device_encodes_tags(dev);
2486
881k
    bool deep = pdev->ctx->deep;
2487
881k
    intptr_t planestride;
2488
881k
    intptr_t rowstride;
2489
881k
    blend_image_row_proc_t *blend_row;
2490
881k
    bool color_mismatch = false;
2491
881k
    bool supports_alpha = false;
2492
881k
    int i;
2493
881k
    int alpha_offset, tag_offset;
2494
881k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
2495
881k
    int rendering_intent_saved;
2496
881k
    int additive;
2497
2498
    /* Nothing was ever drawn. */
2499
881k
    if (buf == NULL)
2500
119k
        return 0;
2501
2502
761k
    additive = buf->group_color_info->isadditive;
2503
2504
761k
    src_profile = buf->group_color_info->icc_profile;
2505
2506
761k
    num_comp = buf->n_chan - 1;
2507
761k
    rect = buf->rect;
2508
761k
    planestride = buf->planestride;
2509
761k
    rowstride = buf->rowstride;
2510
2511
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
2512
       potential problem. Bug 694190 */
2513
761k
    if (buf->saved != NULL) {
2514
14
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
2515
14
    }
2516
761k
    if_debug0m('v', dev->memory, "[v]pdf14_put_image\n");
2517
761k
    rect_intersect(rect, buf->dirty);
2518
761k
    x1 = min(pdev->width, rect.q.x);
2519
761k
    y1 = min(pdev->height, rect.q.y);
2520
761k
    width = x1 - rect.p.x;
2521
761k
    height = y1 - rect.p.y;
2522
#ifdef DUMP_TO_PNG
2523
    dump_planar_rgba(pdev->memory, buf);
2524
#endif
2525
761k
    if (width <= 0 || height <= 0 || buf->data == NULL)
2526
200k
        return 0;
2527
561k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
2528
2529
    /* Check that target is OK.  From fuzzing results the target could have been
2530
       destroyed, for e.g if it were a pattern accumulator that was closed
2531
       prematurely (Bug 694154).  We should always be able to to get an ICC
2532
       profile from the target. */
2533
561k
    code = dev_proc(target, get_profile)(target,  &dev_target_profile);
2534
561k
    if (code < 0)
2535
0
        return code;
2536
561k
    if (dev_target_profile == NULL)
2537
0
        return gs_throw_code(gs_error_Fatal);
2538
2539
561k
    if (src_profile == NULL) {
2540
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
2541
0
        if (code < 0) {
2542
0
            return code;
2543
0
        }
2544
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2545
0
    }
2546
2547
    /* Check if we have a color conversion issue */
2548
561k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2549
561k
    if (!gsicc_profiles_equal(des_profile, src_profile))
2550
103k
        color_mismatch = true;
2551
2552
    /* Check if target supports alpha */
2553
561k
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
2554
561k
    code = 0;
2555
2556
#if RAW_DUMP
2557
    dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2558
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2559
        "pre_final_blend", buf_ptr, deep);
2560
#endif
2561
2562
    /* Note. The logic below will need a little rework if we ever
2563
       have a device that has tags and alpha support */
2564
561k
    if (supports_alpha) {
2565
0
        if (!color_mismatch) {
2566
0
            alpha_offset = num_comp;
2567
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2568
2569
0
            for (i = 0; i < buf->n_planes; i++)
2570
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2571
0
            for (; i < target->color_info.num_components; i++)
2572
0
                buf_ptrs[i] = 0;
2573
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2574
0
                rect.p.x, rect.p.y, width, height,
2575
0
                rowstride, alpha_offset,
2576
0
                tag_offset);
2577
            /* Right now code has number of rows written */
2578
0
        } else {
2579
            /* In this case, just color convert and maintain alpha.  This is a case
2580
               where we either either blend in the right color space and have no
2581
               alpha for the output device or hand back the wrong color space with
2582
               alpha data.  We choose the later. */
2583
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
2584
0
                dev_target_profile, &buf, &buf_ptr, false, rect.p.x, rect.p.y,
2585
0
                width, height, false);
2586
0
            if (code < 0)
2587
0
                return code;
2588
2589
            /* reset */
2590
0
            rowstride = buf->rowstride;
2591
0
            planestride = buf->planestride;
2592
0
            num_comp = buf->n_chan - 1;
2593
0
            alpha_offset = num_comp;
2594
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2595
2596
            /* And then out */
2597
0
            for (i = 0; i < buf->n_planes; i++)
2598
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2599
0
            for (; i < target->color_info.num_components; i++)
2600
0
                buf_ptrs[i] = 0;
2601
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2602
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2603
0
                tag_offset);
2604
            /* Right now code has number of rows written */
2605
0
        }
2606
561k
    } else if (has_tags) {
2607
        /* We are going out to a device that supports tags */
2608
0
        if (deep) {
2609
0
            gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
2610
0
                buf->planestride, num_comp, additive, false);
2611
0
        } else {
2612
0
            gx_blend_image_buffer(buf_ptr, width, height, rowstride,
2613
0
                buf->planestride, num_comp, additive);
2614
0
        }
2615
2616
#if RAW_DUMP
2617
        dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2618
            pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2619
            "post_final_blend", buf_ptr, deep);
2620
#endif
2621
2622
        /* Take care of color issues */
2623
0
        if (color_mismatch) {
2624
            /* In this case, just color convert and maintain alpha.  This is a case
2625
               where we either either blend in the right color space and have no
2626
               alpha for the output device or hand back the wrong color space with
2627
               alpha data.  We choose the later. */
2628
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
2629
0
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, false);
2630
0
            if (code < 0)
2631
0
                return code;
2632
2633
#if RAW_DUMP
2634
            dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2635
                pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2636
                "final_color_manage", buf_ptr, deep);
2637
            global_index++;
2638
#endif
2639
0
        }
2640
2641
        /* reset */
2642
0
        rowstride = buf->rowstride;
2643
0
        planestride = buf->planestride;
2644
0
        num_comp = buf->n_chan - 1;
2645
0
        alpha_offset = 0;  /* It is there but this indicates we have done the blend */
2646
0
        tag_offset = buf->has_tags ? buf->n_chan : 0;
2647
2648
        /* And then out */
2649
0
        for (i = 0; i < buf->n_planes; i++)
2650
0
            buf_ptrs[i] = buf_ptr + i * planestride;
2651
0
        for (; i < target->color_info.num_components; i++)
2652
0
            buf_ptrs[i] = 0;
2653
0
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2654
0
            rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2655
0
            tag_offset);
2656
        /* Right now code has number of rows written */
2657
2658
0
    }
2659
2660
    /* If code > 0 then put image worked.  Let it finish and then exit */
2661
561k
    if (code > 0) {
2662
        /* We processed some or all of the rows.  Continue until we are done */
2663
0
        num_rows_left = height - code;
2664
0
        while (num_rows_left > 0) {
2665
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2666
0
                                                rect.p.x, rect.p.y + code, width,
2667
0
                                                num_rows_left, rowstride,
2668
0
                                                alpha_offset, tag_offset);
2669
0
            num_rows_left = num_rows_left - code;
2670
0
        }
2671
0
        return 0;
2672
0
    }
2673
2674
    /* Target device did not support alpha or tags.
2675
     * Set color space in preparation for sending an image.
2676
     * color conversion will occur after blending with through
2677
     * the begin typed image work flow.
2678
     */
2679
2680
561k
    planestride = buf->planestride;
2681
561k
    rowstride = buf->rowstride;
2682
561k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
2683
561k
    if (code < 0)
2684
0
        return code;
2685
    /* Need to set this to avoid color management during the image color render
2686
       operation.  Exception is for the special case when the destination was
2687
       CIELAB.  Then we need to convert from default RGB to CIELAB in the put
2688
       image operation.  That will happen here as we should have set the profile
2689
       for the pdf14 device to RGB and the target will be CIELAB.  In addition,
2690
       the case when we have a blend color space that is different than the
2691
       target device color space */
2692
561k
    pcs->cmm_icc_profile_data = src_profile;
2693
2694
    /* pcs takes a reference to the profile data it just retrieved. */
2695
561k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_image");
2696
561k
    if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS)
2697
0
        return_error(gs_error_rangecheck);
2698
2699
561k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
2700
561k
    gs_image_t_init_adjust(&image, pcs, false);
2701
561k
    image.ImageMatrix.xx = (float)width;
2702
561k
    image.ImageMatrix.yy = (float)height;
2703
561k
    image.Width = width;
2704
561k
    image.Height = height;
2705
561k
    image.BitsPerComponent = deep ? 16 : 8;
2706
561k
    image.ColorSpace = pcs;
2707
561k
    ctm_only_writable(pgs).xx = (float)width;
2708
561k
    ctm_only_writable(pgs).xy = 0;
2709
561k
    ctm_only_writable(pgs).yx = 0;
2710
561k
    ctm_only_writable(pgs).yy = (float)height;
2711
561k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
2712
561k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
2713
    /* Make sure that the relative colorimetric rendering intent is
2714
       used for this image. */
2715
561k
    rendering_intent_saved = pgs->renderingintent;
2716
561k
    pgs->renderingintent = gsRELATIVECOLORIMETRIC;
2717
561k
    code = dev_proc(target, begin_typed_image) (target,
2718
561k
                                                pgs, NULL,
2719
561k
                                                (gs_image_common_t *)&image,
2720
561k
                                                NULL, NULL, NULL,
2721
561k
                                                pgs->memory, &info);
2722
561k
    pgs->renderingintent = rendering_intent_saved;
2723
561k
    if (code < 0) {
2724
0
        rc_decrement_only_cs(pcs, "pdf14_put_image");
2725
0
        return code;
2726
0
    }
2727
#if RAW_DUMP
2728
    /* Dump the current buffer to see what we have. */
2729
    dump_raw_buffer(pdev->ctx->memory,
2730
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
2731
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
2732
                    pdev->ctx->stack->n_planes,
2733
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2734
                    "pdF14_putimage", pdev->ctx->stack->data, deep);
2735
    dump_raw_buffer(pdev->ctx->memory,
2736
                    height, width, buf->n_planes,
2737
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2738
                    "PDF14_PUTIMAGE_SMALL", buf_ptr, deep);
2739
    global_index++;
2740
    clist_band_count++;
2741
#endif
2742
    /* Allocate on 32-byte border for AVX CMYK case. Four byte overflow for RGB case */
2743
    /* 28 byte overflow for AVX CMYK case. */
2744
561k
#define SSE_ALIGN 32
2745
561k
#define SSE_OVERFLOW 28
2746
561k
    linebuf_unaligned = gs_alloc_bytes(pdev->memory, width * (num_comp<<deep) + SSE_ALIGN + SSE_OVERFLOW, "pdf14_put_image");
2747
561k
    if (linebuf_unaligned == NULL)
2748
0
        return gs_error_VMerror;
2749
561k
    linebuf = linebuf_unaligned + ((-(intptr_t)linebuf_unaligned) & (SSE_ALIGN-1));
2750
2751
561k
    blend_row = deep ? gx_build_blended_image_row16 :
2752
561k
                       gx_build_blended_image_row;
2753
#ifdef WITH_CAL
2754
    blend_row = cal_get_blend_row(pdev->memory->gs_lib_ctx->core->cal_ctx,
2755
                                  blend_row, num_comp, deep);
2756
#endif
2757
2758
561k
    bg = additive ? (deep ? 65535 : 255) : 0;
2759
6.20M
    for (y = 0; y < height; y++) {
2760
5.64M
        gx_image_plane_t planes;
2761
5.64M
        int rows_used;
2762
2763
5.64M
        blend_row(buf_ptr, buf->planestride, width, num_comp, bg, linebuf);
2764
5.64M
        planes.data = linebuf;
2765
5.64M
        planes.data_x = 0;
2766
5.64M
        planes.raster = width * num_comp;
2767
5.64M
        info->procs->plane_data(info, &planes, 1, &rows_used);
2768
        /* todo: check return value */
2769
5.64M
        buf_ptr += buf->rowstride;
2770
5.64M
    }
2771
561k
    gs_free_object(pdev->memory, linebuf_unaligned, "pdf14_put_image");
2772
561k
    info->procs->end_image(info, true);
2773
    /* This will also decrement the device profile */
2774
561k
    rc_decrement_only_cs(pcs, "pdf14_put_image");
2775
561k
    return code;
2776
561k
}
2777
2778
/* Overprint simulation with spots.  Collapse to CMYK */
2779
static void
2780
template_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2781
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2782
    cmyk_composite_map *map, bool keep_alpha)
2783
0
{
2784
0
    int comp_num;
2785
0
    uint cyan, magenta, yellow, black;
2786
0
    cmyk_composite_map *cmyk_map_entry;
2787
0
    int x, y;
2788
0
    intptr_t position;
2789
0
    byte comp, a;
2790
2791
0
    for (y = 0; y < height; y++) {
2792
0
        position = y * rowstride;
2793
0
        for (x = 0; x < width; x++) {
2794
0
            a = buf_ptr[position + planestride * num_comp];
2795
0
            if (a != 0) {
2796
0
                cyan = buf_ptr[position] * frac_1;
2797
0
                magenta = buf_ptr[position + planestride] * frac_1;
2798
0
                yellow = buf_ptr[position + planestride * 2] * frac_1;
2799
0
                black = buf_ptr[position + planestride * 3] * frac_1;
2800
0
                cmyk_map_entry = &(map[4]);
2801
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2802
0
                    comp = buf_ptr[position + planestride * comp_num];
2803
0
                    cyan += cmyk_map_entry->c * comp;
2804
0
                    magenta += cmyk_map_entry->m * comp;
2805
0
                    yellow += cmyk_map_entry->y * comp;
2806
0
                    black += cmyk_map_entry->k * comp;
2807
0
                    cmyk_map_entry++;
2808
0
                }
2809
0
                cyan /= frac_1;
2810
0
                magenta /= frac_1;
2811
0
                yellow /= frac_1;
2812
0
                black /= frac_1;
2813
2814
0
                if (cyan > 255)
2815
0
                    cyan = 255;
2816
0
                if (magenta > 255)
2817
0
                    magenta = 255;
2818
0
                if (yellow > 255)
2819
0
                    yellow = 255;
2820
0
                if (black > 255)
2821
0
                    black = 255;
2822
2823
0
                buf_ptr[position] = cyan;
2824
0
                buf_ptr[position + planestride] = magenta;
2825
0
                buf_ptr[position + planestride * 2] = yellow;
2826
0
                buf_ptr[position + planestride * 3] = black;
2827
0
            }
2828
0
            if (keep_alpha) {
2829
                /* Move the alpha and tag data */
2830
0
                buf_ptr[position + planestride * 4] = a;
2831
0
                if (tag_offset > 0) {
2832
0
                    buf_ptr[position + planestride * 5] =
2833
0
                        buf_ptr[position + planestride * tag_offset];
2834
0
                }
2835
0
            } else {
2836
                /* Remove alpha but keep tags */
2837
0
                if (tag_offset > 0) {
2838
0
                    buf_ptr[position + planestride * 4] =
2839
0
                        buf_ptr[position + planestride * tag_offset];
2840
0
                }
2841
2842
0
            }
2843
0
            position += 1;
2844
0
        }
2845
0
    }
2846
0
}
2847
2848
static void
2849
template_spots_to_cmyk_16(byte *buf_ptr_, int width, int height, intptr_t rowstride,
2850
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2851
    cmyk_composite_map *map, bool keep_alpha)
2852
0
{
2853
0
    int comp_num;
2854
0
    ulong cyan, magenta, yellow, black;
2855
0
    cmyk_composite_map *cmyk_map_entry;
2856
0
    int x, y;
2857
0
    intptr_t position;
2858
0
    ulong comp, a;
2859
0
    uint16_t *buf_ptr = (uint16_t *)(void *)buf_ptr_;
2860
2861
    /* planestride and rowstride are in bytes, and we want them in shorts */
2862
0
    planestride >>= 1;
2863
0
    rowstride >>= 1;
2864
2865
0
    for (y = 0; y < height; y++) {
2866
0
        position = y * rowstride;
2867
0
        for (x = 0; x < width; x++) {
2868
0
            a = buf_ptr[position + planestride * num_comp];
2869
0
            if (a != 0) {
2870
0
                cyan = (ulong)buf_ptr[position] * frac_1_long;
2871
0
                magenta = (ulong)buf_ptr[position + planestride] * frac_1_long;
2872
0
                yellow = (ulong)buf_ptr[position + planestride * 2] * frac_1_long;
2873
0
                black = (ulong)buf_ptr[position + planestride * 3] * frac_1_long;
2874
0
                cmyk_map_entry = &(map[4]);
2875
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2876
0
                    comp = buf_ptr[position + planestride * comp_num];
2877
0
                    cyan += (ulong)cmyk_map_entry->c * comp;
2878
0
                    magenta += (ulong)cmyk_map_entry->m * comp;
2879
0
                    yellow += (ulong)cmyk_map_entry->y * comp;
2880
0
                    black += (ulong)cmyk_map_entry->k * comp;
2881
0
                    cmyk_map_entry++;
2882
0
                }
2883
0
                cyan /= frac_1_long;
2884
0
                magenta /= frac_1_long;
2885
0
                yellow /= frac_1_long;
2886
0
                black /= frac_1_long;
2887
2888
0
                if (cyan > 65535)
2889
0
                    cyan = 65535;
2890
0
                if (magenta > 65535)
2891
0
                    magenta = 65535;
2892
0
                if (yellow > 65535)
2893
0
                    yellow = 65535;
2894
0
                if (black > 65535)
2895
0
                    black = 65535;
2896
2897
#if ARCH_IS_BIG_ENDIAN
2898
                buf_ptr[position] = cyan;
2899
                buf_ptr[position + planestride] = magenta;
2900
                buf_ptr[position + planestride * 2] = yellow;
2901
                buf_ptr[position + planestride * 3] = black;
2902
#else
2903
0
                ((byte *)&buf_ptr[position])[0] = cyan >> 8;
2904
0
                ((byte *)&buf_ptr[position])[1] = cyan;
2905
0
                ((byte *)&buf_ptr[position + planestride])[0] = magenta >> 8;
2906
0
                ((byte *)&buf_ptr[position + planestride])[1] = magenta;
2907
0
                ((byte *)&buf_ptr[position + planestride * 2])[0] = yellow >> 8;
2908
0
                ((byte *)&buf_ptr[position + planestride * 2])[1] = yellow;
2909
0
                ((byte *)&buf_ptr[position + planestride * 3])[0] = black >> 8;
2910
0
                ((byte *)&buf_ptr[position + planestride * 3])[1] = black;
2911
0
#endif
2912
0
            }
2913
            /* Move the alpha and tag data */
2914
#if ARCH_IS_BIG_ENDIAN
2915
            if (keep_alpha) {
2916
                buf_ptr[position + planestride * 4] = a;
2917
                if (tag_offset > 0) {
2918
                    buf_ptr[position + planestride * 5] =
2919
                        buf_ptr[position + planestride * tag_offset];
2920
                }
2921
            } else {
2922
                if (tag_offset > 0) {
2923
                    buf_ptr[position + planestride * 4] =
2924
                        buf_ptr[position + planestride * tag_offset];
2925
                }
2926
            }
2927
#else
2928
0
            if (keep_alpha) {
2929
0
                ((byte *)&buf_ptr[position + planestride * 4])[0] = a >> 8;
2930
0
                ((byte *)&buf_ptr[position + planestride * 4])[1] = a;
2931
0
                if (tag_offset > 0) {
2932
0
                    ((byte *)&buf_ptr[position + planestride * 5])[0] =
2933
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2934
0
                    ((byte *)&buf_ptr[position + planestride * 5])[1] =
2935
0
                        buf_ptr[position + planestride * tag_offset];
2936
0
                }
2937
0
            } else {
2938
0
                if (tag_offset > 0) {
2939
0
                    ((byte *)&buf_ptr[position + planestride * 4])[0] =
2940
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2941
0
                    ((byte *)&buf_ptr[position + planestride * 4])[1] =
2942
0
                        buf_ptr[position + planestride * tag_offset];
2943
0
                }
2944
0
            }
2945
0
#endif
2946
0
            position += 1;
2947
0
        }
2948
0
    }
2949
0
}
2950
2951
static void
2952
pdf14_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2953
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2954
    cmyk_composite_map *map, bool keep_alpha, bool deep)
2955
0
{
2956
0
    if (deep) {
2957
0
        if (keep_alpha) {
2958
0
            if (tag_offset > 0) {
2959
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2960
0
                    planestride, num_comp, spot_start, tag_offset,
2961
0
                    map, true);
2962
0
            } else {
2963
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2964
0
                    planestride, num_comp, spot_start, 0,
2965
0
                    map, true);
2966
0
            }
2967
0
        } else {
2968
0
            if (tag_offset > 0) {
2969
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2970
0
                    planestride, num_comp, spot_start, tag_offset,
2971
0
                    map, false);
2972
0
            } else {
2973
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2974
0
                    planestride, num_comp, spot_start, 0,
2975
0
                    map, false);
2976
0
            }
2977
0
        }
2978
0
    } else {
2979
0
        if (keep_alpha) {
2980
0
            if (tag_offset > 0) {
2981
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2982
0
                    planestride, num_comp, spot_start, tag_offset,
2983
0
                    map, true);
2984
0
            } else {
2985
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2986
0
                    planestride, num_comp, spot_start, 0,
2987
0
                    map, true);
2988
0
            }
2989
0
        } else {
2990
0
            if (tag_offset > 0) {
2991
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2992
0
                    planestride, num_comp, spot_start, tag_offset,
2993
0
                    map, false);
2994
0
            } else {
2995
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2996
0
                    planestride, num_comp, spot_start, 0,
2997
0
                    map, false);
2998
0
            }
2999
0
        }
3000
0
    }
3001
0
}
3002
3003
/* This is for the case where we have mixture of spots and additive color.
3004
   For example, RGB + spots or Gray + spots */
3005
static void
3006
pdf14_blend_image_mixed_buffer(byte* buf_ptr, int width, int height, intptr_t rowstride,
3007
    intptr_t planestride, int num_comp, int spot_start)
3008
7.70k
{
3009
7.70k
    int x, y;
3010
7.70k
    intptr_t position;
3011
7.70k
    byte comp, a;
3012
7.70k
    int tmp, comp_num;
3013
3014
80.2k
    for (y = 0; y < height; y++) {
3015
72.5k
        position = y * rowstride;
3016
65.6M
        for (x = 0; x < width; x++) {
3017
65.5M
            a = buf_ptr[position + planestride * num_comp];
3018
65.5M
            if ((a + 1) & 0xfe) {
3019
759k
                a ^= 0xff;
3020
3.03M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3021
2.27M
                    comp = buf_ptr[position + planestride * comp_num];
3022
2.27M
                    tmp = ((0xff - comp) * a) + 0x80;
3023
2.27M
                    comp += (tmp + (tmp >> 8)) >> 8;
3024
2.27M
                    buf_ptr[position + planestride * comp_num] = comp;
3025
2.27M
                }
3026
759k
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3027
0
                    comp = buf_ptr[position + planestride * comp_num];
3028
0
                    tmp = ((-comp) * a) + 0x80;
3029
0
                    comp += (tmp + (tmp >> 8)) >> 8;
3030
0
                    buf_ptr[position + planestride * comp_num] = comp;
3031
0
                }
3032
64.8M
            } else if (a == 0) {
3033
57.2M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3034
42.9M
                    buf_ptr[position + planestride * comp_num] = 0xff;
3035
42.9M
                }
3036
14.3M
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3037
51.1k
                    buf_ptr[position + planestride * comp_num] = 0;
3038
51.1k
                }
3039
14.3M
            }
3040
65.5M
            position += 1;
3041
65.5M
        }
3042
72.5k
    }
3043
7.70k
}
3044
3045
static void
3046
pdf14_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, intptr_t rowstride,
3047
    intptr_t planestride, int num_comp, int spot_start)
3048
0
{
3049
0
    uint16_t* buf_ptr = (uint16_t*)(void*)buf_ptr_;
3050
0
    int x, y;
3051
0
    intptr_t position;
3052
0
    int comp, a;
3053
0
    int tmp, comp_num;
3054
3055
    /* planestride and rowstride are in bytes, and we want them in shorts */
3056
0
    planestride >>= 1;
3057
0
    rowstride >>= 1;
3058
3059
    /* Note that the input here is native endian, and the output must be in big endian! */
3060
0
    for (y = 0; y < height; y++) {
3061
0
        position = y * rowstride;
3062
0
        for (x = 0; x < width; x++) {
3063
            /* composite RGBA (or CMYKA, etc.) pixel with over solid background */
3064
0
            a = buf_ptr[position + planestride * num_comp];
3065
0
            if (a == 0) {
3066
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3067
0
                    buf_ptr[position + planestride * comp_num] = 0xffff;
3068
0
                }
3069
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3070
0
                    buf_ptr[position + planestride * comp_num] = 0;
3071
0
                }
3072
0
            } else if (a == 0xffff) {
3073
#if ARCH_IS_BIG_ENDIAN
3074
#else
3075
                /* Convert from native -> big endian */
3076
0
                for (comp_num = 0; comp_num < num_comp; comp_num++) {
3077
0
                    comp = buf_ptr[position + planestride * comp_num];
3078
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3079
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3080
0
                }
3081
0
#endif
3082
0
            } else {
3083
0
                a ^= 0xffff;
3084
0
                a += a >> 15; /* a is now 0 to 0x10000 */
3085
0
                a >>= 1; /* We can only use 15 bits as bg-comp has a sign bit we can't lose */
3086
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3087
0
                    comp = buf_ptr[position + planestride * comp_num];
3088
0
                    tmp = ((0xffff - comp) * a) + 0x4000;
3089
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3090
                    /* Store as big endian */
3091
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3092
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3093
0
                }
3094
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3095
0
                    comp = buf_ptr[position + planestride * comp_num];
3096
0
                    tmp = ((0 - comp) * a) + 0x4000;
3097
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3098
                    /* Store as big endian */
3099
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3100
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3101
0
                }
3102
0
            }
3103
0
            position += 1;
3104
0
        }
3105
0
    }
3106
0
}
3107
3108
static int
3109
pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target,
3110
    gs_gstate* pgs, pdf14_buf* buf, intptr_t planestride_in,
3111
    intptr_t rowstride_in, int x0, int y0, int width, int height,
3112
    int num_comp, int additive, bool has_tags, gs_int_rect rect_in,
3113
    gs_separations* pseparations, bool deep)
3114
23.4k
{
3115
23.4k
    pdf14_device* pdev = (pdf14_device*)dev;
3116
23.4k
    int code = 0;
3117
23.4k
    int y;
3118
23.4k
    int num_rows_left;
3119
23.4k
    int i;
3120
23.4k
    gs_int_rect rect = rect_in;
3121
23.4k
    intptr_t planestride = planestride_in;
3122
23.4k
    intptr_t rowstride = rowstride_in;
3123
23.4k
    byte* buf_ptr = NULL;
3124
23.4k
    cmm_profile_t* src_profile = buf->group_color_info->icc_profile;
3125
23.4k
    cmm_profile_t* des_profile = NULL;
3126
23.4k
    cmm_dev_profile_t* dev_target_profile;
3127
23.4k
    cmm_dev_profile_t* pdf14dev_profile;
3128
23.4k
    bool color_mismatch = false;
3129
23.4k
    bool supports_alpha = false;
3130
23.4k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
3131
23.4k
    int alpha_offset = num_comp;
3132
23.4k
    int tag_offset = has_tags ? num_comp + 1 : 0;
3133
23.4k
    gs_color_space *pcs;
3134
23.4k
    gs_image1_t image;
3135
23.4k
    gx_image_enum_common_t *info;
3136
23.4k
    gx_image_plane_t planes[GS_IMAGE_MAX_COMPONENTS];
3137
23.4k
    pdf14_buf *cm_result = NULL;
3138
23.4k
    bool did_alloc;
3139
23.4k
    bool target_sep_device = (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0);
3140
23.4k
    bool has_spots = pdev->ctx->num_spots > 0;
3141
23.4k
    bool blend_spots = !target_sep_device && has_spots;
3142
23.4k
    bool lose_channels = false;
3143
3144
    /* Check if group color space is CMYK based */
3145
23.4k
    code = dev_proc(target, get_profile)(target, &dev_target_profile);
3146
23.4k
    if (code < 0)
3147
0
        return code;
3148
23.4k
    if (dev_target_profile == NULL)
3149
0
        return gs_throw_code(gs_error_Fatal);
3150
3151
23.4k
    if (src_profile == NULL) {
3152
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
3153
0
        if (code < 0) {
3154
0
            return code;
3155
0
        }
3156
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3157
0
    }
3158
3159
    /* If the target device does not support spot colors and we have spot colors
3160
       here due to overprint simulation (blend_spots == true), then we will need to convert the base
3161
       colors to CMYK if it is RGB or Gray so tha we can blend in the spot colors */
3162
23.4k
    if (blend_spots && src_profile->data_cs != gsCMYK) {
3163
3164
0
        cm_result = pdf14_transform_color_buffer_no_matte(pgs, pdev->ctx, (gx_device *)dev, buf,
3165
0
            buf->data, src_profile, pgs->icc_manager->default_cmyk, 0, 0, buf->rect.q.x,
3166
0
            buf->rect.q.y, &did_alloc, buf->deep, false, false);
3167
0
        if (cm_result == NULL)
3168
0
            return_error(gs_error_VMerror);
3169
3170
        /* Update */
3171
0
        buf = cm_result;
3172
0
        src_profile = pgs->icc_manager->default_cmyk;
3173
0
        num_comp = buf->n_chan - 1;
3174
0
        additive = 0;
3175
0
        tag_offset = has_tags ? num_comp + 1 : 0;
3176
0
        alpha_offset = num_comp;
3177
3178
#if RAW_DUMP
3179
        buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3180
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3181
            "convertbase_to_cmyk_for_spot_blend", buf_ptr, deep);
3182
        global_index++;
3183
#endif
3184
0
    }
3185
3186
    /* Fix order map if needed */
3187
109k
    for (i = 0; i < num_comp; i++) {
3188
86.0k
        pdev->devn_params.separation_order_map[i] = i;
3189
86.0k
    }
3190
3191
    /* Check if we have a color conversion issue */
3192
23.4k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3193
23.4k
    if (!gsicc_profiles_equal(des_profile, src_profile))
3194
7.70k
        color_mismatch = true;
3195
23.4k
    if (des_profile->data_cs == gsNCHANNEL)
3196
0
        lose_channels = true;
3197
3198
    /* Check if target supports alpha */
3199
23.4k
    supports_alpha = (dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0) > 0);
3200
23.4k
    code = 0;
3201
3202
23.4k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3203
3204
    /* Note. The logic below will need a little rework if we ever
3205
       have a device that has tags and alpha support */
3206
23.4k
    if (supports_alpha) {
3207
3208
        /* If doing simulated overprint, Bring the spot color channels into
3209
           CMYK. Data is planar and 16 bit data in native format. */
3210
0
        if (pdev->overprint_sim && pdev->devn_params.page_spot_colors > 0) {
3211
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3212
3213
            /* In the clist case, we need to get equiv spots out of the pseudo-band. */
3214
0
            if (pdev->pclist_device != NULL) {
3215
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3216
3217
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3218
0
                if (code < 0)
3219
0
                    return code;
3220
0
            }
3221
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3222
3223
            /* Now we go to big endian */
3224
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3225
0
                planestride, num_comp, src_profile->num_comps,
3226
0
                tag_offset, cmyk_map, true, deep);
3227
3228
            /* Reset buffer information. We have CMYK+alpha and maybe tags */
3229
0
            buf->n_chan = buf->n_chan - buf->num_spots;
3230
0
            buf->n_planes = buf->n_planes - buf->num_spots;
3231
0
            buf->num_spots = 0;
3232
0
            num_comp = buf->n_chan - 1;
3233
0
            tag_offset = has_tags ? buf->n_planes - 1 : 0; /* Tags at end */
3234
0
        }
3235
3236
0
        if (!color_mismatch) {
3237
0
            for (i = 0; i < buf->n_planes; i++)
3238
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3239
0
            for (; i < target->color_info.num_components; i++)
3240
0
                buf_ptrs[i] = 0;
3241
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3242
0
                rect.p.x, rect.p.y, width, height,
3243
0
                rowstride, alpha_offset, tag_offset);
3244
            /* Right now code has number of rows written */
3245
0
        } else {
3246
            /* In this case, just color convert and maintain alpha.
3247
               This is a case where we either either blend in the
3248
               right color space and have no alpha for the output
3249
               device or hand back the wrong color space with
3250
               alpha data.  We choose the later. */
3251
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
3252
0
                        dev_target_profile, &buf, &buf_ptr, false, rect.p.x,
3253
0
                        rect.p.y, width, height, false);
3254
0
            if (code < 0)
3255
0
                return code;
3256
3257
            /* reset */
3258
0
            rowstride = buf->rowstride;
3259
0
            planestride = buf->planestride;
3260
0
            num_comp = buf->n_chan - 1;
3261
0
            alpha_offset = num_comp;
3262
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3263
3264
            /* And then out */
3265
0
            for (i = 0; i < buf->n_planes; i++)
3266
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3267
0
            for (; i < target->color_info.num_components; i++)
3268
0
                buf_ptrs[i] = 0;
3269
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3270
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
3271
0
                tag_offset);
3272
            /* Right now code has number of rows written.  Writing continues below */
3273
0
        }
3274
23.4k
    } else {
3275
        /* Device could not handle the alpha data (we actually don't have
3276
           a device that does spot colorants and has an alpha channel so
3277
           the above code is untested.  Go ahead and preblend now and then
3278
           color convert if needed */
3279
#if RAW_DUMP
3280
           /* Dump before and after the blend to make sure we are doing that ok */
3281
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3282
            "pre_put_image_blend_image", buf_ptr, deep);
3283
        global_index++;
3284
#endif
3285
3286
23.4k
        if (color_mismatch && (src_profile->data_cs == gsRGB || src_profile->data_cs == gsGRAY)) {
3287
7.70k
            if (deep) {
3288
            /* In this case, we are NOT going to bring the spots into the CMYK
3289
               equivalent colors, since otherwise src_profile would be CMYK based.  So
3290
               16 bit data will be converted now from native endian to big endian during
3291
               the blending process */
3292
0
                pdf14_blend_image_mixed_buffer16(buf_ptr, width, height, rowstride,
3293
0
                    planestride, num_comp, src_profile->num_comps);
3294
7.70k
            } else {
3295
7.70k
                pdf14_blend_image_mixed_buffer(buf_ptr, width, height, rowstride,
3296
7.70k
                    planestride, num_comp, src_profile->num_comps);
3297
7.70k
            }
3298
15.7k
        } else {
3299
15.7k
            if (deep) {
3300
            /* In this case, if blend_spots == true, we will shortly be bringing
3301
               the spot colors to CMYK equivalent colors. It is at that time that
3302
               we will convert from native endian to big endian. In all other
3303
               cases this blending will due to conversion from native to BE */
3304
0
                bool keep_native = (blend_spots == true);
3305
3306
0
                gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
3307
0
                    planestride, num_comp, additive, keep_native);
3308
15.7k
            } else {
3309
15.7k
                gx_blend_image_buffer(buf_ptr, width, height, rowstride,
3310
15.7k
                    planestride, num_comp, additive);
3311
15.7k
            }
3312
15.7k
        }
3313
3314
23.4k
        if (deep && has_tags)
3315
0
        {
3316
            /* We still need to convert the tags from Native to BE */
3317
#if ARCH_IS_BIG_ENDIAN
3318
#else
3319
0
            uint16_t *tags = (uint16_t *)&buf_ptr[tag_offset * planestride];
3320
0
            int i, j;
3321
0
            for (j = 0; j < height; j++)
3322
0
            {
3323
0
                for (i = 0; i < width; i++)
3324
0
                {
3325
0
                    uint16_t tag = *tags++;
3326
0
                    ((byte *)tags)[-2] = tag >> 8;
3327
0
                    ((byte *)tags)[-1] = tag;
3328
0
                }
3329
0
                tags += (buf->rowstride>>1) - width;
3330
0
            }
3331
0
#endif
3332
0
        }
3333
3334
#if RAW_DUMP
3335
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3336
            "post_put_image_blend_image", buf_ptr, deep);
3337
        global_index++;
3338
#endif
3339
3340
        /* If doing simulated overprint and we are not going to a sep device and
3341
           we have spot colors, then bring the spot color channels into CMYK
3342
           (We should have already converted our base color space to CMYK if it was RGB or gray).
3343
           At this point, data is planar and 16 bit data is still in native format. It is
3344
           here that 16 bit data will be converted to BE. Otherwise it will have been converted
3345
           above during the alpha blend operation. */
3346
23.4k
        if (blend_spots) {
3347
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3348
3349
            /* In the clist case, we need to get equiv spots out of the
3350
               pseudo-band. */
3351
0
            if (pdev->pclist_device != NULL) {
3352
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3353
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3354
0
                if (code < 0)
3355
0
                    return code;
3356
0
            }
3357
3358
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3359
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3360
0
                planestride, num_comp, src_profile->num_comps,
3361
0
                tag_offset, cmyk_map, false, deep);
3362
3363
            /* Reset buffer information. We have CMYK and maybe tags */
3364
0
            num_comp = 4;
3365
0
            alpha_offset = 0;
3366
0
            buf->n_chan = buf->n_chan - buf->num_spots - 1;     /* No spots or alpha */
3367
0
            buf->n_planes = buf->n_planes - buf->num_spots - 1; /* No spots or alpha */
3368
0
            tag_offset = has_tags ? buf->n_chan : 0;      /* Tags at end */
3369
0
            buf->num_spots = 0;
3370
3371
#if RAW_DUMP
3372
            dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3373
                "post_put_image_spot_to_cmyk", buf_ptr, deep);
3374
            global_index++;
3375
#endif
3376
0
        }
3377
3378
        /* Map to the destination color space */
3379
23.4k
        if (color_mismatch) {
3380
            /* We started out with the original process colorants, and spots. If we have an
3381
             * nchannel output profile, this can mean that the first few spots might come from
3382
             * that and the rest from the document itself. e.g:
3383
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3384
             * Then we might have a blend space that changes the process colorants:
3385
             *        R, G, B, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3386
             * Now we're about to convert 'RGB' back to 'CMYKII'.
3387
             * If we're not careful, we'll end up with:
3388
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3389
             * so we might need to lose some channels.      ^^^^^^^^^^^^^^^^^^^^^^^^
3390
             */
3391
7.70k
            int num_original_process_colorants = target->color_info.num_components - has_tags - buf->num_spots;
3392
7.70k
            int num_channels_to_lose = lose_channels ? des_profile->num_comps - num_original_process_colorants : 0;
3393
7.70k
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
3394
7.70k
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, num_channels_to_lose);
3395
7.70k
            if (code < 0)
3396
0
                return code;
3397
3398
            /* reset */
3399
7.70k
            rowstride = buf->rowstride;
3400
7.70k
            planestride = buf->planestride;
3401
7.70k
            num_comp = buf->n_chan;
3402
7.70k
            tag_offset = buf->has_tags ? (buf->n_chan - num_channels_to_lose) : 0;
3403
7.70k
        }
3404
3405
#if RAW_DUMP
3406
        /* Dump after the CS transform */
3407
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3408
            "post_put_image_color_convert", buf_ptr, deep);
3409
        global_index++;
3410
        /* clist_band_count++; */
3411
#endif
3412
3413
        /* Try put_image again. This can occur if the
3414
           target, like psdcmyk and tiffsep, support put_image */
3415
23.4k
        alpha_offset = 0;
3416
140k
        for (i = 0; i < buf->n_planes; i++)
3417
117k
            buf_ptrs[i] = buf_ptr + i * planestride;
3418
23.4k
        for (; i < target->color_info.num_components; i++)
3419
0
            buf_ptrs[i] = 0;
3420
23.4k
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3421
23.4k
            rect.p.x, rect.p.y, width, height,
3422
23.4k
            rowstride, alpha_offset, tag_offset);
3423
23.4k
    }
3424
3425
    /* Put image was succesful.  We processed some or all of the rows.
3426
       Continue until we are done */
3427
23.4k
    if (code > 0) {
3428
109
        num_rows_left = height - code;
3429
109
        while (num_rows_left > 0) {
3430
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3431
0
                rect.p.x, rect.p.y + code, width, num_rows_left, rowstride,
3432
0
                alpha_offset, tag_offset);
3433
0
            if (code < 0) {
3434
0
                return code;
3435
0
            }
3436
0
            num_rows_left = num_rows_left - code;
3437
0
        }
3438
109
        return 0;
3439
109
    }
3440
3441
    /* Sep devices all support put_image (tiffsep and psdcmyk)
3442
       as well as those devices that support alpha (pngalpha,
3443
       png16malpha). If we are here, then we are doing an
3444
       overprint simulation on some other device. Image data
3445
       is aleady blended and in device color space. */
3446
23.3k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
3447
23.3k
    if (code < 0)
3448
0
        return code;
3449
3450
    /* Already in destination CS */
3451
23.3k
    pcs->cmm_icc_profile_data = des_profile;
3452
3453
    /* pcs takes a reference to the profile data it just retrieved. */
3454
23.3k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_blended_image_cmykspot");
3455
23.3k
    if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS)
3456
0
        return_error(gs_error_rangecheck);
3457
23.3k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
3458
3459
    /* If we have more components to write out than are in the des_profile,
3460
     * then just using a PCS based on des_profile, will result in us dropping
3461
     * the spot colors.
3462
     * So, if our target supports devn colors, we instead construct a
3463
     * DevN device space with colors names taken from the devn_params, and
3464
     * use that instead. */
3465
23.3k
    if (des_profile->num_comps != target->color_info.num_components &&
3466
24
        dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0)
3467
24
    {
3468
24
        int num_std;
3469
24
        gs_devn_params *devn_params =  dev_proc(target, ret_devn_params)(target);
3470
24
        gs_color_space *pcs2 = pcs;
3471
24
        code = gs_cspace_new_DeviceN(&pcs, target->color_info.num_components,
3472
24
                                     pcs2, pgs->memory->non_gc_memory);
3473
24
        if (code < 0)
3474
0
            return code;
3475
        /* set up a usable DeviceN space with info from the tdev->devn_params */
3476
24
        pcs->params.device_n.use_alt_cspace = false;
3477
24
        num_std = devn_params->num_std_colorant_names;
3478
120
        for (i = 0; i < num_std; i++) {
3479
96
            const char *name = devn_params->std_colorant_names[i];
3480
96
            size_t len = strlen(name);
3481
96
            pcs->params.device_n.names[i] = (char *)gs_alloc_bytes(pgs->memory->non_gc_memory, len + 1, "mem_planar_put_image_very_slow");
3482
96
            if (pcs->params.device_n.names[i] == NULL) {
3483
0
                int j = 0;
3484
0
                for (j = 0;j < i; j++) {
3485
0
                    if (pcs->params.device_n.names[j] != NULL)
3486
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3487
0
                    pcs->params.device_n.names[j] = NULL;
3488
0
                }
3489
0
                return_error(gs_error_VMerror);
3490
0
            }
3491
96
            strcpy(pcs->params.device_n.names[i], name);
3492
96
        }
3493
24
        for (; i < devn_params->separations.num_separations; i++) {
3494
0
            devn_separation_name *name = &devn_params->separations.names[i - num_std];
3495
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");
3496
0
            if (pcs->params.device_n.names[i] == NULL) {
3497
0
                int j = 0;
3498
0
                for (j = 0;j < i; j++) {
3499
0
                    if (pcs->params.device_n.names[j] != NULL)
3500
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3501
0
                    pcs->params.device_n.names[j] = NULL;
3502
0
                }
3503
0
                return_error(gs_error_VMerror);
3504
0
            }
3505
0
            memcpy(pcs->params.device_n.names[i], devn_params->separations.names[i - num_std].data, name->size);
3506
0
            pcs->params.device_n.names[i][name->size] = 0;
3507
0
        }
3508
24
        if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
3509
0
            return code;
3510
0
        }
3511
        /* One last thing -- we need to fudge the pgs->color_component_map */
3512
144
        for (i=0; i < dev->color_info.num_components; i++)
3513
120
            pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
3514
24
    }
3515
3516
23.3k
    gs_image_t_init_adjust(&image, pcs, false);
3517
23.3k
    image.ImageMatrix.xx = (float)width;
3518
23.3k
    image.ImageMatrix.yy = (float)height;
3519
23.3k
    image.Width = width;
3520
23.3k
    image.Height = height;
3521
23.3k
    image.BitsPerComponent = deep ? 16 : 8;
3522
23.3k
    image.ColorSpace = pcs;
3523
23.3k
    image.format = gs_image_format_component_planar;
3524
3525
23.3k
    ctm_only_writable(pgs).xx = (float)width;
3526
23.3k
    ctm_only_writable(pgs).xy = 0;
3527
23.3k
    ctm_only_writable(pgs).yx = 0;
3528
23.3k
    ctm_only_writable(pgs).yy = (float)height;
3529
23.3k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
3530
23.3k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
3531
23.3k
    code = dev_proc(target, begin_typed_image) (target,
3532
23.3k
        pgs, NULL, (gs_image_common_t *)&image,
3533
23.3k
        NULL, NULL, NULL, pgs->memory, &info);
3534
23.3k
    if (code < 0) {
3535
0
        rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3536
0
        return code;
3537
0
    }
3538
#if RAW_DUMP
3539
    /* Dump the current buffer to see what we have. */
3540
    dump_raw_buffer(pdev->ctx->memory,
3541
        pdev->ctx->stack->rect.q.y - pdev->ctx->stack->rect.p.y,
3542
        pdev->ctx->stack->rect.q.x - pdev->ctx->stack->rect.p.x,
3543
        pdev->ctx->stack->n_planes,
3544
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3545
        "put_image_final_big", pdev->ctx->stack->data, deep);
3546
    dump_raw_buffer(pdev->ctx->memory,
3547
        height, width, buf->n_planes,
3548
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3549
        "put_image_final_small", buf_ptr, deep);
3550
    global_index++;
3551
    clist_band_count++;
3552
#endif
3553
3554
124k
    for (i = 0; i < num_comp; i++) {
3555
100k
        planes[i].data = buf_ptr + i * planestride;
3556
100k
        planes[i].data_x = 0;
3557
100k
        planes[i].raster = buf->rowstride;
3558
100k
    }
3559
3560
254k
    for (y = 0; y < height; y++) {
3561
231k
        int rows_used;
3562
3563
231k
        info->procs->plane_data(info, (const gx_image_plane_t*) &planes, 1, &rows_used);
3564
3565
1.22M
        for (i = 0; i < num_comp; i++) {
3566
997k
            planes[i].data += buf->rowstride;
3567
997k
        }
3568
231k
    }
3569
23.3k
    info->procs->end_image(info, true);
3570
3571
    /* This will also decrement the profile */
3572
23.3k
    rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3573
23.3k
    return code;
3574
23.3k
}
3575
3576
/**
3577
 * pdf14_cmykspot_put_image: Put rendered image to target device.
3578
 * @pdev: The PDF 1.4 rendering device.
3579
 * @pgs: State for image draw operation.
3580
 * @target: The target device.
3581
 *
3582
 * Puts the rendered image in @pdev's buffer to @target. This is called
3583
 * as part of the sequence of popping the PDF 1.4 device filter.
3584
 *
3585
 * Return code: negative on error.
3586
 **/
3587
static  int
3588
pdf14_cmykspot_put_image(gx_device *dev, gs_gstate *pgs, gx_device *target)
3589
66.3k
{
3590
66.3k
    pdf14_device *pdev = (pdf14_device *)dev;
3591
66.3k
    pdf14_buf *buf = pdev->ctx->stack;
3592
66.3k
    gs_int_rect rect;
3593
66.3k
    int x1, y1, width, height;
3594
66.3k
    gs_devn_params *pdevn_params = &pdev->devn_params;
3595
66.3k
    gs_separations *pseparations = &pdevn_params->separations;
3596
66.3k
    intptr_t planestride;
3597
66.3k
    intptr_t rowstride;
3598
66.3k
    bool deep = pdev->ctx->deep;
3599
66.3k
    int num_comp;
3600
3601
    /* Nothing was ever drawn. */
3602
66.3k
    if (buf == NULL)
3603
25.5k
        return 0;
3604
3605
40.8k
    num_comp = buf->n_chan - 1;
3606
40.8k
    rect = buf->rect;
3607
40.8k
    planestride = buf->planestride;
3608
40.8k
    rowstride = buf->rowstride;
3609
3610
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3611
       potential problem. Bug 694190 */
3612
40.8k
    if (buf->saved != NULL) {
3613
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3614
0
    }
3615
40.8k
    if_debug0m('v', dev->memory, "[v]pdf14_cmykspot_put_image\n");
3616
40.8k
    rect_intersect(rect, buf->dirty);
3617
40.8k
    x1 = min(pdev->width, rect.q.x);
3618
40.8k
    y1 = min(pdev->height, rect.q.y);
3619
40.8k
    width = x1 - rect.p.x;
3620
40.8k
    height = y1 - rect.p.y;
3621
40.8k
    if (width <= 0 || height <= 0 || buf->data == NULL)
3622
17.3k
        return 0;
3623
3624
#if RAW_DUMP
3625
    /* Dump the current buffer to see what we have. */
3626
    dump_raw_buffer(pdev->ctx->memory,
3627
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
3628
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
3629
                    pdev->ctx->stack->n_planes,
3630
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3631
                    "CMYK_SPOT_PUTIMAGE", pdev->ctx->stack->data,
3632
                    pdev->ctx->stack->deep);
3633
3634
    global_index++;
3635
    clist_band_count++;
3636
#endif
3637
3638
23.4k
    return pdf14_put_blended_image_cmykspot(dev, target, pgs,
3639
23.4k
                      buf, planestride, rowstride,
3640
23.4k
                      rect.p.x, rect.p.y, width, height, num_comp, buf->group_color_info->isadditive,
3641
23.4k
                      buf->has_tags, rect, pseparations, deep);
3642
40.8k
}
3643
3644
/**
3645
 * pdf14_custom_put_image: Put rendered image to target device.
3646
 * @pdev: The PDF 1.4 rendering device.
3647
 * @pgs: State for image draw operation.
3648
 * @target: The target device.
3649
 *
3650
 * Puts the rendered image in @pdev's buffer to @target. This is called
3651
 * as part of the sequence of popping the PDF 1.4 device filter.
3652
 *
3653
 * Return code: negative on error.
3654
 **/
3655
static  int
3656
pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
3657
0
{
3658
0
    pdf14_device * pdev = (pdf14_device *)dev;
3659
0
    pdf14_buf *buf = pdev->ctx->stack;
3660
0
    bool deep = pdev->ctx->deep;
3661
0
    gs_int_rect rect;
3662
0
    int x0, y0;
3663
0
    intptr_t planestride;
3664
0
    intptr_t rowstride;
3665
0
    int num_comp;
3666
0
    uint16_t bg;
3667
0
    int x1, y1, width, height;
3668
0
    byte *buf_ptr;
3669
3670
    /* Nothing was ever drawn. */
3671
0
    if (buf == NULL)
3672
0
        return 0;
3673
3674
0
    bg = pdev->ctx->additive ? 0xffff : 0;
3675
0
    num_comp = buf->n_chan - 1;
3676
0
    rect = buf->rect;
3677
0
    x0 = rect.p.x;
3678
0
    y0 = rect.p.y;
3679
0
    planestride = buf->planestride;
3680
0
    rowstride = buf->rowstride;
3681
3682
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3683
       potential problem. Bug 694190 */
3684
0
    if (buf->saved != NULL) {
3685
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3686
0
    }
3687
0
    if_debug0m('v', dev->memory, "[v]pdf14_custom_put_image\n");
3688
0
    rect_intersect(rect, buf->dirty);
3689
0
    x1 = min(pdev->width, rect.q.x);
3690
0
    y1 = min(pdev->height, rect.q.y);
3691
0
    width = x1 - rect.p.x;
3692
0
    height = y1 - rect.p.y;
3693
0
    if (width <= 0 || height <= 0 || buf->data == NULL)
3694
0
        return 0;
3695
0
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x)<<deep);
3696
3697
0
    return gx_put_blended_image_custom(target, buf_ptr,
3698
0
                      planestride, rowstride,
3699
0
                      x0, y0, width, height, num_comp, bg, deep);
3700
0
}
3701
3702
/* This is rather nasty: in the event we are interrupted (by an error) between a push and pop
3703
 * of one or more groups, we have to cycle through any ICC profile changes since the push
3704
 * putting everything back how it was, and cleaning up the reference counts.
3705
 */
3706
static void pdf14_cleanup_group_color_profiles (pdf14_device *pdev)
3707
1.93M
{
3708
1.93M
    if (pdev->ctx && pdev->ctx->stack) {
3709
809k
        pdf14_buf *buf, *next;
3710
3711
809k
        for (buf = pdev->ctx->stack->saved; buf != NULL; buf = next) {
3712
16
            pdf14_group_color_t *group_color_info = buf->group_color_info;
3713
16
            next = buf->saved;
3714
32
            while (group_color_info) {
3715
16
               if (group_color_info->icc_profile != NULL) {
3716
16
                   cmm_profile_t *group_profile;
3717
16
                   gsicc_rendering_param_t render_cond;
3718
16
                   cmm_dev_profile_t *dev_profile;
3719
16
                   int code = dev_proc((gx_device *)pdev, get_profile)((gx_device *)pdev,  &dev_profile);
3720
3721
16
                   if (code >= 0) {
3722
16
                       gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
3723
16
                                             &render_cond);
3724
3725
16
                       gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
3726
16
                                               -1, "pdf14_end_transparency_group");
3727
16
                       pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
3728
16
                           group_color_info->icc_profile;
3729
16
                       group_color_info->icc_profile = NULL;
3730
16
                   }
3731
16
               }
3732
3733
16
               group_color_info = group_color_info->previous;
3734
16
            }
3735
16
        }
3736
809k
    }
3737
1.93M
}
3738
3739
static  int
3740
pdf14_close(gx_device *dev)
3741
965k
{
3742
965k
    pdf14_device *pdev = (pdf14_device *)dev;
3743
3744
965k
    pdf14_cleanup_group_color_profiles(pdev);
3745
3746
965k
    if (pdev->ctx) {
3747
958k
        pdf14_ctx_free(pdev->ctx);
3748
958k
        pdev->ctx = NULL;
3749
958k
    }
3750
965k
    return 0;
3751
965k
}
3752
3753
/* This is called when something has gone wrong and the interpreter received a
3754
   stop while in the middle of doing something with the PDF14 device.  We need
3755
   to clean up and end this in a graceful manner */
3756
static int
3757
pdf14_discard_trans_layer(gx_device *dev, gs_gstate * pgs)
3758
0
{
3759
0
    pdf14_device *pdev = (pdf14_device *)dev;
3760
    /* The things that need to be cleaned up */
3761
0
    pdf14_ctx *ctx = pdev->ctx;
3762
0
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
3763
3764
    /* Free up the smask color */
3765
0
    if (smaskcolor != NULL) {
3766
0
        smaskcolor->ref_count = 1;
3767
0
        pdf14_decrement_smask_color(pgs, dev);
3768
0
        pdev->smaskcolor = NULL;
3769
0
    }
3770
3771
    /* Free up the nested color procs and decrement the profiles */
3772
0
    while (pdev->color_model_stack)
3773
0
        pdf14_pop_group_color(dev, NULL);
3774
3775
    /* Start the context clean up */
3776
0
    if (ctx != NULL) {
3777
0
        pdf14_buf *buf, *next;
3778
0
        pdf14_group_color_t *procs, *prev_procs;
3779
3780
0
        if (ctx->mask_stack != NULL) {
3781
0
            rc_decrement(ctx->mask_stack, "pdf14_discard_trans_layer");
3782
0
        }
3783
3784
        /* Now the stack of buffers */
3785
0
        for (buf = ctx->stack; buf != NULL; buf = next) {
3786
0
            next = buf->saved;
3787
3788
0
            gs_free_object(ctx->memory, buf->transfer_fn, "pdf14_discard_trans_layer");
3789
0
            gs_free_object(ctx->memory, buf->matte, "pdf14_discard_trans_layer");
3790
0
            gs_free_object(ctx->memory, buf->data, "pdf14_discard_trans_layer");
3791
0
            gs_free_object(ctx->memory, buf->backdrop, "pdf14_discard_trans_layer");
3792
            /* During the soft mask push, the mask_stack was copied (not moved) from
3793
               the ctx to the tos mask_stack. We are done with this now so it is safe
3794
               to free this one object */
3795
0
            gs_free_object(ctx->memory, buf->mask_stack, "pdf14_discard_trans_layer");
3796
0
            for (procs = buf->group_color_info; procs != NULL; procs = prev_procs) {
3797
0
                prev_procs = procs->previous;
3798
0
                gs_free_object(ctx->memory, procs, "pdf14_discard_trans_layer");
3799
0
            }
3800
0
            gs_free_object(ctx->memory, buf, "pdf14_discard_trans_layer");
3801
0
        }
3802
        /* Finally the context itself */
3803
0
        gs_free_object(ctx->memory, ctx, "pdf14_discard_trans_layer");
3804
0
        pdev->ctx = NULL;
3805
0
    }
3806
0
    return 0;
3807
0
}
3808
3809
static  int
3810
pdf14_output_page(gx_device * dev, int num_copies, int flush)
3811
0
{
3812
0
    pdf14_device * pdev = (pdf14_device *)dev;
3813
3814
0
    if (pdev->target != NULL)
3815
0
        return (*dev_proc(pdev->target, output_page)) (pdev->target, num_copies, flush);
3816
0
    return 0;
3817
0
}
3818
3819
7.76M
#define COPY_PARAM(p) dev->p = target->p
3820
4.85M
#define COPY_ARRAY_PARAM(p) memcpy(dev->p, target->p, sizeof(dev->p))
3821
3822
static void
3823
copy_tag_setup(gx_device *dev, const gx_device *target)
3824
970k
{
3825
970k
    bool deep = device_is_deep(target);
3826
970k
    int had_tags = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3827
970k
    int has_tags = (target->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3828
970k
    COPY_PARAM(graphics_type_tag);
3829
970k
    if (had_tags && !has_tags)
3830
0
    {
3831
        /* We have just removed a tags plane. Adjust num_components and depth accordingly. */
3832
0
        dev->color_info.num_components--;
3833
0
        dev->color_info.depth -= deep ? 16 : 8;
3834
0
    }
3835
970k
    else if (!had_tags && has_tags)
3836
0
    {
3837
        /* We have just added a tags plane. Adjust num_components and depth accordingly. */
3838
0
        dev->color_info.num_components++;
3839
0
        dev->color_info.depth += deep ? 16 : 8;
3840
0
    }
3841
970k
}
3842
3843
/*
3844
 * Copy device parameters back from a target.  This copies all standard
3845
 * parameters related to page size and resolution, but not any of the
3846
 * color-related parameters, as the pdf14 device retains its own color
3847
 * handling. This routine is parallel to gx_device_copy_params().
3848
 * Note that it DOES copy the devn_params since these are required to
3849
 * keep agreement with colorant name->number mapping, and don't change
3850
 * with the pdf14 color handling.
3851
 */
3852
static  int
3853
gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target)
3854
970k
{
3855
970k
    cmm_dev_profile_t *profile_targ;
3856
970k
    cmm_dev_profile_t *profile_dev14;
3857
970k
    pdf14_device *pdev = (pdf14_device*) dev;
3858
970k
    cmm_profile_t *blend_profile = NULL;
3859
970k
    int k;
3860
3861
970k
    COPY_PARAM(width);
3862
970k
    COPY_PARAM(height);
3863
970k
    COPY_ARRAY_PARAM(MediaSize);
3864
970k
    COPY_ARRAY_PARAM(ImagingBBox);
3865
970k
    COPY_PARAM(ImagingBBox_set);
3866
970k
    COPY_ARRAY_PARAM(HWResolution);
3867
970k
    COPY_ARRAY_PARAM(Margins);
3868
970k
    COPY_ARRAY_PARAM(HWMargins);
3869
970k
    COPY_PARAM(PageCount);
3870
970k
    COPY_PARAM(MaxPatternBitmap);
3871
3872
3873
    /* Supposedly this function isn't supposed to change the color setup of dev.
3874
     * BUT... if we change the tags value, we have to change the color setup to
3875
     * keep it valid. This is because num_components and depth include tags. */
3876
970k
    copy_tag_setup(dev, target);
3877
970k
    COPY_PARAM(interpolate_control);
3878
970k
    COPY_PARAM(non_strict_bounds);
3879
970k
    memcpy(&(dev->space_params), &(target->space_params), sizeof(gdev_space_params));
3880
3881
970k
    if (dev->icc_struct == NULL) {
3882
970k
        dev->icc_struct = gsicc_new_device_profile_array(dev);
3883
970k
        if (dev->icc_struct == NULL)
3884
0
            return_error(gs_error_VMerror);
3885
970k
        profile_dev14 = dev->icc_struct;
3886
970k
        dev_proc((gx_device *) target, get_profile)((gx_device *) target,
3887
970k
                                          &(profile_targ));
3888
3889
4.85M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
3890
3.88M
            if (profile_targ->device_profile[k] != NULL) {
3891
970k
                gsicc_adjust_profile_rc(profile_targ->device_profile[k], 1, "gs_pdf14_device_copy_params");
3892
970k
            }
3893
3.88M
            if (profile_dev14->device_profile[k] != NULL) {
3894
0
                gsicc_adjust_profile_rc(profile_dev14->device_profile[k], -1, "gs_pdf14_device_copy_params");
3895
0
            }
3896
3.88M
            profile_dev14->device_profile[k] = profile_targ->device_profile[k];
3897
3.88M
            profile_dev14->rendercond[k] = profile_targ->rendercond[k];
3898
3.88M
        }
3899
3900
970k
        dev->icc_struct->devicegraytok = profile_targ->devicegraytok;
3901
970k
        dev->icc_struct->graydetection = profile_targ->graydetection;
3902
970k
        dev->icc_struct->pageneutralcolor = profile_targ->pageneutralcolor;
3903
970k
        dev->icc_struct->supports_devn = profile_targ->supports_devn;
3904
970k
        dev->icc_struct->usefastcolor = profile_targ->usefastcolor;
3905
970k
        dev->icc_struct->blacktext = profile_targ->blacktext;
3906
970k
        dev->icc_struct->blackvector = profile_targ->blackvector;
3907
970k
        dev->icc_struct->blackthresholdL = profile_targ->blackthresholdL;
3908
970k
        dev->icc_struct->blackthresholdC = profile_targ->blackthresholdC;
3909
3910
970k
        switch (pdev->blend_cs_state) {
3911
970k
            case PDF14_BLEND_CS_UNSPECIFIED:
3912
970k
            case PDF14_BLEND_CS_TARGET_CIELAB:
3913
                /* PDF14_BLEND_CS_TARGET_CIELAB handled
3914
                   during the device push, when we have
3915
                   access to the pgs */
3916
970k
                break;
3917
0
            case PDF14_BLEND_CS_OUTPUTINTENT:
3918
0
                blend_profile = profile_targ->oi_profile;
3919
0
                break;
3920
0
            case PDF14_BLEND_CS_SPECIFIED:
3921
0
                blend_profile = profile_targ->blend_profile;
3922
0
                break;
3923
0
            default:
3924
0
                break;
3925
970k
        }
3926
3927
970k
        if (blend_profile != NULL) {
3928
            /* Set the device profile to the blend profile. Note only default profile is set */
3929
0
            gsicc_adjust_profile_rc(blend_profile, 1, "gs_pdf14_device_copy_params");
3930
0
            gsicc_adjust_profile_rc(profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "gs_pdf14_device_copy_params");
3931
0
            profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE] = blend_profile;
3932
0
        }
3933
3934
970k
        profile_dev14->overprint_control = profile_targ->overprint_control;
3935
970k
    }
3936
970k
#undef COPY_ARRAY_PARAM
3937
970k
#undef COPY_PARAM
3938
970k
    return 0;
3939
970k
}
3940
3941
/*
3942
 * This is a forwarding version of the put_params device proc.  It is only
3943
 * used when the PDF 1.4 compositor devices are closed.  The routine will
3944
 * check if the target device has closed and, if so, close itself.  The routine
3945
 * also sync the device parameters.
3946
 */
3947
static  int
3948
pdf14_forward_put_params(gx_device * dev, gs_param_list * plist)
3949
0
{
3950
0
    pdf14_device * pdev = (pdf14_device *)dev;
3951
0
    gx_device * tdev = pdev->target;
3952
0
    bool was_open = tdev->is_open;
3953
0
    int code = 0;
3954
3955
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
3956
0
        gx_device_decache_colors(dev);
3957
0
        if (!tdev->is_open) {
3958
0
            code = gs_closedevice(dev);
3959
0
            if (code == 0)
3960
0
                code = was_open ? 1 : 0;   /* target device closed */
3961
0
        }
3962
0
        gx_device_copy_params(dev, tdev);
3963
0
    }
3964
0
    return code;
3965
0
}
3966
3967
/* Function prototypes */
3968
int put_param_pdf14_spot_names(gx_device * pdev,
3969
                gs_separations * pseparations, gs_param_list * plist);
3970
95.2k
#define PDF14NumSpotColorsParamName "PDF14NumSpotColors"
3971
3972
/*
3973
 * The put_params method for the PDF 1.4 device will check if the
3974
 * target device has closed and, if so, close itself.  Note:  This routine is
3975
 * currently being used by both the pdf14_clist_device and the pdf_device.
3976
 * Please make sure that any changes are either applicable to both devices
3977
 * or clone the routine for each device.
3978
 */
3979
static  int
3980
pdf14_put_params(gx_device * dev, gs_param_list * plist)
3981
0
{
3982
0
    pdf14_device * pdev = (pdf14_device *)dev;
3983
0
    gx_device * tdev = pdev->target;
3984
0
    bool was_open = tdev->is_open;
3985
0
    int code = 0, code2 = 0;
3986
3987
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
3988
0
        gx_device_decache_colors(dev);
3989
0
        if (!tdev->is_open) {
3990
0
            code = gs_closedevice(dev);
3991
0
            if (code == 0)
3992
0
                code = was_open ? 1 : 0;   /* target device closed */
3993
0
        }
3994
0
        code2 = gs_pdf14_device_copy_params(dev, tdev);
3995
0
        if (code2 < 0)
3996
0
            code = code2;
3997
0
    }
3998
0
    return code;
3999
0
}
4000
4001
/*
4002
 * Copy marking related parameters into the PDF 1.4 device structure for use
4003
 * by pdf14_fill_rectangle.
4004
 */
4005
static  void
4006
pdf14_set_marking_params(gx_device *dev, const gs_gstate *pgs)
4007
28.6M
{
4008
28.6M
    pdf14_device * pdev = (pdf14_device *)dev;
4009
4010
28.6M
    if (pgs->alphaisshape) {
4011
349k
        pdev->opacity = 1.0;
4012
349k
        if (pgs->is_fill_color) {
4013
339k
            pdev->shape = pgs->fillconstantalpha;
4014
339k
        } else {
4015
9.95k
            pdev->shape = pgs->strokeconstantalpha;
4016
9.95k
        }
4017
28.3M
    } else {
4018
28.3M
        pdev->shape = 1.0;
4019
28.3M
        if (pgs->is_fill_color) {
4020
10.2M
            pdev->opacity = pgs->fillconstantalpha;
4021
18.1M
        } else {
4022
18.1M
            pdev->opacity = pgs->strokeconstantalpha;
4023
18.1M
        }
4024
28.3M
    }
4025
28.6M
    pdev->alpha = pdev->opacity * pdev->shape;
4026
28.6M
    pdev->blend_mode = pgs->blend_mode;
4027
28.6M
    if (pdev->icc_struct->overprint_control != gs_overprint_control_disable) {
4028
28.6M
        pdev->overprint = pgs->overprint;
4029
28.6M
        pdev->stroke_overprint = pgs->stroke_overprint;
4030
28.6M
    } else {
4031
0
        pdev->overprint = false;
4032
0
        pdev->stroke_overprint = false;
4033
0
    }
4034
4035
28.6M
    pdev->fillconstantalpha = pgs->fillconstantalpha;
4036
28.6M
    pdev->strokeconstantalpha = pgs->strokeconstantalpha;
4037
4038
28.6M
    if (pgs->is_fill_color)
4039
10.5M
        pdev->op_state = PDF14_OP_STATE_FILL;
4040
18.1M
    else
4041
18.1M
        pdev->op_state = PDF14_OP_STATE_STROKE;
4042
4043
28.6M
    if_debug6m('v', dev->memory,
4044
28.6M
               "[v]set_marking_params, opacity = %g, shape = %g, bm = %d, op = %d, eop = %d seop = %d\n",
4045
28.6M
               pdev->opacity, pdev->shape, pgs->blend_mode, pgs->overprint, pdev->effective_overprint_mode,
4046
28.6M
               pdev->stroke_effective_op_mode);
4047
28.6M
}
4048
4049
static  void
4050
update_lop_for_pdf14(gs_gstate *pgs, const gx_drawing_color *pdcolor)
4051
21.2M
{
4052
21.2M
    bool hastrans = false;
4053
4054
    /* We'd really rather not have to set the pdf14 bit in the lop, as this
4055
     * makes other operations much slower. We have no option however, if the
4056
     * current colour involves transparency, or if it's anything other than
4057
     * a completely solid (or transparent) operation in the normal blend mode.
4058
     */
4059
21.2M
    if (pdcolor != NULL)
4060
21.2M
    {
4061
21.2M
        if (gx_dc_is_pattern1_color(pdcolor) &&
4062
444k
            gx_pattern1_get_transptr(pdcolor) != NULL) {
4063
4.36k
            hastrans = true;
4064
21.2M
        } else if (gx_dc_is_pattern2_color(pdcolor)) {
4065
            /* FIXME: Here we assume that ALL type 2 patterns are
4066
             * transparent - this test could be better. */
4067
8.94k
            hastrans = true;
4068
8.94k
        }
4069
21.2M
    }
4070
    /* The only idempotent blend modes are Normal, Darken and Lighten.
4071
       This appears to be the only place where this test is done so
4072
       not adding a is_idempotent method */
4073
21.2M
    if ((pgs->blend_mode != BLEND_MODE_Normal &&
4074
119k
        pgs->blend_mode != BLEND_MODE_Darken &&
4075
114k
        pgs->blend_mode != BLEND_MODE_Lighten) ||
4076
21.1M
        (pgs->fillconstantalpha != 1.0) ||
4077
20.9M
        (pgs->strokeconstantalpha != 1.0) ||
4078
20.9M
        (hastrans))
4079
335k
    {
4080
        /*
4081
         * The blend operations are not idempotent.  Force non-idempotent
4082
         * filling and stroking operations.
4083
         */
4084
335k
        pgs->log_op |= lop_pdf14;
4085
335k
    }
4086
21.2M
}
4087
4088
static int
4089
push_shfill_group(pdf14_clist_device *pdev,
4090
                  gs_gstate *pgs,
4091
                  gs_fixed_rect *box)
4092
327
{
4093
327
    gs_transparency_group_params_t params = { 0 };
4094
327
    int code;
4095
327
    gs_rect cb;
4096
327
    gs_gstate fudged_pgs = *pgs;
4097
4098
327
    params.shade_group = true;
4099
4100
    /* gs_begin_transparency_group takes a bbox that it then
4101
     * transforms by ctm. Our bbox has already been transformed,
4102
     * so clear out the ctm. */
4103
327
    fudged_pgs.ctm.xx = 1.0;
4104
327
    fudged_pgs.ctm.xy = 0;
4105
327
    fudged_pgs.ctm.yx = 0;
4106
327
    fudged_pgs.ctm.yy = 1.0;
4107
327
    fudged_pgs.ctm.tx = 0;
4108
327
    fudged_pgs.ctm.ty = 0;
4109
327
    cb.p.x = fixed2int_pixround(box->p.x);
4110
327
    cb.p.y = fixed2int_pixround(box->p.y);
4111
327
    cb.q.x = fixed2int_pixround(box->q.x);
4112
327
    cb.q.y = fixed2int_pixround(box->q.y);
4113
4114
327
    params.Isolated = false;
4115
327
    params.Knockout = true;
4116
327
    params.page_group = false;
4117
327
    params.group_opacity = fudged_pgs.fillconstantalpha;
4118
327
    params.group_shape = 1.0;
4119
327
    code = gs_begin_transparency_group(&fudged_pgs, &params, &cb, PDF14_BEGIN_TRANS_GROUP);
4120
4121
    /* We have the group handle the blendmode and the opacity,
4122
     * and continue with the existing graphics state reset
4123
     * to normal, opaque operation. We could do it the other
4124
     * way around, but this way means that if we push a knockout
4125
     * group for a stroke, and then the code calls back into
4126
     * the fill operation as part of doing the stroking, we don't
4127
     * push another one. */
4128
327
    gs_setblendmode(pgs, BLEND_MODE_Normal);
4129
327
    gs_setfillconstantalpha(pgs, 1.0);
4130
327
    gs_setstrokeconstantalpha(pgs, 1.0);
4131
327
    if (pdev) {
4132
327
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
4133
327
        if (code < 0)
4134
0
            return code;
4135
327
    }
4136
4137
327
    return code;
4138
327
}
4139
4140
static int
4141
pop_shfill_group(gs_gstate *pgs)
4142
325
{
4143
325
     return gs_end_transparency_group(pgs);
4144
325
}
4145
4146
static int
4147
pdf14_fill_path(gx_device *dev, const gs_gstate *pgs,
4148
                           gx_path *ppath, const gx_fill_params *params,
4149
                           const gx_drawing_color *pdcolor,
4150
                           const gx_clip_path *pcpath)
4151
15.8M
{
4152
15.8M
    gs_gstate new_pgs = *pgs;
4153
15.8M
    int code = 0;
4154
15.8M
    gs_pattern2_instance_t *pinst = NULL;
4155
15.8M
    int push_group = 0;
4156
4157
15.8M
    code = pdf14_initialize_ctx(dev, pgs);
4158
15.8M
    if (code < 0)
4159
0
        return code;
4160
4161
15.8M
    if (pdcolor == NULL)
4162
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4163
15.8M
    ((pdf14_device *)dev)->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_STROKE;
4164
15.8M
    if (gx_dc_is_pattern1_color(pdcolor)){
4165
493k
        if( gx_pattern1_get_transptr(pdcolor) != NULL ||
4166
477k
            gx_pattern1_clist_has_trans(pdcolor) ){
4167
            /* In this case, we need to push a transparency group
4168
               and tile the pattern color, which is stored in
4169
               a pdf14 device buffer in the ctile object memember
4170
               variable ttrans */
4171
#if RAW_DUMP
4172
            /* Since we do not get a put_image to view what
4173
               we have do it now */
4174
            if (gx_pattern1_get_transptr(pdcolor) != NULL) {
4175
                const pdf14_device * ppatdev14 = (const pdf14_device *)
4176
                                pdcolor->colors.pattern.p_tile->ttrans->pdev14;
4177
                if (ppatdev14 != NULL) {  /* can occur during clist reading */
4178
                    byte *buf_ptr = ppatdev14->ctx->stack->data  +
4179
                        ppatdev14->ctx->stack->rect.p.y *
4180
                        ppatdev14->ctx->stack->rowstride +
4181
                        ppatdev14->ctx->stack->rect.p.x;
4182
                    dump_raw_buffer(ppatdev14->ctx->memory,
4183
                                    (ppatdev14->ctx->stack->rect.q.y -
4184
                                     ppatdev14->ctx->stack->rect.p.y),
4185
                                    (ppatdev14->ctx->stack->rect.q.x -
4186
                                     ppatdev14->ctx->stack->rect.p.x),
4187
                                    ppatdev14->ctx->stack->n_planes,
4188
                                    ppatdev14->ctx->stack->planestride,
4189
                                    ppatdev14->ctx->stack->rowstride,
4190
                                    "Pattern_Fill", buf_ptr,
4191
                                    ppatdev14->ctx->stack->deep);
4192
                    global_index++;
4193
                } else {
4194
                     gx_pattern_trans_t *patt_trans =
4195
                                        pdcolor->colors.pattern.p_tile->ttrans;
4196
                     dump_raw_buffer(patt_trans->mem,
4197
                                     patt_trans->rect.q.y-patt_trans->rect.p.y,
4198
                                     patt_trans->rect.q.x-patt_trans->rect.p.x,
4199
                                     patt_trans->n_chan,
4200
                                     patt_trans->planestride, patt_trans->rowstride,
4201
                                     "Pattern_Fill_clist",
4202
                                     patt_trans->transbytes +
4203
                                         patt_trans->rect.p.y * patt_trans->rowstride +
4204
                                         (patt_trans->rect.p.x<<patt_trans->deep),
4205
                                     patt_trans->deep);
4206
                    global_index++;
4207
                }
4208
            }
4209
#endif
4210
57.1k
            pdf14_set_marking_params(dev, &new_pgs);
4211
57.1k
            code = pdf14_tile_pattern_fill(dev, &new_pgs, ppath,
4212
57.1k
                params, pdcolor, pcpath);
4213
57.1k
            new_pgs.trans_device = NULL;
4214
57.1k
            new_pgs.has_transparency = false;
4215
57.1k
            return code;
4216
57.1k
        }
4217
493k
    }
4218
15.7M
    if (gx_dc_is_pattern2_color(pdcolor) ||
4219
15.7M
        pdcolor->type == &gx_dc_devn_masked) {
4220
        /* Non-idempotent blends require a transparency
4221
         * group to be pushed because shadings might
4222
         * paint several pixels twice. */
4223
12
        push_group = pgs->fillconstantalpha != 1.0 ||
4224
12
               !blend_is_idempotent(gs_currentblendmode(pgs));
4225
12
        pinst =
4226
12
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
4227
12
        pinst->saved->has_transparency = true;
4228
        /* The transparency color space operations are driven
4229
           by the pdf14 clist writer device.  */
4230
12
        pinst->saved->trans_device = dev;
4231
12
    }
4232
15.7M
    if (push_group) {
4233
0
        gs_fixed_rect box;
4234
0
        if (pcpath)
4235
0
            gx_cpath_outer_box(pcpath, &box);
4236
0
        else
4237
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4238
0
        if (ppath) {
4239
0
            gs_fixed_rect path_box;
4240
4241
0
            gx_path_bbox(ppath, &path_box);
4242
0
            if (box.p.x < path_box.p.x)
4243
0
                box.p.x = path_box.p.x;
4244
0
            if (box.p.y < path_box.p.y)
4245
0
                box.p.y = path_box.p.y;
4246
0
            if (box.q.x > path_box.q.x)
4247
0
                box.q.x = path_box.q.x;
4248
0
            if (box.q.y > path_box.q.y)
4249
0
                box.q.y = path_box.q.y;
4250
0
        }
4251
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4252
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4253
0
    } else
4254
15.7M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4255
15.7M
    pdf14_set_marking_params(dev, &new_pgs);
4256
15.7M
    if (code >= 0) {
4257
15.7M
        new_pgs.trans_device = dev;
4258
15.7M
        new_pgs.has_transparency = true;
4259
        /* ppath can permissibly be NULL here, if we want to have a
4260
         * shading or a pattern fill the clipping path. This upsets
4261
         * coverity, which is not smart enough to realise that the
4262
         * validity of a NULL ppath depends on the type of pdcolor.
4263
         * We'll mark it as a false positive. */
4264
15.7M
        code = gx_default_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4265
15.7M
        new_pgs.trans_device = NULL;
4266
15.7M
        new_pgs.has_transparency = false;
4267
15.7M
    }
4268
15.7M
    if (code >= 0 && push_group) {
4269
0
        code = pop_shfill_group(&new_pgs);
4270
0
        pdf14_set_marking_params(dev, pgs);
4271
0
    }
4272
15.7M
    if (pinst != NULL){
4273
12
        pinst->saved->trans_device = NULL;
4274
12
    }
4275
15.7M
    return code;
4276
15.8M
}
4277
4278
static  int
4279
pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs,
4280
                             gx_path *ppath, const gx_stroke_params *params,
4281
                             const gx_drawing_color *pdcolor,
4282
                             const gx_clip_path *pcpath)
4283
4.06M
{
4284
4.06M
    gs_gstate new_pgs = *pgs;
4285
4.06M
    int push_group = 0;
4286
4.06M
    int code = 0;
4287
4288
4.06M
    if (pdcolor == NULL)
4289
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4290
4291
4.06M
    code = pdf14_initialize_ctx(dev, pgs);
4292
4.06M
    if (code < 0)
4293
0
        return code;
4294
4295
4.06M
    if (gx_dc_is_pattern2_color(pdcolor)) {
4296
        /* Non-idempotent blends require a transparency
4297
         * group to be pushed because shadings might
4298
         * paint several pixels twice. */
4299
0
        push_group = pgs->strokeconstantalpha != 1.0 ||
4300
0
               !blend_is_idempotent(gs_currentblendmode(pgs));
4301
0
    }
4302
4.06M
    if (push_group) {
4303
0
        gs_fixed_rect box;
4304
0
        if (pcpath)
4305
0
            gx_cpath_outer_box(pcpath, &box);
4306
0
        else
4307
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4308
4309
        /* For fill_path, we accept ppath == NULL to mean
4310
         * fill the entire clipping region. That makes no
4311
         * sense for stroke_path, hence ppath is always non
4312
         * NULL here. */
4313
0
        {
4314
0
            gs_fixed_rect path_box;
4315
0
            gs_fixed_point expansion;
4316
4317
0
            gx_path_bbox(ppath, &path_box);
4318
            /* Expand the path bounding box by the scaled line width. */
4319
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
4320
                /* The expansion is so large it caused a limitcheck. */
4321
0
                path_box.p.x = path_box.p.y = min_fixed;
4322
0
                path_box.q.x = path_box.q.y = max_fixed;
4323
0
            } else {
4324
0
                expansion.x += pgs->fill_adjust.x;
4325
0
                expansion.y += pgs->fill_adjust.y;
4326
                /*
4327
                 * It's theoretically possible for the following computations to
4328
                 * overflow, so we need to check for this.
4329
                 */
4330
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
4331
0
                                path_box.p.x - expansion.x);
4332
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
4333
0
                                path_box.p.y - expansion.y);
4334
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
4335
0
                                path_box.q.x + expansion.x);
4336
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
4337
0
                                path_box.q.y + expansion.y);
4338
0
            }
4339
0
            if (box.p.x < path_box.p.x)
4340
0
                box.p.x = path_box.p.x;
4341
0
            if (box.p.y < path_box.p.y)
4342
0
                box.p.y = path_box.p.y;
4343
0
            if (box.q.x > path_box.q.x)
4344
0
                box.q.x = path_box.q.x;
4345
0
            if (box.q.y > path_box.q.y)
4346
0
                box.q.y = path_box.q.y;
4347
0
        }
4348
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4349
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
4350
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4351
0
    } else
4352
4.06M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4353
4.06M
    pdf14_set_marking_params(dev, &new_pgs);
4354
4.06M
    if (code >= 0) {
4355
4.06M
        PDF14_OP_FS_STATE save_op_state = ((pdf14_device *)dev)->op_state;
4356
4357
4.06M
        ((pdf14_device*)dev)->op_state = PDF14_OP_STATE_STROKE;
4358
4.06M
        code = gx_default_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4359
4.06M
        ((pdf14_device*)dev)->op_state = save_op_state;
4360
4.06M
    }
4361
4.06M
    if (code >= 0 && push_group) {
4362
0
        code = pop_shfill_group(&new_pgs);
4363
0
        pdf14_set_marking_params(dev, pgs);
4364
0
    }
4365
4366
4.06M
    return code;
4367
4.06M
}
4368
4369
/* Pull out steps of transparency updates for fill/stroke
4370
   so that they can be invoked elsewhere (e.g.
4371
   when the abuf device is handling the stroke/fill */
4372
4373
/* Set-up prior to fill operation in fill-stroke */
4374
static int
4375
pdf14_fill_stroke_prefill(gx_device* dev, gs_gstate* pgs, gx_path* ppath,
4376
    const gx_clip_path* pcpath, float fill_alpha, float stroke_alpha,
4377
    gs_blend_mode_t blend_mode, bool* op_ca_eq_CA, bool* path_empty, gs_log2_scale_point path_log2scale)
4378
21.0k
{
4379
21.0k
    int code = 0;
4380
21.0k
    gs_transparency_group_params_t params = { 0 };
4381
21.0k
    gs_fixed_rect clip_bbox;
4382
21.0k
    gs_rect bbox, group_stroke_box;
4383
21.0k
    gs_fixed_rect path_bbox;
4384
21.0k
    int expansion_code;
4385
21.0k
    gs_fixed_point expansion;
4386
21.0k
    pdf14_device* p14dev = (pdf14_device*)dev;
4387
4388
21.0k
    *path_empty = false;
4389
4390
21.0k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
4391
21.0k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
4392
54
    {
4393
54
        *op_ca_eq_CA = true;
4394
54
        *path_empty = true;
4395
54
        return 0;
4396
54
    }
4397
4398
    /* The clip box returned here is scaled up by path_log2scale, so we need
4399
     * to scale down by this later. */
4400
21.0k
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
4401
21.0k
    if (code < 0 && code != gs_error_unknownerror)
4402
0
        return code;
4403
4404
21.0k
    if (code == gs_error_unknownerror) {
4405
        /* didn't get clip box from gx_curr_fixed_bbox */
4406
        /* This is NOT scaled by path_log2scale, so allow for the fact we'll be
4407
         * scaling down by this in a moment. */
4408
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
4409
0
        clip_bbox.q.x = int2fixed(dev->width) << path_log2scale.x;
4410
0
        clip_bbox.q.y = int2fixed(dev->height) << path_log2scale.y;
4411
0
    }
4412
    /* pcpath->outer_box is scaled by path_log2scale too. */
4413
21.0k
    if (pcpath)
4414
21.0k
        rect_intersect(clip_bbox, pcpath->outer_box);
4415
4416
    /* expand the ppath using stroke expansion rule, then intersect it */
4417
21.0k
    code = gx_path_bbox(ppath, &path_bbox);
4418
4419
    /* If we are coming from the abuf device, the path has been scaled
4420
       by a factor (see alpha_buffer_init).  Undo the scaling here so
4421
       on the path_bbox so that we get the proper bounding box for our group. */
4422
21.0k
    if (path_log2scale.x != 0 || path_log2scale.y != 0) {
4423
0
        path_bbox.p.x = path_bbox.p.x >> path_log2scale.x;
4424
0
        path_bbox.q.x = path_bbox.q.x >> path_log2scale.x;
4425
0
        path_bbox.p.y = path_bbox.p.y >> path_log2scale.y;
4426
0
        path_bbox.q.y = path_bbox.q.y >> path_log2scale.y;
4427
0
        clip_bbox.p.x = clip_bbox.p.x >> path_log2scale.x;
4428
0
        clip_bbox.q.x = clip_bbox.q.x >> path_log2scale.x;
4429
0
        clip_bbox.p.y = clip_bbox.p.y >> path_log2scale.y;
4430
0
        clip_bbox.q.y = clip_bbox.q.y >> path_log2scale.y;
4431
0
    }
4432
4433
21.0k
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0) {
4434
1.93k
        *path_empty = true;
4435
1.93k
        return 0; /* ignore empty path -- could try to send back a positive code for this but
4436
                     there are simply too many return cases that I can't account for. */
4437
1.93k
    }
4438
19.0k
    if (code < 0)
4439
0
        return code;
4440
4441
19.0k
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
4442
19.0k
    if (expansion_code >= 0) {
4443
19.0k
        path_bbox.p.x -= expansion.x;
4444
19.0k
        path_bbox.p.y -= expansion.y;
4445
19.0k
        path_bbox.q.x += expansion.x;
4446
19.0k
        path_bbox.q.y += expansion.y;
4447
19.0k
    }
4448
19.0k
    rect_intersect(path_bbox, clip_bbox);
4449
19.0k
    bbox.p.x = fixed2float(path_bbox.p.x);
4450
19.0k
    bbox.p.y = fixed2float(path_bbox.p.y);
4451
19.0k
    bbox.q.x = fixed2float(path_bbox.q.x);
4452
19.0k
    bbox.q.y = fixed2float(path_bbox.q.y);
4453
4454
19.0k
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
4455
19.0k
    if (code < 0)
4456
2
        return code;
4457
4458
19.0k
    if (p14dev->overprint != pgs->overprint || p14dev->stroke_overprint != pgs->stroke_overprint) {
4459
0
        p14dev->overprint = pgs->overprint;
4460
0
        p14dev->stroke_overprint = pgs->stroke_overprint;
4461
0
    }
4462
4463
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
4464
19.0k
    if (fill_alpha == stroke_alpha &&
4465
4.38k
        p14dev->overprint && p14dev->stroke_overprint &&
4466
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
4467
4468
        /* Push a non-isolated non-knockout group with alpha = 1.0 and
4469
           compatible overprint mode.  Group will be composited with
4470
           original alpha and blend mode */
4471
0
        *op_ca_eq_CA = true;
4472
0
        params.Isolated = false;
4473
0
        params.group_color_type = UNKNOWN;
4474
0
        params.Knockout = false;
4475
0
        params.page_group = false;
4476
0
        params.group_opacity = 1.0;
4477
0
        params.group_shape = fill_alpha;
4478
4479
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
4480
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4481
0
        if (code < 0)
4482
0
            return code;
4483
4484
        /* Change fill alpha to 1.0 and blend mode to compatible overprint for actual drawing */
4485
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
4486
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4487
4488
19.0k
    } else {
4489
        /* Push a non-isolated knockout group. Do not change the alpha or
4490
            blend modes. Note: we need to draw those that have alpha = 0 */
4491
19.0k
        *op_ca_eq_CA = false;
4492
19.0k
        params.Isolated = false;
4493
19.0k
        params.group_color_type = UNKNOWN;
4494
19.0k
        params.Knockout = true;
4495
19.0k
        params.page_group = false;
4496
19.0k
        params.group_shape = 1.0;
4497
19.0k
        params.group_opacity = 1.0;
4498
4499
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
4500
19.0k
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
4501
19.0k
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4502
19.0k
        if (code < 0)
4503
0
            return code;
4504
4505
        /* restore blend mode for actual drawing in the group */
4506
19.0k
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4507
4508
        /* If we are in an overprint situation, set the blend mode to compatible
4509
            overprint */
4510
19.0k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4511
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4512
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4513
19.0k
    }
4514
19.0k
    p14dev->op_state = PDF14_OP_STATE_FILL;
4515
19.0k
    return code;
4516
19.0k
}
4517
4518
/* Set-up prior to stroke operation in fill-stroke */
4519
static void
4520
pdf14_fill_stroke_prestroke(gx_device* dev, gs_gstate* pgs, float stroke_alpha,
4521
    gs_blend_mode_t blend_mode, bool op_ca_eq_CA)
4522
19.0k
{
4523
19.0k
    pdf14_device* p14dev = (pdf14_device*)dev;
4524
4525
19.0k
    if (op_ca_eq_CA) {
4526
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
4527
19.0k
    } else {
4528
19.0k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4529
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4530
0
            (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4531
4532
        /* Note that the stroke can end up doing fill methods */
4533
19.0k
        (void)gs_setfillconstantalpha(pgs, stroke_alpha);
4534
4535
19.0k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->stroke_overprint &&
4536
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4537
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4538
19.0k
    }
4539
19.0k
    p14dev->op_state = PDF14_OP_STATE_STROKE;
4540
19.0k
}
4541
4542
/* Cleanup after the stroke in fill-stroke  */
4543
static int
4544
pdf14_fill_stroke_poststroke(gx_device* dev, gs_gstate* pgs, float fill_alpha, bool op_ca_eq_CA)
4545
19.0k
{
4546
19.0k
    int code;
4547
4548
19.0k
    if (!op_ca_eq_CA) {
4549
        /* Bug 703324 we need to reset the fill constant alpha in the graphics
4550
          * state to the correct saved value. We also need to reset the 'opacity' member of the
4551
          * device, because some device methods (eg fill_masked_image) don't take a graphics
4552
          * state pointer as a parameter and so are unable to set the opacity value themselves.
4553
          * We therefore need to make sure it is set according to the current fill state.
4554
          */
4555
19.0k
        (void)gs_setfillconstantalpha(pgs, fill_alpha);
4556
19.0k
        code = gs_update_trans_marking_params(pgs);
4557
19.0k
        if (code < 0)
4558
0
            return code;
4559
19.0k
        pdf14_set_marking_params(dev, pgs);
4560
19.0k
    }
4561
4562
19.0k
    return 0;
4563
19.0k
}
4564
4565
/* cleanup in fill-stroke  */
4566
static int
4567
pdf14_fill_stroke_cleanup(gx_device* dev, gs_gstate* pgs, float fill_alpha, float stroke_alpha,
4568
    gs_blend_mode_t blend_mode, PDF14_OP_FS_STATE save_op_state)
4569
19.0k
{
4570
19.0k
    pdf14_device* p14dev = (pdf14_device*)dev;
4571
19.0k
    int code2;
4572
19.0k
    int code = 0;
4573
4574
    /* Restore the state */
4575
19.0k
    p14dev->op_state = save_op_state;
4576
19.0k
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4577
19.0k
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
4578
19.0k
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
4579
4580
19.0k
    code2 = gs_end_transparency_group(pgs);
4581
19.0k
    if (code2 < 0) {
4582
        /* At this point things have gone very wrong. We should just shut down */
4583
0
        code = gs_abort_pdf14trans_device(pgs);
4584
0
        return code2;
4585
0
    }
4586
19.0k
    return code;
4587
19.0k
}
4588
4589
static int
4590
pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
4591
    const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill,
4592
    const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke,
4593
    const gx_clip_path *pcpath)
4594
80.6k
{
4595
80.6k
    bool op_ca_eq_CA;
4596
80.6k
    bool path_empty;
4597
80.6k
    int code;
4598
80.6k
    float stroke_alpha = cpgs->strokeconstantalpha;
4599
80.6k
    float fill_alpha = cpgs->fillconstantalpha;
4600
80.6k
    gs_blend_mode_t blend_mode = cpgs->blend_mode;
4601
80.6k
    pdf14_device* p14dev = (pdf14_device*)dev;
4602
80.6k
    PDF14_OP_FS_STATE save_op_state = p14dev->op_state;
4603
80.6k
    gs_log2_scale_point path_log2scale;
4604
80.6k
    bool group_needed = true;
4605
80.6k
    gx_device* curr_pgs_dev = cpgs->device;
4606
4607
80.6k
    union {
4608
80.6k
        const gs_gstate* cpgs;
4609
80.6k
        gs_gstate* pgs;
4610
80.6k
    } const_breaker;
4611
80.6k
    gs_gstate* pgs;
4612
4613
    /* Break const just once, neatly */
4614
80.6k
    const_breaker.cpgs = cpgs;
4615
80.6k
    pgs = const_breaker.pgs;
4616
80.6k
    path_log2scale.x = 0;
4617
80.6k
    path_log2scale.y = 0;
4618
4619
80.6k
    code = pdf14_initialize_ctx(dev, pgs);
4620
80.6k
    if (code < 0)
4621
0
        return code;
4622
4623
    /* From looking at what AR is doing, it appears that if alpha is 1 and
4624
     * blend is normal we don't do a group push. Just do the stroke
4625
     * and the fill, even with overprint */
4626
80.6k
    if (stroke_alpha == 1 && fill_alpha == 1 && blend_mode == BLEND_MODE_Normal)
4627
59.5k
        group_needed = false;
4628
4629
80.6k
    if (group_needed) {
4630
21.0k
        pgs->device = dev; /* This is needed due to the gs_trans calls.  This method
4631
                              can be called on the clist writer side when dealing
4632
                              with the abuf/pdf14 interaction. Those calls have to
4633
                              go through the gs_trans API not the gx_trans or pdf14
4634
                              methods.  Perhaps these methods should have a different
4635
                              suffix, but they are static methods here in the pdf14
4636
                              file. */
4637
21.0k
        code = pdf14_fill_stroke_prefill(dev, pgs, ppath, pcpath, fill_alpha, stroke_alpha,
4638
21.0k
            blend_mode, &op_ca_eq_CA, &path_empty, path_log2scale);
4639
21.0k
        pgs->device = curr_pgs_dev;
4640
21.0k
        if (code < 0)
4641
2
            goto cleanup;
4642
21.0k
        if (path_empty)
4643
1.99k
            return 0;
4644
21.0k
    }
4645
4646
78.6k
    code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
4647
78.6k
    if (code < 0)
4648
0
        goto cleanup;
4649
4650
78.6k
    if (group_needed)
4651
19.0k
        pdf14_fill_stroke_prestroke(dev, pgs, stroke_alpha, blend_mode, op_ca_eq_CA);
4652
78.6k
    gs_swapcolors_quick(pgs);
4653
4654
4655
#if RAW_DUMP
4656
    /* Dump the current buffer to see what we have. */
4657
    dump_raw_buffer(p14dev->ctx->memory,
4658
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4659
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4660
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4661
        "BeforeStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4662
    global_index++;
4663
#endif
4664
4665
78.6k
    code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
4666
78.6k
    gs_swapcolors_quick(pgs);
4667
78.6k
    if (code < 0) {
4668
0
        goto cleanup;
4669
0
    }
4670
4671
#if RAW_DUMP
4672
    /* Dump the current buffer to see what we have. */
4673
    dump_raw_buffer(p14dev->ctx->memory,
4674
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4675
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4676
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4677
        "AfterStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4678
    global_index++;
4679
#endif
4680
78.6k
    if (group_needed)
4681
19.0k
        code = pdf14_fill_stroke_poststroke(dev, pgs, fill_alpha, op_ca_eq_CA);
4682
4683
78.6k
cleanup:
4684
78.6k
    if (group_needed) {
4685
19.0k
        int code1;
4686
19.0k
        pgs->device = dev; /* This is needed due to the gs_trans calls */
4687
19.0k
        code1 = pdf14_fill_stroke_cleanup(dev, pgs, fill_alpha, stroke_alpha, blend_mode,
4688
19.0k
            save_op_state);
4689
19.0k
        if (code1 < 0)
4690
0
            code = code1;
4691
19.0k
        pgs->device = curr_pgs_dev;
4692
19.0k
    }
4693
78.6k
    return code;
4694
78.6k
}
4695
4696
static int
4697
pdf14_copy_alpha(gx_device * dev, const byte * data, int data_x,
4698
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4699
                      gx_color_index color, int depth)
4700
0
{
4701
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4702
0
                                  color, NULL, depth, false);
4703
0
}
4704
4705
static int
4706
pdf14_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
4707
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4708
                      const gx_drawing_color *pdcolor, int depth)
4709
0
{
4710
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4711
0
                                  0, pdcolor, depth, true);
4712
0
}
4713
4714
static int
4715
do_pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
4716
                          int aa_raster, gx_bitmap_id id, int x, int y,
4717
                          int w, int h, gx_color_index color,
4718
                          const gx_device_color *pdc, int depth, bool devn)
4719
0
{
4720
0
    const byte *aa_row;
4721
0
    pdf14_device *pdev = (pdf14_device *)dev;
4722
0
    pdf14_buf *buf = pdev->ctx->stack;
4723
0
    int i, j, k;
4724
0
    byte *bline, *line, *dst_ptr, *back_ptr;
4725
0
    byte src[PDF14_MAX_PLANES];
4726
0
    byte dst[PDF14_MAX_PLANES] = { 0 };
4727
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4728
0
    bool additive = pdev->ctx->additive;
4729
0
    intptr_t rowstride = buf->rowstride;
4730
0
    intptr_t planestride = buf->planestride;
4731
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4732
0
    bool has_alpha_g = buf->has_alpha_g;
4733
0
    bool has_shape = buf->has_shape;
4734
0
    bool has_tags = buf->has_tags;
4735
0
    bool knockout = buf->knockout;
4736
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4737
0
        blend_mode == BLEND_MODE_Compatible ||
4738
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4739
0
    int num_chan = buf->n_chan;
4740
0
    int num_comp = num_chan - 1;
4741
0
    intptr_t shape_off = num_chan * planestride;
4742
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4743
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4744
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4745
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
4746
0
                                 pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4747
0
    gx_color_index comps;
4748
0
    byte shape = 0; /* Quiet compiler. */
4749
0
    byte src_alpha;
4750
0
    int alpha2_aa, alpha_aa, sx;
4751
0
    int alpha_aa_act;
4752
0
    int xoff;
4753
0
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
4754
0
    int shift = 8;
4755
0
    bool has_backdrop = buf->backdrop != NULL;
4756
4757
0
    if (buf->data == NULL)
4758
0
        return 0;
4759
0
    aa_row = data;
4760
0
    if (has_tags) {
4761
0
        if (devn)
4762
0
            curr_tag = pdc->tag;
4763
0
        else
4764
0
            curr_tag = (color >> (num_comp*8)) & 0xff;
4765
0
    }
4766
4767
0
    if (devn) {
4768
0
        if (additive) {
4769
0
            for (j = 0; j < num_comp; j++) {
4770
0
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
4771
0
            }
4772
0
        } else {
4773
0
            for (j = 0; j < num_comp; j++) {
4774
0
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
4775
0
            }
4776
0
        }
4777
0
    } else
4778
0
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
4779
0
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
4780
0
    if (has_shape)
4781
0
        shape = (byte)floor (255 * pdev->shape + 0.5);
4782
    /* Limit the area we write to the bounding rectangle for this buffer */
4783
0
    if (x < buf->rect.p.x) {
4784
0
        xoff = data_x + buf->rect.p.x - x;
4785
0
        w += x - buf->rect.p.x;
4786
0
        x = buf->rect.p.x;
4787
0
    } else {
4788
0
        xoff = data_x;
4789
0
    }
4790
0
    if (y < buf->rect.p.y) {
4791
0
      h += y - buf->rect.p.y;
4792
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4793
0
      y = buf->rect.p.y;
4794
0
    }
4795
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
4796
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
4797
    /* Update the dirty rectangle. */
4798
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
4799
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
4800
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
4801
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
4802
4803
    /* composite with backdrop only. */
4804
0
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4805
0
    if (knockout && has_backdrop)
4806
0
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4807
0
    else
4808
0
        bline = line;
4809
4810
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
4811
0
        back_ptr = bline;
4812
0
        dst_ptr = line;
4813
0
        sx = xoff;
4814
0
        for (i = 0; i < w; ++i, ++sx) {
4815
            /* Complement the components for subtractive color spaces */
4816
0
            if (additive) {
4817
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
4818
0
                    dst[k] = back_ptr[k * planestride];
4819
0
            } else { /* Complement the components for subtractive color spaces */
4820
0
                for (k = 0; k < num_comp; ++k)
4821
0
                    dst[k] = 255 - back_ptr[k * planestride];
4822
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
4823
0
            }
4824
            /* Get the aa alpha from the buffer */
4825
0
            switch(depth)
4826
0
            {
4827
0
            case 2:  /* map 0 - 3 to 0 - 255 */
4828
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
4829
0
                break;
4830
0
            case 4:
4831
0
                alpha2_aa = aa_row[sx >> 1];
4832
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
4833
0
                break;
4834
0
            case 8:
4835
0
                alpha_aa = aa_row[sx];
4836
0
                break;
4837
0
            default:
4838
0
                return_error(gs_error_rangecheck);
4839
0
            }
4840
0
            if (alpha_aa != 0) {  /* This does happen */
4841
0
                if (alpha_aa != 255) {
4842
                    /* We have an alpha value from aa */
4843
0
                    alpha_aa_act = alpha_aa;
4844
0
                    if (src_alpha != 255) {
4845
                        /* Need to combine it with the existing alpha */
4846
0
                        int tmp = src_alpha * alpha_aa_act + 0x80;
4847
0
                        alpha_aa_act = (tmp + (tmp >> 8)) >> 8;
4848
0
                    }
4849
                    /* Set our source alpha value appropriately */
4850
0
                    src[num_comp] = alpha_aa_act;
4851
0
                } else {
4852
                    /* We may have to reset this is it was changed as we
4853
                       moved across the row */
4854
0
                    src[num_comp] = src_alpha;
4855
0
                }
4856
0
                if (knockout) {
4857
0
                    if (buf->isolated) {
4858
0
                        art_pdf_knockoutisolated_group_8(dst, src, num_comp);
4859
0
                    } else {
4860
0
                        art_pdf_composite_knockout_8(dst, src, num_comp,
4861
0
                            blend_mode, pdev->blend_procs, pdev);
4862
0
                    }
4863
0
                } else {
4864
0
                    art_pdf_composite_pixel_alpha_8(dst, src, num_comp, blend_mode, num_comp,
4865
0
                                                    pdev->blend_procs, pdev);
4866
0
                }
4867
                /* Complement the results for subtractive color spaces */
4868
0
                if (additive) {
4869
0
                    for (k = 0; k < num_chan; ++k)
4870
0
                        dst_ptr[k * planestride] = dst[k];
4871
0
                } else {
4872
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
4873
0
                        for (k = 0, comps = drawn_comps; comps != 0;
4874
0
                                ++k, comps >>= 1) {
4875
0
                            if ((comps & 0x1) != 0) {
4876
0
                                dst_ptr[k * planestride] = 255 - dst[k];
4877
0
                            }
4878
0
                        }
4879
                        /* The alpha channel */
4880
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4881
0
                    } else {
4882
0
                        for (k = 0; k < num_comp; ++k)
4883
0
                            dst_ptr[k * planestride] = 255 - dst[k];
4884
                        /* The alpha channel */
4885
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4886
0
                    }
4887
0
                }
4888
0
                if (has_alpha_g) {
4889
0
                    int tmp = (255 - back_ptr[alpha_g_off]) * (255 - src[num_comp]) + 0x80;
4890
0
                    dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4891
0
                }
4892
0
                if (has_shape) {
4893
0
                    int tmp = (255 - back_ptr[shape_off]) * (255 - shape) + 0x80;
4894
0
                    dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4895
0
                }
4896
0
                if (has_tags) {
4897
                    /* If alpha is 100% then set to curr_tag, else or */
4898
                    /* other than Normal BM, we always OR */
4899
0
                    if (src[num_comp] == 255 && tag_blend) {
4900
0
                        dst_ptr[tag_off] = curr_tag;
4901
0
                    } else {
4902
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
4903
0
                    }
4904
0
                }
4905
0
            }
4906
0
            ++dst_ptr;
4907
0
            ++back_ptr;
4908
0
        }
4909
0
        line += rowstride;
4910
0
        bline += rowstride;
4911
0
    }
4912
0
    return 0;
4913
0
}
4914
4915
static int
4916
do_pdf14_copy_alpha_color_16(gx_device * dev, const byte * data, int data_x,
4917
                             int aa_raster, gx_bitmap_id id, int x, int y,
4918
                             int w, int h, gx_color_index color,
4919
                             const gx_device_color *pdc, int depth, bool devn)
4920
0
{
4921
0
    const byte *aa_row;
4922
0
    pdf14_device *pdev = (pdf14_device *)dev;
4923
0
    pdf14_buf *buf = pdev->ctx->stack;
4924
0
    int i, j, k;
4925
0
    byte *bline, *line;
4926
0
    uint16_t *dst_ptr, *back_ptr;
4927
0
    uint16_t src[PDF14_MAX_PLANES];
4928
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
4929
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4930
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4931
0
        blend_mode == BLEND_MODE_Compatible ||
4932
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4933
0
    bool additive = pdev->ctx->additive;
4934
0
    intptr_t rowstride = buf->rowstride;
4935
0
    int planestride = buf->planestride;
4936
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4937
0
    bool has_alpha_g = buf->has_alpha_g;
4938
0
    bool has_shape = buf->has_shape;
4939
0
    bool has_tags = buf->has_tags;
4940
0
    bool knockout = buf->knockout;
4941
0
    int num_chan = buf->n_chan;
4942
0
    int num_comp = num_chan - 1;
4943
0
    intptr_t shape_off = num_chan * planestride;
4944
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4945
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4946
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4947
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
4948
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4949
0
    gx_color_index comps;
4950
0
    uint16_t shape = 0; /* Quiet compiler. */
4951
0
    uint16_t src_alpha;
4952
0
    int alpha2_aa, alpha_aa, sx;
4953
0
    int alpha_aa_act;
4954
0
    int xoff;
4955
0
    bool has_backdrop = buf->backdrop != NULL;
4956
4957
0
    if (buf->data == NULL)
4958
0
        return 0;
4959
0
    aa_row = data;
4960
0
    if (has_tags) {
4961
0
        if (devn)
4962
0
            curr_tag = pdc->tag;
4963
0
        else
4964
0
            curr_tag = (color >> (num_comp*16)) & 0xff;
4965
0
    }
4966
4967
0
    if (devn) {
4968
0
        if (additive) {
4969
0
            for (j = 0; j < num_comp; j++) {
4970
0
                src[j] = pdc->colors.devn.values[j];
4971
0
            }
4972
0
        } else {
4973
0
            for (j = 0; j < num_comp; j++) {
4974
0
                src[j] = 65535 - pdc->colors.devn.values[j];
4975
0
            }
4976
0
        }
4977
0
    } else
4978
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
4979
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
4980
0
    if (has_shape)
4981
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
4982
    /* Limit the area we write to the bounding rectangle for this buffer */
4983
0
    if (x < buf->rect.p.x) {
4984
0
        xoff = data_x + buf->rect.p.x - x;
4985
0
        w += x - buf->rect.p.x;
4986
0
        x = buf->rect.p.x;
4987
0
    } else {
4988
0
        xoff = data_x;
4989
0
    }
4990
0
    if (y < buf->rect.p.y) {
4991
0
      h += y - buf->rect.p.y;
4992
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4993
0
      y = buf->rect.p.y;
4994
0
    }
4995
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
4996
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
4997
    /* Update the dirty rectangle. */
4998
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
4999
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
5000
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
5001
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
5002
5003
    /* composite with backdrop only. */
5004
0
    line = buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5005
0
    if (knockout && has_backdrop)
5006
0
        bline = buf->backdrop + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5007
0
    else
5008
0
        bline = line;
5009
5010
0
    planestride >>= 1;
5011
0
    rowstride   >>= 1;
5012
0
    alpha_g_off >>= 1;
5013
0
    shape_off   >>= 1;
5014
0
    tag_off     >>= 1;
5015
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
5016
0
        back_ptr = (uint16_t *)(void *)bline;
5017
0
        dst_ptr = (uint16_t *)(void *)line;
5018
0
        sx = xoff;
5019
0
        for (i = 0; i < w; ++i, ++sx) {
5020
            /* Complement the components for subtractive color spaces */
5021
0
            if (additive) {
5022
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
5023
0
                    dst[k] = back_ptr[k * planestride];
5024
0
            } else { /* Complement the components for subtractive color spaces */
5025
0
                for (k = 0; k < num_comp; ++k)
5026
0
                    dst[k] = 65535 - back_ptr[k * planestride];
5027
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
5028
0
            }
5029
            /* Get the aa alpha from the buffer */
5030
0
            switch(depth)
5031
0
            {
5032
0
            case 2:  /* map 0 - 3 to 0 - 255 */
5033
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
5034
0
                break;
5035
0
            case 4:
5036
0
                alpha2_aa = aa_row[sx >> 1];
5037
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
5038
0
                break;
5039
0
            case 8:
5040
0
                alpha_aa = aa_row[sx];
5041
0
                break;
5042
0
            default:
5043
0
                return_error(gs_error_rangecheck);
5044
0
            }
5045
0
            if (alpha_aa != 0) {  /* This does happen */
5046
0
                if (alpha_aa != 255) {
5047
                    /* We have an alpha value from aa */
5048
0
                    alpha_aa_act = alpha_aa * 0x101;
5049
0
                    if (src_alpha != 65535) {
5050
                        /* Need to combine it with the existing alpha */
5051
0
                        int tmp = src_alpha * alpha_aa_act + 0x8000;
5052
0
                        alpha_aa_act = (tmp + (tmp >> 16)) >> 16;
5053
0
                    }
5054
                    /* Set our source alpha value appropriately */
5055
0
                    src[num_comp] = alpha_aa_act;
5056
0
                } else {
5057
                    /* We may have to reset this is it was changed as we
5058
                       moved across the row */
5059
0
                    src[num_comp] = src_alpha;
5060
0
                }
5061
0
                if (knockout) {
5062
0
                    if (buf->isolated) {
5063
0
                        art_pdf_knockoutisolated_group_16(dst, src, num_comp);
5064
0
                    } else {
5065
0
                        art_pdf_composite_knockout_16(dst, src, num_comp,
5066
0
                            blend_mode, pdev->blend_procs, pdev);
5067
0
                    }
5068
0
                } else {
5069
0
                    art_pdf_composite_pixel_alpha_16(dst, src, num_comp, blend_mode, num_comp,
5070
0
                                                     pdev->blend_procs, pdev);
5071
0
                }
5072
                /* Complement the results for subtractive color spaces */
5073
0
                if (additive) {
5074
0
                    for (k = 0; k < num_chan; ++k)
5075
0
                        dst_ptr[k * planestride] = dst[k];
5076
0
                } else {
5077
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
5078
0
                        for (k = 0, comps = drawn_comps; comps != 0;
5079
0
                                ++k, comps >>= 1) {
5080
0
                            if ((comps & 0x1) != 0) {
5081
0
                                dst_ptr[k * planestride] = 65535 - dst[k];
5082
0
                            }
5083
0
                        }
5084
                        /* The alpha channel */
5085
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5086
0
                    } else {
5087
0
                        for (k = 0; k < num_comp; ++k)
5088
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
5089
                        /* The alpha channel */
5090
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5091
0
                    }
5092
0
                }
5093
0
                if (has_alpha_g) {
5094
0
                    int tmp = (65535 - back_ptr[alpha_g_off]) * (65535 - src[num_comp]) + 0x8000;
5095
0
                    dst_ptr[alpha_g_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5096
0
                }
5097
0
                if (has_shape) {
5098
0
                    int tmp = (65535 - back_ptr[shape_off]) * (65535 - shape) + 0x8000;
5099
0
                    dst_ptr[shape_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5100
0
                }
5101
0
                if (has_tags) {
5102
                    /* If alpha is 100% then set to curr_tag, else or */
5103
                    /* other than Normal BM, we always OR */
5104
0
                    if (src[num_comp] == 65535 && tag_blend) {
5105
0
                        dst_ptr[tag_off] = curr_tag;
5106
0
                    } else {
5107
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
5108
0
                    }
5109
0
                }
5110
0
            }
5111
0
            ++dst_ptr;
5112
0
            ++back_ptr;
5113
0
        }
5114
0
        line += rowstride;
5115
0
        bline += rowstride;
5116
0
    }
5117
0
    return 0;
5118
0
}
5119
5120
static int
5121
pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
5122
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
5123
                      gx_color_index color, const gx_device_color *pdc,
5124
                      int depth, bool devn)
5125
0
{
5126
0
    bool deep = device_is_deep(dev);
5127
0
    int code;
5128
5129
0
    code = pdf14_initialize_ctx(dev, NULL);
5130
0
    if (code < 0)
5131
0
        return code;
5132
5133
0
    if (deep)
5134
0
        return do_pdf14_copy_alpha_color_16(dev, data, data_x, aa_raster,
5135
0
                                            id, x, y, w, h,
5136
0
                                            color, pdc, depth, devn);
5137
0
    else
5138
0
        return do_pdf14_copy_alpha_color(dev, data, data_x, aa_raster,
5139
0
                                         id, x, y, w, h,
5140
0
                                         color, pdc, depth, devn);
5141
0
}
5142
5143
static  int
5144
pdf14_fill_mask(gx_device * orig_dev,
5145
                     const byte * data, int dx, int raster, gx_bitmap_id id,
5146
                     int x, int y, int w, int h,
5147
                     const gx_drawing_color * pdcolor, int depth,
5148
                     gs_logical_operation_t lop, const gx_clip_path * pcpath)
5149
11.1M
{
5150
11.1M
    gx_device *dev;
5151
11.1M
    pdf14_device *p14dev = (pdf14_device *)orig_dev;
5152
11.1M
    gx_device_clip cdev;
5153
11.1M
    gx_color_tile *ptile = NULL;
5154
11.1M
    int code = 0;
5155
11.1M
    gs_int_rect group_rect;
5156
11.1M
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5157
11.1M
    bool has_pattern_trans = false;
5158
11.1M
    cmm_dev_profile_t *dev_profile;
5159
5160
11.1M
    if (pdcolor == NULL)
5161
0
        return_error(gs_error_unknownerror);  /* color must be defined */
5162
5163
11.1M
    code = pdf14_initialize_ctx(orig_dev, NULL);
5164
11.1M
    if (code < 0)
5165
0
        return code;
5166
5167
    /* If we are doing a fill with a pattern that has a transparency then
5168
       go ahead and do a push and a pop of the transparency group */
5169
11.1M
    if (gx_dc_is_pattern1_color(pdcolor)) {
5170
0
        if( gx_pattern1_get_transptr(pdcolor) != NULL) {
5171
0
            ptile = pdcolor->colors.pattern.p_tile;
5172
            /* Set up things in the ptile so that we get the proper
5173
               blending etc */
5174
            /* Set the blending procs and the is_additive setting based
5175
               upon the number of channels */
5176
0
            if (ptile->ttrans->n_chan-1 < 4) {
5177
0
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5178
0
                ptile->ttrans->is_additive = true;
5179
0
            } else {
5180
0
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5181
0
                ptile->ttrans->is_additive = false;
5182
0
            }
5183
            /* Set the procs so that we use the proper filling method. */
5184
0
            gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5185
            /* Based upon if the tiles overlap pick the type of rect
5186
               fill that we will want to use */
5187
0
            if (ptile->has_overlap) {
5188
                /* This one does blending since there is tile overlap */
5189
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5190
0
            } else {
5191
                /* This one does no blending since there is no tile overlap */
5192
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5193
0
            }
5194
            /* Push the group */
5195
0
            group_rect.p.x = x;
5196
0
            group_rect.p.y = max(0,y);
5197
0
            group_rect.q.x = x + w;
5198
0
            group_rect.q.y = y + h;
5199
0
            if (!(w <= 0 || h <= 0)) {
5200
5201
0
                pdf14_group_color_t *group_color_info = pdf14_clone_group_color_info((gx_device *) p14dev, p14dev->ctx->stack->group_color_info);
5202
0
                if (group_color_info == NULL)
5203
0
                    return_error(gs_error_VMerror);
5204
5205
0
                code = pdf14_push_transparency_group(p14dev->ctx, &group_rect,
5206
0
                     1, 0, 65535, 65535, 65535, BLEND_MODE_Normal, 0, 0,
5207
0
                     ptile->ttrans->n_chan-1, false, false, NULL, NULL,
5208
0
                     group_color_info, NULL, NULL);
5209
0
                if (code < 0)
5210
0
                    return code;
5211
                /* Set up the output buffer information now that we have
5212
                   pushed the group */
5213
0
                fill_trans_buffer = new_pattern_trans_buff(p14dev->memory);
5214
0
                if (fill_trans_buffer == NULL)
5215
0
                    return_error(gs_error_VMerror);
5216
5217
0
                pdf14_get_buffer_information((gx_device *) p14dev,
5218
0
                                              fill_trans_buffer, NULL, false);
5219
                /* Store this in the appropriate place in pdcolor.  This
5220
                   is released later after the mask fill */
5221
0
                ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5222
0
                has_pattern_trans = true;
5223
0
            }
5224
0
        }
5225
0
    }
5226
11.1M
    if (pcpath != 0) {
5227
1.33M
        gx_make_clip_device_on_stack(&cdev, pcpath, orig_dev);
5228
1.33M
        dev = (gx_device *) & cdev;
5229
1.33M
    } else
5230
9.80M
        dev = orig_dev;
5231
11.1M
    if (depth > 1) {
5232
        /****** CAN'T DO ROP OR HALFTONE WITH ALPHA ******/
5233
0
        code = (*dev_proc(dev, copy_alpha))
5234
0
            (dev, data, dx, raster, id, x, y, w, h,
5235
0
             gx_dc_pure_color(pdcolor), depth);
5236
11.1M
    } else {
5237
11.1M
        code = pdcolor->type->fill_masked(pdcolor, data, dx, raster, id,
5238
11.1M
                                          x, y, w, h, dev, lop, false);
5239
11.1M
    }
5240
11.1M
    if (has_pattern_trans) {
5241
0
        bool has_tags = device_encodes_tags(dev);
5242
0
        if (code >= 0)
5243
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5244
0
        if (code >= 0)
5245
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx,
5246
0
                                                p14dev->blend_procs,
5247
0
                                                p14dev->color_info.num_components - has_tags,
5248
0
                                                dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5249
0
                                                orig_dev);
5250
0
        gs_free_object(p14dev->memory, ptile->ttrans->fill_trans_buffer,
5251
0
                       "pdf14_fill_mask");
5252
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5253
0
    }
5254
11.1M
    if (pcpath != 0)
5255
1.33M
        gx_destroy_clip_device_on_stack(&cdev);
5256
11.1M
    return code;
5257
11.1M
}
5258
5259
5260
5261
/* Used for filling rects when we are doing a fill with a pattern that
5262
   has transparency */
5263
static  int
5264
pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
5265
                        gx_path * ppath, const gx_fill_params * params,
5266
                        const gx_device_color * pdevc,
5267
                        const gx_clip_path * pcpath)
5268
57.1k
{
5269
57.1k
    int code;
5270
57.1k
    gs_gstate *pgs_noconst = (gs_gstate *)pgs; /* Break const. */
5271
57.1k
    gs_fixed_rect clip_box;
5272
57.1k
    gs_fixed_rect outer_box;
5273
57.1k
    pdf14_device * p14dev = (pdf14_device *)pdev;
5274
57.1k
    gs_int_rect rect;
5275
57.1k
    gx_clip_rect *curr_clip_rect;
5276
57.1k
    gx_color_tile *ptile = NULL;
5277
57.1k
    int k;
5278
57.1k
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5279
57.1k
    gs_int_point phase;  /* Needed during clist rendering for band offset */
5280
57.1k
    int n_chan_tile;
5281
57.1k
    gx_clip_path cpath_intersection;
5282
57.1k
    gx_path path_ttrans;
5283
57.1k
    pdf14_group_color_t *group_color_info;
5284
57.1k
    bool has_tags = device_encodes_tags(pdev);
5285
5286
57.1k
    if (ppath == NULL)
5287
0
        return_error(gs_error_unknownerror);  /* should not happen */
5288
57.1k
    if (pcpath != NULL) {
5289
54.2k
        code = gx_cpath_init_local_shared_nested(&cpath_intersection, pcpath, ppath->memory, 1);
5290
54.2k
    } else {
5291
2.95k
        (*dev_proc(pdev, get_clipping_box)) (pdev, &clip_box);
5292
2.95k
        gx_cpath_init_local(&cpath_intersection, ppath->memory);
5293
2.95k
        code = gx_cpath_from_rectangle(&cpath_intersection, &clip_box);
5294
2.95k
    }
5295
57.1k
    if (code < 0)
5296
0
        return code;
5297
57.1k
    code = gx_cpath_intersect_with_params(&cpath_intersection, ppath,
5298
57.1k
                                          params->rule, pgs_noconst, params);
5299
57.1k
    if (code < 0)
5300
0
        return code;
5301
    /* One (common) case worth optimising for is where we have a pattern that
5302
     * is positioned such that only one repeat of the tile is actually
5303
     * visible. In this case, we can restrict the size of the blending group
5304
     * we need to produce to be that of the actual area of the tile that is
5305
     * used. */
5306
57.1k
    ptile = pdevc->colors.pattern.p_tile;
5307
57.1k
    if (ptile->ttrans != NULL)
5308
15.7k
    {
5309
15.7k
        if ((cpath_intersection.outer_box.p.x < 0) ||
5310
15.7k
            (cpath_intersection.outer_box.p.y < 0) ||
5311
15.7k
            (cpath_intersection.outer_box.q.x > int2fixed(ptile->ttrans->width)) ||
5312
9.60k
            (cpath_intersection.outer_box.q.y > int2fixed(ptile->ttrans->height)))
5313
6.59k
        {
5314
            /* More than one repeat of the tile would be visible, so we can't
5315
             * use the optimisation here. (Actually, this test isn't quite
5316
             * right - it actually tests whether more than the '0th' repeat
5317
             * of the tile is visible. A better test would test if just one
5318
             * repeat of the tile was visible, irrespective of which one.
5319
             * This is (hopefully) relatively rare, and would make the code
5320
             * below more complex too, so we're ignoring that for now. If it
5321
             * becomes evident that it's a case that matters we can revisit
5322
             * it.) */
5323
9.13k
        } else {
5324
            /* Only the 0th repeat is visible. Restrict the size further to
5325
             * just the used area of that patch. */
5326
9.13k
            gx_path_init_local(&path_ttrans, ppath->memory);
5327
9.13k
            code = gx_path_add_rectangle(&path_ttrans,
5328
9.13k
                                         int2fixed(ptile->ttrans->rect.p.x),
5329
9.13k
                                         int2fixed(ptile->ttrans->rect.p.y),
5330
9.13k
                                         int2fixed(ptile->ttrans->rect.q.x),
5331
9.13k
                                         int2fixed(ptile->ttrans->rect.q.y));
5332
9.13k
            if (code < 0)
5333
0
                return code;
5334
9.13k
            code = gx_cpath_intersect(&cpath_intersection, &path_ttrans,
5335
9.13k
                                      params->rule, pgs_noconst);
5336
9.13k
            gx_path_free(&path_ttrans, "pdf14_tile_pattern_fill(path_ttrans)");
5337
9.13k
            if (code < 0)
5338
0
                return code;
5339
9.13k
        }
5340
15.7k
    }
5341
    /* Now let us push a transparency group into which we are
5342
     * going to tile the pattern.  */
5343
57.1k
    if (ppath != NULL) {
5344
57.1k
        pdf14_device save_pdf14_dev;    /* save area for p14dev */
5345
5346
57.1k
        gx_cpath_outer_box(&cpath_intersection, &outer_box);
5347
57.1k
        rect.p.x = fixed2int(outer_box.p.x);
5348
57.1k
        rect.p.y = fixed2int(outer_box.p.y);
5349
57.1k
        rect.q.x = fixed2int_ceiling(outer_box.q.x);
5350
57.1k
        rect.q.y = fixed2int_ceiling(outer_box.q.y);
5351
5352
        /* The color space of this group must be the same as that of the
5353
           tile.  Then when we pop the group, if there is a mismatch between
5354
           the tile color space and the current context we will do the proper
5355
           conversion.  In this way, we ensure that if the tile has any overlapping
5356
           occuring it will be blended in the proper manner i.e in the tile
5357
           underlying color space. */
5358
57.1k
        if (ptile->cdev == NULL) {
5359
15.7k
            if (ptile->ttrans == NULL)
5360
0
                return_error(gs_error_unknownerror);  /* should not happen */
5361
15.7k
            n_chan_tile = ptile->ttrans->n_chan;
5362
41.4k
        } else {
5363
41.4k
            n_chan_tile = ptile->cdev->common.color_info.num_components+1;
5364
41.4k
        }
5365
57.1k
        memcpy(&save_pdf14_dev, p14dev, sizeof(pdf14_device));
5366
5367
        /* Transparency handling with patterns confuses me, so some notes...
5368
         *
5369
         * For simple, non-transparent patterns, like you'd get in PS, we've
5370
         * used bitmap tiles. Draw into those tiles, and tile those out multiple
5371
         * times. To cope with unmarked pixels, we have a "transparency" plane
5372
         * (simple on/off) that says whether a pixel is marked or not.
5373
         *
5374
         * For patterns with transparency (but not blending), we can create an
5375
         * isolated transparency group, tile all the bitmap tiles into that, and
5376
         * then blend that back with the required alpha at the end. This works
5377
         * because the alpha values of the individual objects within the tile are
5378
         * recorded in that group.
5379
         *
5380
         * We can't do that for groups that use blending though, as each object
5381
         * in the pattern might use a different blend, and we don't (can't) record
5382
         * the blending mode. An isolated group doesn't even allow us to actually
5383
         * do the blending at all. So, for such patterns (any patterns that sets (or
5384
         * just has a resource that mentions) a non-normal blend mode), we use
5385
         * a pattern clist.
5386
         */
5387
57.1k
        if (ptile->cdev == NULL) {
5388
15.7k
            group_color_info = pdf14_clone_group_color_info(pdev, p14dev->ctx->stack->group_color_info);
5389
15.7k
            if (group_color_info == NULL)
5390
0
                return gs_error_VMerror;
5391
5392
15.7k
            code = pdf14_push_transparency_group(p14dev->ctx, &rect, 1, 0, (uint16_t)floor(65535 * p14dev->alpha + 0.5),
5393
15.7k
                                                 (uint16_t)floor(65535 * p14dev->shape + 0.5), (uint16_t)floor(65535 * p14dev->opacity + 0.5),
5394
15.7k
                                                 BLEND_MODE_Normal, 0, 0, n_chan_tile - 1, false, false,
5395
15.7k
                                                 NULL, NULL, group_color_info, pgs_noconst, pdev);
5396
15.7k
            if (code < 0)
5397
0
                return code;
5398
15.7k
        }
5399
5400
        /* Set the blending procs and the is_additive setting based
5401
           upon the number of channels */
5402
57.1k
        if (ptile->cdev == NULL) {
5403
15.7k
            if (n_chan_tile-1 < 4) {
5404
15.0k
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5405
15.0k
                ptile->ttrans->is_additive = true;
5406
15.0k
            } else {
5407
690
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5408
690
                ptile->ttrans->is_additive = false;
5409
690
            }
5410
15.7k
        }
5411
        /* Now lets go through the rect list and fill with the pattern */
5412
        /* First get the buffer that we will be filling */
5413
57.1k
        if (ptile->cdev == NULL) {
5414
15.7k
            fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5415
15.7k
            if (fill_trans_buffer == NULL) {
5416
0
                p14dev->pclist_device = NULL;
5417
0
                return_error(gs_error_VMerror);
5418
0
            }
5419
15.7k
            pdf14_get_buffer_information(pdev, fill_trans_buffer, NULL, false);
5420
            /* Based upon if the tiles overlap pick the type of rect fill that we will
5421
               want to use */
5422
15.7k
            if (ptile->has_overlap) {
5423
                /* This one does blending since there is tile overlap */
5424
1.34k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5425
14.3k
            } else {
5426
                /* This one does no blending since there is no tile overlap */
5427
14.3k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5428
14.3k
            }
5429
            /* fill the rectangles */
5430
15.7k
            phase.x = pdevc->phase.x;
5431
15.7k
            phase.y = pdevc->phase.y;
5432
15.7k
            if (cpath_intersection.rect_list->list.head != NULL){
5433
642
                curr_clip_rect = cpath_intersection.rect_list->list.head->next;
5434
10.6k
                for( k = 0; k < cpath_intersection.rect_list->list.count && code >= 0; k++){
5435
9.98k
                    if_debug5m('v', pgs->memory,
5436
9.98k
                               "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5437
9.98k
                               curr_clip_rect->xmin, curr_clip_rect->ymin,
5438
9.98k
                               curr_clip_rect->xmax-curr_clip_rect->xmin,
5439
9.98k
                               curr_clip_rect->ymax-curr_clip_rect->ymin, (int)ptile->id);
5440
9.98k
                    code = gx_trans_pattern_fill_rect(curr_clip_rect->xmin, curr_clip_rect->ymin,
5441
9.98k
                                                      curr_clip_rect->xmax, curr_clip_rect->ymax, ptile,
5442
9.98k
                                                      fill_trans_buffer, phase, pdev, pdevc, 1);
5443
9.98k
                    curr_clip_rect = curr_clip_rect->next;
5444
9.98k
                }
5445
15.0k
            } else if (cpath_intersection.rect_list->list.count == 1) {
5446
                /* The case when there is just a single rect */
5447
14.7k
                if_debug5m('v', pgs->memory,
5448
14.7k
                           "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5449
14.7k
                           cpath_intersection.rect_list->list.single.xmin,
5450
14.7k
                           cpath_intersection.rect_list->list.single.ymin,
5451
14.7k
                           cpath_intersection.rect_list->list.single.xmax-
5452
14.7k
                              cpath_intersection.rect_list->list.single.xmin,
5453
14.7k
                           cpath_intersection.rect_list->list.single.ymax-
5454
14.7k
                              cpath_intersection.rect_list->list.single.ymin,
5455
14.7k
                           (int)ptile->id);
5456
14.7k
                code = gx_trans_pattern_fill_rect(cpath_intersection.rect_list->list.single.xmin,
5457
14.7k
                                                  cpath_intersection.rect_list->list.single.ymin,
5458
14.7k
                                                  cpath_intersection.rect_list->list.single.xmax,
5459
14.7k
                                                  cpath_intersection.rect_list->list.single.ymax,
5460
14.7k
                                                  ptile, fill_trans_buffer, phase, pdev, pdevc, 1);
5461
14.7k
            }
5462
41.4k
        } else {
5463
            /* Clist pattern with transparency.  Create a clip device from our
5464
               cpath_intersection.  The above non-clist case could probably be
5465
               done this way too, which will reduce the amount of code here.
5466
               That is for another day though due to time constraints*/
5467
41.4k
            gx_device *dev;
5468
41.4k
            gx_device_clip clipdev;
5469
5470
41.4k
            gx_make_clip_device_on_stack(&clipdev, &cpath_intersection, pdev);
5471
41.4k
            dev = (gx_device *)&clipdev;
5472
41.4k
            phase.x = pdevc->phase.x;
5473
41.4k
            phase.y = pdevc->phase.y;
5474
41.4k
            code = gx_trans_pattern_fill_rect(rect.p.x, rect.p.y, rect.q.x, rect.q.y,
5475
41.4k
                                              ptile, fill_trans_buffer, phase,
5476
41.4k
                                              dev, pdevc, 1);
5477
41.4k
            gx_destroy_clip_device_on_stack(&clipdev);
5478
41.4k
        }
5479
        /* We're done drawing with the pattern, remove the reference to the
5480
         * pattern device
5481
         */
5482
57.1k
        p14dev->pclist_device = NULL;
5483
57.1k
        if (code < 0)
5484
0
            return code;
5485
5486
        /* free our buffer object */
5487
57.1k
        if (fill_trans_buffer != NULL) {
5488
15.7k
            gs_free_object(pgs->memory, fill_trans_buffer, "pdf14_tile_pattern_fill");
5489
15.7k
            ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5490
15.7k
        }
5491
57.1k
        if (ptile->cdev == NULL) {
5492
            /* pop our transparency group which will force the blending.
5493
               This was all needed for Bug 693498 */
5494
15.7k
            code = pdf14_pop_transparency_group(pgs_noconst, p14dev->ctx,
5495
15.7k
                                                p14dev->blend_procs,
5496
15.7k
                                                p14dev->color_info.num_components - has_tags,
5497
15.7k
                                                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5498
15.7k
                                                pdev);
5499
15.7k
        }
5500
57.1k
        memcpy(p14dev, &save_pdf14_dev, sizeof(pdf14_device));
5501
57.1k
        p14dev->pclist_device = NULL;
5502
57.1k
    }
5503
57.1k
    gx_cpath_free(&cpath_intersection, "pdf14_tile_pattern_fill");
5504
57.1k
    return code;
5505
57.1k
}
5506
5507
/* Useful function that should probably go elsewhere.
5508
 * Call this function to find the topmost pdf14 device in the device chain,
5509
 * or NULL if there is not one.
5510
 */
5511
static pdf14_device *find_pdf14_device(gx_device *dev)
5512
0
{
5513
0
    pdf14_device *pdev;
5514
5515
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, &pdev, sizeof(pdev)) <= 0)
5516
0
        return NULL;
5517
0
    return pdev;
5518
0
}
5519
5520
/* Imager render for pattern transparency filling.  This is just here to catch
5521
   the final flush, at which time we will pop the group and reset a few items */
5522
static  int
5523
pdf14_pattern_trans_render(gx_image_enum * penum, const byte * buffer, int data_x,
5524
                    uint w, int h, gx_device * dev)
5525
0
{
5526
0
    int code;
5527
0
    pdf14_device * p14dev;
5528
0
    const gs_gstate * pgs = penum->pgs;
5529
0
    gx_device_color * pdcolor = (penum->icolor1);
5530
0
    gx_color_tile *ptile = pdcolor->colors.pattern.p_tile;
5531
0
    bool has_tags = device_encodes_tags(dev);
5532
5533
    /* Pass along to the original renderer */
5534
0
    code = (ptile->ttrans->image_render)(penum, buffer, data_x, w, h, dev);
5535
0
    if (code < 0)
5536
0
        return code;
5537
    /* On our final time through here, go ahead and pop the transparency
5538
       group and reset the procs in the device color. And free the fill
5539
       trans buffer object */
5540
0
    if (h == 0 && ptile->trans_group_popped == false) {
5541
0
        p14dev = find_pdf14_device(dev);
5542
5543
0
        if (p14dev->pclist_device == NULL) {
5544
            /* Used if we are on clist writing phase.  Would only
5545
               occur if we somehow failed in high level clist
5546
               image writing */
5547
0
            code = gs_end_transparency_group((gs_gstate *) pgs);
5548
0
        } else {
5549
            /* Used if we are on clist reading phase.  If we had high level
5550
               image in clist */
5551
0
            cmm_dev_profile_t *dev_profile;
5552
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5553
0
            if (code < 0)
5554
0
                return code;
5555
5556
0
            if_debug2m('v', p14dev->ctx->memory,
5557
0
                      "[v*] Popping trans group pattern fill, uid = %ld id = %ld \n",
5558
0
                       ptile->uid.id, ptile->id);
5559
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx, p14dev->blend_procs,
5560
0
                    p14dev->color_info.num_components - has_tags,
5561
0
                    dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5562
0
                    (gx_device *) p14dev);
5563
0
        }
5564
0
        pdcolor->colors.pattern.p_tile->trans_group_popped = true;
5565
0
        gs_free_object(pgs->memory, ptile->ttrans->fill_trans_buffer,
5566
0
                       "pdf14_pattern_trans_render");
5567
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5568
0
    }
5569
0
    return code;
5570
0
}
5571
5572
/* This function is used to get things in place for filling a mask image
5573
   with a pattern that has transparency.  It is used by pdf14_begin_type_image
5574
   and pdf14_clist_begin_type_image */
5575
static int
5576
pdf14_patt_trans_image_fill(gx_device * dev, const gs_gstate * pgs,
5577
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5578
                           const gs_int_rect * prect,
5579
                           const gx_drawing_color * pdcolor,
5580
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5581
                           gx_image_enum_common_t ** pinfo)
5582
0
{
5583
0
    const gs_image_t *pim = (const gs_image_t *)pic;
5584
0
    pdf14_device * p14dev = (pdf14_device *)dev;
5585
0
    gx_color_tile *ptile;
5586
0
    int code;
5587
0
    gs_int_rect group_rect;
5588
0
    gx_image_enum *penum;
5589
0
    gs_rect bbox_in, bbox_out;
5590
0
    gx_pattern_trans_t *fill_trans_buffer;
5591
5592
0
    ptile = pdcolor->colors.pattern.p_tile;
5593
    /* Set up things in the ptile so that we get the proper
5594
       blending etc */
5595
    /* Set the blending procs and the is_additive setting based
5596
       upon the number of channels */
5597
0
    if (ptile->ttrans->n_chan-1 < 4) {
5598
0
        ptile->ttrans->blending_procs = &rgb_blending_procs;
5599
0
        ptile->ttrans->is_additive = true;
5600
0
    } else {
5601
0
        ptile->ttrans->blending_procs = &cmyk_blending_procs;
5602
0
        ptile->ttrans->is_additive = false;
5603
0
    }
5604
    /* Set the blending mode in the ptile based upon the current
5605
       setting in the gs_gstate */
5606
0
    ptile->blending_mode = pgs->blend_mode;
5607
    /* Based upon if the tiles overlap pick the type of rect
5608
       fill that we will want to use */
5609
0
    if (ptile->has_overlap) {
5610
        /* This one does blending since there is tile overlap */
5611
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5612
0
    } else {
5613
        /* This one does no blending since there is no tile overlap */
5614
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5615
0
    }
5616
    /* Set the procs so that we use the proper filling method. */
5617
0
    gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5618
    /* Let the imaging stuff get set up */
5619
0
    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
5620
0
                            prect, pdcolor,pcpath, mem, pinfo);
5621
0
    if (code < 0)
5622
0
        return code;
5623
    /* Now Push the group */
5624
    /* First apply the inverse of the image matrix to our
5625
       image size to get our bounding box. */
5626
0
    bbox_in.p.x = 0;
5627
0
    bbox_in.p.y = 0;
5628
0
    bbox_in.q.x = pim->Width;
5629
0
    bbox_in.q.y = pim->Height;
5630
0
    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
5631
0
                                &bbox_out);
5632
0
    if (code < 0)
5633
0
        return code;
5634
    /* That in turn will get hit by the matrix in the gs_gstate */
5635
0
    code = compute_group_device_int_rect(p14dev, &group_rect,
5636
0
                                            &bbox_out, (gs_gstate *)pgs);
5637
0
    if (code < 0)
5638
0
        return code;
5639
0
    if (!(pim->Width == 0 || pim->Height == 0)) {
5640
0
        if_debug2m('v', p14dev->ctx->memory,
5641
0
                   "[v*] Pushing trans group patt_trans_image_fill, uid = %ld id = %ld \n",
5642
0
                   ptile->uid.id, ptile->id);
5643
5644
0
        code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, 1, 0, 65535, 65535,
5645
0
                                             65535, pgs->blend_mode, 0, 0,
5646
0
                                             ptile->ttrans->n_chan-1, false, false,
5647
0
                                             NULL, NULL, NULL, (gs_gstate *)pgs, dev);
5648
5649
        /* Set up the output buffer information now that we have
5650
           pushed the group */
5651
0
        fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5652
0
        if (fill_trans_buffer == NULL)
5653
0
            return_error(gs_error_VMerror);
5654
5655
0
        pdf14_get_buffer_information(dev, fill_trans_buffer, NULL, false);
5656
5657
        /* Store this in the appropriate place in pdcolor.  This
5658
           is released later in pdf14_pattern_trans_render when
5659
           we are all done with the mask fill */
5660
0
        ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5661
5662
        /* Change the renderer to handle this case so we can catch the
5663
           end.  We will then pop the group and reset the pdcolor proc.
5664
           Keep the base renderer also. */
5665
0
        penum = (gx_image_enum *) *pinfo;
5666
0
        ptile->ttrans->image_render = penum->render;
5667
0
        penum->render = &pdf14_pattern_trans_render;
5668
0
        ptile->trans_group_popped = false;
5669
0
    }
5670
0
    return code;
5671
0
}
5672
5673
static  int
5674
pdf14_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
5675
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5676
                           const gs_int_rect * prect,
5677
                           const gx_drawing_color * pdcolor,
5678
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5679
                           gx_image_enum_common_t ** pinfo)
5680
290k
{
5681
290k
    const gs_image_t *pim = (const gs_image_t *)pic;
5682
290k
    int code;
5683
5684
290k
    code = pdf14_initialize_ctx(dev, pgs);
5685
290k
    if (code < 0)
5686
0
        return code;
5687
5688
    /* If we are filling an image mask with a pattern that has a transparency
5689
       then we need to do some special handling */
5690
290k
    if (pim->ImageMask) {
5691
93
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
5692
0
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
5693
                /* If we are in a final run through here for this case then
5694
                   go ahead and push the transparency group.   Also, update
5695
                   the proc for the pattern color so that we used the
5696
                   appropriate fill operation.  Note that the group
5697
                   is popped and the proc will be reset when we flush the
5698
                   image data.  This is handled in a special pdf14 image
5699
                   renderer which will end up installed for this case.
5700
                   Detect setting of begin_image to gx_no_begin_image.
5701
                   (final recursive call) */
5702
0
                if (dev_proc(dev, begin_typed_image) != gx_default_begin_typed_image) {
5703
0
                    code = pdf14_patt_trans_image_fill(dev, pgs, pmat, pic,
5704
0
                                                prect, pdcolor, pcpath, mem,
5705
0
                                                pinfo);
5706
0
                    return code;
5707
0
                }
5708
0
            }
5709
0
        }
5710
93
    }
5711
290k
    pdf14_set_marking_params(dev, pgs);
5712
290k
    return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor,
5713
290k
                                        pcpath, mem, pinfo);
5714
290k
}
5715
5716
static  void
5717
pdf14_set_params(gs_gstate * pgs,
5718
                 gx_device * dev,
5719
                 const gs_pdf14trans_params_t * pparams)
5720
7.52M
{
5721
7.52M
    if_debug0m('v', dev->memory, "[v]pdf14_set_params\n");
5722
7.52M
    if (pparams->changed & PDF14_SET_BLEND_MODE)
5723
1.88M
        pgs->blend_mode = pparams->blend_mode;
5724
7.52M
    if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
5725
957k
        pgs->text_knockout = pparams->text_knockout;
5726
7.52M
    if (pparams->changed & PDF14_SET_AIS)
5727
258k
        pgs->alphaisshape = pparams->ais;
5728
7.52M
    if (pparams->changed & PDF14_SET_OVERPRINT)
5729
2.21M
        pgs->overprint = pparams->overprint;
5730
7.52M
    if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
5731
2.21M
        pgs->stroke_overprint = pparams->stroke_overprint;
5732
7.52M
    if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
5733
2.39M
        pgs->fillconstantalpha = pparams->fillconstantalpha;
5734
7.52M
    if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
5735
1.69M
        pgs->strokeconstantalpha = pparams->strokeconstantalpha;
5736
7.52M
    if (pparams->changed & PDF14_SET_FILLSTROKE_STATE) {
5737
1.70M
        gs_swapcolors_quick(pgs);
5738
1.70M
        if (pparams->op_fs_state == PDF14_OP_STATE_STROKE)
5739
602k
            pgs->is_fill_color = false;
5740
1.10M
        else
5741
1.10M
            pgs->is_fill_color = true;
5742
1.70M
    }
5743
7.52M
    pdf14_set_marking_params(dev, pgs);
5744
7.52M
}
5745
5746
/*
5747
 * This open_device method for the PDF 1.4 compositor devices is only used
5748
 * when these devices are disabled.  This routine is about as close to
5749
 * a pure "forwarding" open_device operation as is possible. Its only
5750
 * significant function is to ensure that the is_open field of the
5751
 * PDF 1.4 compositor devices matches that of the target device.
5752
 *
5753
 * We assume this procedure is called only if the device is not already
5754
 * open, and that gs_opendevice will take care of the is_open flag.
5755
 */
5756
static  int
5757
pdf14_forward_open_device(gx_device * dev)
5758
0
{
5759
0
    gx_device_forward * pdev = (gx_device_forward *)dev;
5760
0
    gx_device * tdev = pdev->target;
5761
0
    int code;
5762
5763
    /* The PDF 1.4 compositing devices must have a target */
5764
0
    if (tdev == 0)
5765
0
        return_error(gs_error_unknownerror);
5766
0
    if ((code = gs_opendevice(tdev)) >= 0)
5767
0
        gx_device_copy_params(dev, tdev);
5768
0
    return code;
5769
0
}
5770
5771
/*
5772
 * Convert all device procs to be 'forwarding'.  The caller is responsible
5773
 * for setting any device procs that should not be forwarded.
5774
 */
5775
static  void
5776
pdf14_forward_device_procs(gx_device * dev)
5777
960k
{
5778
960k
    gx_device_forward *pdev = (gx_device_forward *)dev;
5779
960k
    pdf14_device *p14dev = (pdf14_device*)dev;
5780
5781
    /* If doing simulated overprint with spot colors
5782
       then makes sure to reset devn setting */
5783
960k
    if (p14dev->overprint_sim &&
5784
0
        p14dev->color_info.num_components > 4)
5785
0
        p14dev->icc_struct->supports_devn =
5786
0
            p14dev->target_support_devn;
5787
5788
    /*
5789
     * We are using gx_device_forward_fill_in_procs to set the various procs.
5790
     * This will ensure that any new device procs are also set.  However that
5791
     * routine only changes procs which are NULL.  Thus we start by setting all
5792
     * procs to NULL.
5793
     */
5794
960k
    memset(&(pdev->procs), 0, size_of(pdev->procs));
5795
960k
    gx_device_forward_fill_in_procs(pdev);
5796
    /*
5797
     * gx_device_forward_fill_in_procs does not forward all procs.
5798
     * Set the remainding procs to also forward.
5799
     */
5800
960k
    set_dev_proc(dev, close_device, gx_forward_close_device);
5801
960k
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
5802
960k
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
5803
960k
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
5804
960k
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
5805
960k
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
5806
960k
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
5807
960k
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
5808
960k
    set_dev_proc(dev, get_profile, gx_forward_get_profile);
5809
960k
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
5810
    /* These are forwarding devices with minor tweaks. */
5811
960k
    set_dev_proc(dev, open_device, pdf14_forward_open_device);
5812
960k
    set_dev_proc(dev, put_params, pdf14_forward_put_params);
5813
960k
}
5814
5815
/*
5816
 * Disable the PDF 1.4 compositor device.  Once created, the PDF 1.4
5817
 * compositor device is never removed.  (We do not have a remove compositor
5818
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
5819
 * routine implements that action.
5820
 */
5821
int
5822
pdf14_disable_device(gx_device * dev)
5823
951k
{
5824
951k
    gx_device_forward * pdev = (gx_device_forward *)dev;
5825
5826
951k
    if_debug0m('v', dev->memory, "[v]pdf14_disable_device\n");
5827
951k
    dev->color_info = pdev->target->color_info;
5828
951k
    pdf14_forward_device_procs(dev);
5829
951k
    set_dev_proc(dev, composite, pdf14_forward_composite);
5830
951k
    return 0;
5831
951k
}
5832
5833
/*
5834
 * The default color space for PDF 1.4 blend modes is based upon the process
5835
 * color model of the output device.
5836
 */
5837
static  pdf14_default_colorspace_t
5838
pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum,
5839
                                 pdf14_blend_cs_t *blend_cs_state)
5840
2.88M
{
5841
    /* If a blend color space was specified, then go ahead and use that to
5842
       define the default color space for the blend modes.  Only Gray, RGB
5843
       or CMYK blend color spaces are allowed.  Note we do not allow this
5844
       setting if we are dealing with a separation device. */
5845
2.88M
    cmm_dev_profile_t *dev_profile;
5846
2.88M
    cmm_profile_t *blend_profile = NULL;
5847
2.88M
    pdf14_blend_cs_t temp_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5848
2.88M
    int code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
5849
2.88M
    bool valid_blend_cs = false;
5850
2.88M
    int has_tags = device_encodes_tags(pdev);
5851
5852
2.88M
    *blend_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5853
5854
    /* Are we using a blend color space or the output intent color space? Also
5855
       is there a conflict in the settings. i.e. has someone set a blend color
5856
       space and tried to use the output intent with simulate overprint setting.
5857
    */
5858
2.88M
    if (dev_profile->overprint_control == gs_overprint_control_simulate &&
5859
0
        dev_profile->oi_profile != NULL &&
5860
0
        !gsicc_profiles_equal(dev_profile->oi_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5861
        /* If blend profile is also set, throw a warning about output intent not being used. We have
5862
           possible conflicting command line settings and we will err on using the blend profile
5863
           if one was specified. */
5864
0
        if (dev_profile->blend_profile != NULL &&
5865
0
            !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->oi_profile)) {
5866
0
            blend_profile = dev_profile->blend_profile;
5867
0
            temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5868
0
            emprintf(pdev->memory, "Warning: OI profile not used for blending CS\n");
5869
0
        } else {
5870
            /* All good, use the output intent profile as we have one
5871
               and are doing simulate overprint with a different device
5872
               profile set. */
5873
0
            blend_profile = dev_profile->oi_profile;
5874
0
            temp_cs_state = PDF14_BLEND_CS_OUTPUTINTENT;
5875
0
        }
5876
2.88M
    } else if (dev_profile->blend_profile != NULL &&
5877
0
               !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5878
        /* Blend profile is different than device profile */
5879
0
        blend_profile = dev_profile->blend_profile;
5880
0
        temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5881
0
    }
5882
5883
    /* Make sure any blend color space is valid along with other cond */
5884
2.88M
    if (code == 0 && blend_profile != NULL && !use_pdf14_accum) {
5885
0
        if (!blend_profile->isdevlink &&
5886
0
            !blend_profile->islab &&
5887
0
            (blend_profile->data_cs == gsGRAY ||
5888
0
             blend_profile->data_cs == gsRGB ||
5889
0
             blend_profile->data_cs == gsCMYK)) {
5890
            /* Also, do not allow the use of the blend space when we are pushing
5891
               a pattern pdf14 device.  Those should inherit from the parent */
5892
0
            if (!(gx_device_is_pattern_clist(pdev) ||
5893
0
                  gx_device_is_pattern_accum(pdev))) {
5894
0
                valid_blend_cs = true;
5895
0
            }
5896
0
        }
5897
0
    }
5898
5899
    /* If num components is one, just go ahead and use gray.  This avoids
5900
       issues with additive/subtractive mono color devices  */
5901
2.88M
    if (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ||
5902
2.65M
        pdev->color_info.num_components == 1) {
5903
        /*
5904
        * Note:  We do not allow the SeparationOrder device parameter for
5905
        * additive devices.  Thus we always have 1 colorant for DeviceGray
5906
        * and 3 colorants for DeviceRGB.
5907
        */
5908
2.65M
        if (valid_blend_cs) {
5909
0
            *blend_cs_state = temp_cs_state;
5910
0
            switch (blend_profile->num_comps) {
5911
0
            case 1:
5912
0
                return PDF14_DeviceGray;
5913
0
            case 3:
5914
0
                return PDF14_DeviceRGB;
5915
0
            case 4:
5916
0
                return PDF14_DeviceCMYK;
5917
0
            }
5918
0
        }
5919
2.65M
        if (pdev->color_info.num_components - has_tags == 1)
5920
946k
            return PDF14_DeviceGray;
5921
1.71M
        else if (pdev->color_info.num_components - has_tags == 3)
5922
1.71M
            return PDF14_DeviceRGB;
5923
0
        else
5924
0
            return PDF14_DeviceRGBspot;
5925
2.65M
    } else {
5926
        /*
5927
         * Check if the device is CMYK only or CMYK plus spot colors. Note
5928
         * the CMYK plus spot colors will not support the blend color space
5929
         */
5930
229k
        int i, output_comp_num, num_cmyk_used = 0, num_cmyk = 0;
5931
#if CUSTOM_BLENDING_MODE == ALWAYS_USE_CUSTOM_BLENDING
5932
        return PDF14_DeviceCustom;
5933
#endif
5934
        /*
5935
         * Count the number of CMYK process components supported by the output
5936
         * device.
5937
         */
5938
1.14M
        for (i = 0; i < 4; i++) {
5939
919k
            const char * pcomp_name = (const char *)DeviceCMYKComponents[i];
5940
5941
919k
            output_comp_num = dev_proc(pdev, get_color_comp_index)
5942
919k
                (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE_OP);
5943
919k
            if (output_comp_num >= 0) {
5944
919k
                num_cmyk++;
5945
919k
                if (output_comp_num != GX_DEVICE_COLOR_MAX_COMPONENTS)
5946
919k
                    num_cmyk_used++;
5947
919k
            }
5948
919k
        }
5949
        /*
5950
         * Check if the device supports only CMYK.  Otherewise we assume that
5951
         * the output device supports spot colors.  Note:  This algorithm can
5952
         * be fooled if the SeparationOrder device parameter is being used by
5953
         * the output device device to only select CMYK.
5954
         */
5955
229k
        if (num_cmyk_used == 4 && pdev->color_info.num_components == 4
5956
219k
            && pdev->color_info.max_components == 4) {
5957
48.6k
            if (valid_blend_cs) {
5958
0
                *blend_cs_state = temp_cs_state;
5959
0
                switch (blend_profile->num_comps) {
5960
0
                case 1:
5961
0
                    return PDF14_DeviceGray;
5962
0
                case 3:
5963
0
                    return PDF14_DeviceRGB;
5964
0
                case 4:
5965
0
                    return PDF14_DeviceCMYK;
5966
0
                }
5967
0
            }
5968
48.6k
            return PDF14_DeviceCMYK;
5969
48.6k
        }
5970
        /*
5971
         * Check if we should use the 'custom' PDF 1.4 compositor device.
5972
         * This device is only needed for those devices which do not support
5973
         * a basic CMYK process color model.
5974
         */
5975
181k
#if CUSTOM_BLENDING_MODE == AUTO_USE_CUSTOM_BLENDING
5976
181k
        if (num_cmyk != 4)
5977
0
            return PDF14_DeviceCustom;
5978
181k
#endif
5979
        /*
5980
         * Otherewise we use a CMYK plus spot colors for blending.
5981
         */
5982
181k
        if (valid_blend_cs)
5983
0
            *blend_cs_state = temp_cs_state;
5984
181k
        return PDF14_DeviceCMYKspot;
5985
181k
    }
5986
2.88M
}
5987
5988
/*
5989
 * the PDF 1.4 transparency spec says that color space for blending
5990
 * operations can be based upon either a color space specified in the
5991
 * group or a default value based upon the output device.  We are
5992
 * currently only using a color space based upon the device.
5993
 */
5994
static  int
5995
get_pdf14_device_proto(gx_device       *dev,
5996
                       pdf14_device    *pdevproto,
5997
                       gs_gstate       *pgs,
5998
                 const gs_pdf14trans_t *pdf14pct,
5999
                       bool             use_pdf14_accum)
6000
958k
{
6001
958k
    pdf14_blend_cs_t blend_cs_state;
6002
958k
    pdf14_default_colorspace_t dev_cs =
6003
958k
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
6004
958k
                                                 &blend_cs_state);
6005
958k
    bool deep = device_is_deep(dev);
6006
958k
    int num_spots = pdf14pct->params.num_spot_colors;
6007
958k
    bool has_tags = device_encodes_tags(dev);
6008
6009
    /* overprint overide */
6010
958k
    if (pdf14pct->params.overprint_sim_push &&
6011
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
6012
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
6013
0
            dev_cs = PDF14_DeviceCMYKspot;
6014
0
            num_spots = pdf14pct->params.num_spot_colors_int;
6015
0
        } else
6016
0
            dev_cs = PDF14_DeviceCMYK;
6017
0
    }
6018
6019
958k
    switch (dev_cs) {
6020
353k
        case PDF14_DeviceGray:
6021
353k
            *pdevproto = gs_pdf14_Gray_device;
6022
353k
            pdevproto->color_info.max_components = 1 + has_tags;
6023
353k
            pdevproto->color_info.num_components =
6024
353k
                                    pdevproto->color_info.max_components + has_tags;
6025
353k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6026
353k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6027
353k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
6028
353k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6029
353k
            pdevproto->sep_device = false;
6030
353k
            break;
6031
534k
        case PDF14_DeviceRGB:
6032
534k
            *pdevproto = gs_pdf14_RGB_device;
6033
534k
            pdevproto->color_info.max_components += has_tags;
6034
534k
            pdevproto->color_info.num_components += has_tags;
6035
534k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6036
534k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6037
534k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6038
534k
            pdevproto->sep_device = false;
6039
534k
            break;
6040
2.59k
        case PDF14_DeviceCMYK:
6041
2.59k
            *pdevproto = gs_pdf14_CMYK_device;
6042
2.59k
            pdevproto->color_info.max_components += has_tags;
6043
2.59k
            pdevproto->color_info.num_components += has_tags;
6044
2.59k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6045
2.59k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6046
2.59k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6047
2.59k
            pdevproto->sep_device = false;
6048
2.59k
            break;
6049
67.6k
        case PDF14_DeviceCMYKspot:
6050
67.6k
            *pdevproto = gs_pdf14_CMYKspot_device;
6051
            /* Need to figure out how we want to handle the device profile
6052
               for this case */
6053
            /*
6054
             * The number of components for the PDF14 device is the sum
6055
             * of the process components and the number of spot colors
6056
             * for the page.
6057
             */
6058
67.6k
            if (num_spots >= 0) {
6059
67.6k
                pdevproto->color_info.num_components =
6060
67.6k
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6061
67.6k
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6062
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6063
67.6k
                pdevproto->color_info.depth =
6064
67.6k
                                    pdevproto->color_info.num_components * (8<<deep);
6065
67.6k
                pdevproto->sep_device = true;
6066
67.6k
            }
6067
0
            else
6068
0
            {
6069
0
                pdevproto->color_info.max_components += has_tags;
6070
0
                pdevproto->color_info.num_components += has_tags;
6071
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6072
0
            }
6073
67.6k
            break;
6074
0
        case PDF14_DeviceRGBspot:
6075
0
            *pdevproto = gs_pdf14_RGBspot_device;
6076
            /* Need to figure out how we want to handle the device profile
6077
               for this case */
6078
            /*
6079
             * The number of components for the PDF14 device is the sum
6080
             * of the process components and the number of spot colors
6081
             * for the page.
6082
             */
6083
0
            if (num_spots >= 0) {
6084
0
                pdevproto->color_info.num_components =
6085
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6086
0
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6087
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6088
0
                pdevproto->color_info.depth =
6089
0
                    pdevproto->color_info.num_components * (8 << deep);
6090
0
                pdevproto->sep_device = true;
6091
0
            }
6092
0
            else
6093
0
            {
6094
0
                pdevproto->color_info.max_components += has_tags;
6095
0
                pdevproto->color_info.num_components += has_tags;
6096
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6097
0
            }
6098
0
            break;
6099
0
        case PDF14_DeviceCustom:
6100
            /*
6101
             * We are using the output device's process color model.  The
6102
             * color_info for the PDF 1.4 compositing device needs to match
6103
             * the output device.
6104
             */
6105
0
            *pdevproto = gs_pdf14_custom_device;
6106
0
            pdevproto->color_info = dev->color_info;
6107
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
6108
0
            pdevproto->color_info.depth =
6109
0
                       pdevproto->color_info.num_components * (8<<deep);
6110
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6111
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
6112
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6113
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
6114
0
            break;
6115
0
        default:      /* Should not occur */
6116
0
            return_error(gs_error_rangecheck);
6117
958k
    }
6118
958k
    pdevproto->initialize_device_procs((gx_device *)pdevproto);
6119
958k
    pdevproto->blend_cs_state = blend_cs_state;
6120
958k
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
6121
958k
    return 0;
6122
958k
}
6123
6124
/* When playing back the clist, we need to know if the buffer device is compatible */
6125
/* with the pdf14 compositor that was used when writing the clist. Colorspace and  */
6126
/* depth are critical since these must match when reading back colors.             */
6127
bool
6128
pdf14_ok_to_optimize(gx_device *dev)
6129
1.92M
{
6130
1.92M
    pdf14_blend_cs_t blend_cs_state;
6131
1.92M
    pdf14_default_colorspace_t pdf14_cs =
6132
1.92M
        pdf14_determine_default_blend_cs(dev, false, &blend_cs_state);
6133
1.92M
    gsicc_colorbuffer_t dev_icc_cs;
6134
1.92M
    bool ok = false;
6135
1.92M
    int tag_depth = device_encodes_tags(dev) ? 8 : 0;
6136
1.92M
    cmm_dev_profile_t *dev_profile;
6137
1.92M
    int code = dev_proc(dev, get_profile)(dev,  &dev_profile);
6138
1.92M
    bool deep = device_is_deep(dev);
6139
6140
1.92M
    if (code < 0)
6141
0
        return false;
6142
6143
1.92M
    check_device_compatible_encoding(dev);
6144
6145
1.92M
    if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN_STANDARD)
6146
869k
        return false;
6147
6148
1.05M
    dev_icc_cs = dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->data_cs;
6149
    /* If the outputprofile is not "standard" then colors converted to device color */
6150
    /* during clist writing won't match the colors written for the pdf14 clist dev  */
6151
1.05M
    if (!(dev_icc_cs == gsGRAY || dev_icc_cs == gsRGB || dev_icc_cs == gsCMYK))
6152
0
        return false;                           /* can't handle funky output profiles */
6153
6154
1.05M
    switch (pdf14_cs) {
6155
275k
        case PDF14_DeviceGray:
6156
275k
            ok = dev->color_info.max_gray == (deep ? 65535 : 255) && dev->color_info.depth == (8<<deep) + tag_depth;
6157
275k
            break;
6158
663k
        case PDF14_DeviceRGB:
6159
663k
            ok = dev->color_info.max_color == (deep ? 65535: 255) && dev->color_info.depth == (24<<deep) + tag_depth;
6160
663k
            break;
6161
0
        case PDF14_DeviceCMYK:
6162
0
            ok = dev->color_info.max_color == (deep ? 65535 : 255) && dev->color_info.depth == (32<<deep) + tag_depth;
6163
0
            break;
6164
112k
        case PDF14_DeviceCMYKspot:
6165
112k
            ok = false;     /* punt for this case */
6166
112k
            break;
6167
0
        case PDF14_DeviceRGBspot:
6168
0
            ok = false;     /* punt for this case */
6169
0
            break;
6170
0
        case PDF14_DeviceCustom:
6171
            /*
6172
             * We are using the output device's process color model.  The
6173
             * color_info for the PDF 1.4 compositing device needs to match
6174
             * the output device, but it may not have been contone.
6175
             */
6176
0
            ok = dev->color_info.depth == dev->color_info.num_components * (8<<deep) + tag_depth;
6177
0
            break;
6178
0
        default:      /* Should not occur */
6179
0
            ok = false;
6180
1.05M
    }
6181
1.05M
    return ok;
6182
1.05M
}
6183
6184
/*
6185
 * Recreate the PDF 1.4 compositor device.  Once created, the PDF 1.4
6186
 * compositor device is never removed.  (We do not have a remove compositor
6187
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
6188
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
6189
 * again.
6190
 */
6191
static  int
6192
pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs,
6193
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
6194
0
{
6195
0
    pdf14_device * pdev = (pdf14_device *)dev;
6196
0
    gx_device * target = pdev->target;
6197
0
    pdf14_device dev_proto;
6198
0
    bool has_tags = device_encodes_tags(dev);
6199
0
    int code;
6200
0
    bool deep = device_is_deep(dev);
6201
6202
0
    if_debug0m('v', dev->memory, "[v]pdf14_recreate_device\n");
6203
6204
    /*
6205
     * We will not use the entire prototype device but we will set the
6206
     * color related info and the device procs to match the prototype.
6207
     */
6208
0
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
6209
0
                                  pdf14pct, false);
6210
0
    if (code < 0)
6211
0
        return code;
6212
0
    pdev->color_info = dev_proto.color_info;
6213
0
    pdev->pad = target->pad;
6214
0
    pdev->log2_align_mod = target->log2_align_mod;
6215
6216
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
6217
0
        pdev->num_planar_planes = dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
6218
0
    else
6219
0
        pdev->num_planar_planes = target->num_planar_planes;
6220
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
6221
6222
0
    if (dev_proto.initialize_device_procs != NULL)
6223
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
6224
0
    pdev->procs = dev_proto.procs;
6225
0
    if (deep) {
6226
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
6227
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
6228
0
    }
6229
0
    if (has_tags) {
6230
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
6231
0
    }
6232
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
6233
0
    gx_device_fill_in_procs((gx_device *)pdev);
6234
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
6235
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
6236
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
6237
0
    check_device_separable(dev);
6238
0
    return dev_proc(pdev, open_device)(dev);
6239
0
}
6240
6241
/*
6242
 * Implement the various operations that can be specified via the PDF 1.4
6243
 * create compositor request.
6244
 */
6245
static  int
6246
gx_update_pdf14_compositor(gx_device * pdev, gs_gstate * pgs,
6247
    const gs_pdf14trans_t * pdf14pct, gs_memory_t * mem )
6248
18.7M
{
6249
18.7M
    pdf14_device *p14dev = (pdf14_device *)pdev;
6250
18.7M
    gs_pdf14trans_params_t params = pdf14pct->params;
6251
18.7M
    int code = 0;
6252
6253
18.7M
    params.idle = pdf14pct->idle;
6254
18.7M
    switch (params.pdf14_op) {
6255
0
        default:      /* Should not occur. */
6256
0
            break;
6257
10.5k
        case PDF14_PUSH_DEVICE:
6258
10.5k
            if (!(params.is_pattern)) {
6259
0
                p14dev->blend_mode = 0;
6260
0
                p14dev->opacity = p14dev->shape = 0.0;
6261
0
                pdf14_recreate_device(mem, pgs, pdev, pdf14pct);
6262
0
            }
6263
10.5k
            break;
6264
0
        case PDF14_ABORT_DEVICE:
6265
            /* Something has gone very wrong.  Let transparency device clean up
6266
               what ever it has allocated and then we are shutting it down */
6267
0
            code = gx_abort_trans_device(pgs, pdev);
6268
0
            if (p14dev->free_devicen) {
6269
0
                devn_free_params(pdev);
6270
0
            }
6271
0
            pdf14_disable_device(pdev);
6272
0
            pdf14_close(pdev);
6273
0
            break;
6274
958k
        case PDF14_POP_DEVICE:
6275
958k
            if (!(params.is_pattern)) {
6276
947k
                if_debug0m('v', pdev->memory,
6277
947k
                           "[v]gx_update_pdf14_compositor(PDF14_POP_DEVICE)\n");
6278
947k
                pgs->get_cmap_procs = p14dev->save_get_cmap_procs;
6279
947k
                gx_set_cmap_procs(pgs, p14dev->target);
6280
                /* Send image out raster data to output device */
6281
947k
                {
6282
                    /* Make a copy so we can change the ROP */
6283
947k
                    gs_gstate new_pgs = *pgs;
6284
6285
                    /* We don't use the gs_gstate log_op since this is for the */
6286
                    /* clist playback. Putting the image (band in the case of the */
6287
                    /* clist) only needs to use the default ROP to copy the data  */
6288
947k
                    new_pgs.log_op = rop3_default;
6289
947k
                    code = p14dev->pdf14_procs->put_image(pdev, &new_pgs, p14dev->target);
6290
947k
                }
6291
                /* Before we disable the device release any deviceN structures.
6292
                    free_devicen is set if the pdf14 device had inherited its
6293
                    deviceN parameters from the target clist device.  In this
6294
                    case they should not be freed */
6295
947k
                if (p14dev->free_devicen) {
6296
947k
                    gs_devn_params *devn_params = dev_proc(pdev, ret_devn_params)(pdev);
6297
947k
                    if (devn_params) {
6298
947k
                        gxdso_spot_info si;
6299
947k
                        si.params = devn_params;
6300
947k
                        si.equiv = &p14dev->op_pequiv_cmyk_colors;
6301
947k
                        (void)dev_proc(p14dev->target, dev_spec_op)(p14dev->target, gxdso_update_spots, &si, sizeof(si));
6302
947k
                    }
6303
947k
                    devn_free_params(pdev);
6304
947k
                }
6305
947k
                pdf14_disable_device(pdev);
6306
947k
                pdf14_close(pdev);
6307
947k
            }
6308
958k
            break;
6309
369k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
6310
1.95M
        case PDF14_BEGIN_TRANS_GROUP:
6311
1.95M
            if (p14dev->smask_constructed || p14dev->depth_within_smask)
6312
269k
                p14dev->depth_within_smask++;
6313
1.95M
            p14dev->smask_constructed = 0;
6314
1.95M
            code = gx_begin_transparency_group(pgs, pdev, &params);
6315
1.95M
            break;
6316
1.56M
        case PDF14_END_TRANS_GROUP:
6317
1.56M
            code = gx_end_transparency_group(pgs, pdev);
6318
1.56M
            if (p14dev->depth_within_smask)
6319
269k
                p14dev->depth_within_smask--;
6320
1.56M
            break;
6321
131
        case PDF14_BEGIN_TRANS_TEXT_GROUP:
6322
131
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
6323
0
                p14dev->text_group = PDF14_TEXTGROUP_MISSING_ET;
6324
0
                emprintf(p14dev->memory, "Warning: Text group pushed but no ET found\n");
6325
0
            } else
6326
131
                p14dev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6327
131
            break;
6328
386k
        case PDF14_END_TRANS_TEXT_GROUP:
6329
386k
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED)
6330
386k
                code = gx_end_transparency_group(pgs, pdev);
6331
386k
            p14dev->text_group = PDF14_TEXTGROUP_NO_BT; /* Hit ET */
6332
386k
            break;
6333
3.56M
        case PDF14_BEGIN_TRANS_MASK:
6334
3.56M
            code = gx_begin_transparency_mask(pgs, pdev, &params);
6335
3.56M
            if (code >= 0 && params.subtype != TRANSPARENCY_MASK_None)
6336
361k
                p14dev->in_smask_construction++;
6337
3.56M
            break;
6338
361k
        case PDF14_END_TRANS_MASK:
6339
361k
            code = gx_end_transparency_mask(pgs, pdev, &params);
6340
361k
            if (code >= 0) {
6341
361k
                p14dev->in_smask_construction--;
6342
361k
                if (p14dev->in_smask_construction < 0)
6343
0
                    p14dev->in_smask_construction = 0;
6344
361k
                if (p14dev->in_smask_construction == 0)
6345
361k
                    p14dev->smask_constructed = 1;
6346
361k
            }
6347
361k
            break;
6348
7.52M
        case PDF14_SET_BLEND_PARAMS:
6349
7.52M
            pdf14_set_params(pgs, pdev, &pdf14pct->params);
6350
7.52M
            break;
6351
0
        case PDF14_PUSH_TRANS_STATE:
6352
0
            code = gx_push_transparency_state(pgs, pdev);
6353
0
            break;
6354
2.42M
        case PDF14_POP_TRANS_STATE:
6355
2.42M
            code = gx_pop_transparency_state(pgs, pdev);
6356
2.42M
            break;
6357
3.78k
        case PDF14_PUSH_SMASK_COLOR:
6358
3.78k
            code = pdf14_increment_smask_color(pgs, pdev);
6359
3.78k
            break;
6360
3.78k
        case PDF14_POP_SMASK_COLOR:
6361
3.78k
            code = pdf14_decrement_smask_color(pgs, pdev);
6362
3.78k
            break;
6363
18.7M
    }
6364
18.7M
    return code;
6365
18.7M
}
6366
6367
/*
6368
 * The PDF 1.4 compositor is never removed.  (We do not have a 'remove
6369
 * compositor' method.  However the compositor is disabled when we are not
6370
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
6371
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
6372
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
6373
 * to the target.
6374
 */
6375
static  int
6376
pdf14_forward_composite(gx_device * dev, gx_device * * pcdev,
6377
        const gs_composite_t * pct, gs_gstate * pgs,
6378
        gs_memory_t * mem, gx_device *cdev)
6379
1.34k
{
6380
1.34k
    pdf14_device *pdev = (pdf14_device *)dev;
6381
1.34k
    gx_device * tdev = pdev->target;
6382
1.34k
    int code;
6383
6384
1.34k
    *pcdev = dev;
6385
1.34k
    if (gs_is_pdf14trans_compositor(pct)) {
6386
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6387
6388
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
6389
0
            return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6390
0
        return 0;
6391
0
    }
6392
1.34k
    code = dev_proc(tdev, composite)(tdev, pcdev, pct, pgs, mem, cdev);
6393
1.34k
    if (code == 1) {
6394
        /* We have created a new compositor that wrapped tdev. This means
6395
         * that our target should be updated to point to that. */
6396
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
6397
0
        code = 0; /* We have not created a new compositor that wrapped dev. */
6398
0
    }
6399
1.34k
    return code;
6400
1.34k
}
6401
6402
/*
6403
 * The PDF 1.4 compositor can be handled directly, so just set *pcdev = dev
6404
 * and return. Since the gs_pdf14_device only supports the high-level routines
6405
 * of the interface, don't bother trying to handle any other compositor.
6406
 */
6407
static int
6408
pdf14_composite(gx_device * dev, gx_device * * pcdev,
6409
        const gs_composite_t * pct, gs_gstate * pgs,
6410
        gs_memory_t * mem, gx_device *cdev)
6411
103M
{
6412
103M
    pdf14_device *p14dev = (pdf14_device *)dev;
6413
103M
    if (gs_is_pdf14trans_compositor(pct)) {
6414
18.7M
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6415
18.7M
        *pcdev = dev;
6416
        /* cdev, may be the clist reader device which may contain information that
6417
           we will need related to the ICC color spaces that define transparency
6418
           groups.  We want this propogated through all the pdf14 functions.  Store
6419
           a pointer to it in the pdf14 device */
6420
18.7M
        p14dev->pclist_device = cdev;
6421
18.7M
        return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6422
84.9M
    } else if (gs_is_overprint_compositor(pct)) {
6423
                /* If we had an overprint compositer action, then the
6424
                   color components that were drawn should be updated.
6425
                   The overprint compositor logic and its interactions
6426
                   with the clist is a little odd as it passes uninitialized
6427
                   values around a fair amount.  Hence the forced assignement here.
6428
                   See gx_spot_colors_set_overprint in gscspace for issues... */
6429
84.9M
                const gs_overprint_t * op_pct = (const gs_overprint_t *) pct;
6430
84.9M
                gx_color_index drawn_comps;
6431
84.9M
                PDF14_OP_FS_STATE curr_state = p14dev->op_state;
6432
6433
84.9M
                p14dev->op_state = op_pct->params.op_state;
6434
84.9M
                if (p14dev->op_state == PDF14_OP_STATE_NONE) {
6435
42.4M
                    if (op_pct->params.retain_any_comps) {
6436
23.0k
                        drawn_comps = op_pct->params.drawn_comps;
6437
42.4M
                    } else {
6438
                        /* Draw everything. If this parameter was not set, clist does
6439
                           not fill it in.  */
6440
42.4M
                        drawn_comps = ((gx_color_index)1 << (p14dev->color_info.num_components)) - (gx_color_index)1;
6441
42.4M
                    }
6442
6443
42.4M
                    if (op_pct->params.is_fill_color) {
6444
23.3M
                        p14dev->effective_overprint_mode = op_pct->params.effective_opm;
6445
23.3M
                        p14dev->drawn_comps_fill = drawn_comps;
6446
23.3M
                    } else {
6447
19.1M
                        p14dev->stroke_effective_op_mode = op_pct->params.effective_opm;
6448
19.1M
                        p14dev->drawn_comps_stroke = drawn_comps;
6449
19.1M
                    }
6450
                    /* We restore the NONE states as that is used just to force
6451
                       overprint settings in the overprint compositor communication */
6452
42.4M
                    p14dev->op_state = curr_state;
6453
42.4M
                }
6454
84.9M
                *pcdev = dev;
6455
84.9M
                return 0;
6456
84.9M
    } else
6457
0
        return gx_no_composite(dev, pcdev, pct, pgs, mem, cdev);
6458
103M
}
6459
6460
static int
6461
pdf14_push_text_group(gx_device *dev, gs_gstate *pgs,
6462
                      gs_blend_mode_t blend_mode, float opacity,
6463
                      float shape, bool is_clist)
6464
2.27k
{
6465
2.27k
    int code;
6466
2.27k
    gs_transparency_group_params_t params = { 0 };
6467
2.27k
    gs_rect bbox = { 0 }; /* Bounding box is set by parent */
6468
2.27k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
6469
2.27k
    float alpha = pgs->fillconstantalpha;
6470
6471
    /* Push a non-isolated knock-out group making sure the opacity and blend
6472
       mode are correct */
6473
2.27k
    params.Isolated = false;
6474
2.27k
    params.Knockout = true;
6475
2.27k
    params.page_group = false;
6476
2.27k
    params.text_group = PDF14_TEXTGROUP_BT_PUSHED;
6477
2.27k
    params.group_opacity = 1.0;
6478
2.27k
    params.group_shape = 1.0;
6479
6480
2.27k
    gs_setfillconstantalpha(pgs, 1.0);
6481
2.27k
    gs_setblendmode(pgs, BLEND_MODE_Normal);
6482
6483
2.27k
    if (is_clist) {
6484
2.27k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6485
2.27k
        if (code < 0)
6486
0
            return code;
6487
2.27k
    }
6488
6489
2.27k
    code = gs_begin_transparency_group(pgs, &params, &bbox, PDF14_BEGIN_TRANS_GROUP);
6490
2.27k
    gs_setfillconstantalpha(pgs, alpha);
6491
2.27k
    gs_setblendmode(pgs, blend_mode);
6492
2.27k
    if (code < 0)
6493
0
        return code;
6494
6495
2.27k
    if (is_clist) {
6496
2.27k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6497
2.27k
    }
6498
2.27k
    return code;
6499
2.27k
}
6500
6501
static  int
6502
pdf14_text_begin(gx_device * dev, gs_gstate * pgs,
6503
                 const gs_text_params_t * text, gs_font * font,
6504
                 const gx_clip_path * pcpath,
6505
                 gs_text_enum_t ** ppenum)
6506
287
{
6507
287
    int code;
6508
287
    gs_text_enum_t *penum;
6509
287
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
6510
287
    float opacity = pgs->fillconstantalpha;
6511
287
    float shape = 1.0;
6512
287
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
6513
287
    pdf14_device *pdev = (pdf14_device*)dev;
6514
287
    bool draw = !(text->operation & TEXT_DO_NONE);
6515
287
    uint text_mode = gs_currenttextrenderingmode(pgs);
6516
287
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
6517
287
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
6518
6519
287
    code = pdf14_initialize_ctx(dev, pgs);
6520
287
    if (code < 0)
6521
0
        return code;
6522
6523
287
    if_debug0m('v', pgs->memory, "[v]pdf14_text_begin\n");
6524
287
    pdf14_set_marking_params(dev, pgs);
6525
287
    code = gx_default_text_begin(dev, pgs, text, font, pcpath, &penum);
6526
287
    if (code < 0)
6527
0
        return code;
6528
6529
    /* We may need to push a non-isolated transparency group if the following
6530
       is true.
6531
       1) We are not currently in one that we pushed for text and we are in
6532
          a BT/ET pair.  This is determined by looking at the pdf14 text_group.
6533
       2) The blend mode is not Normal or the opacity is not 1.0
6534
       3) Text knockout is set to true
6535
       4) We are actually doing a text drawing
6536
6537
       Special note:  If text-knockout is set to false while we are within a
6538
       BT ET pair, we should pop the group.  I need to create a test file for
6539
       this case.  */
6540
6541
       /* Catch case where we already pushed a group and are trying to push another one.
6542
       In that case, we will pop the current one first, as we don't want to be left
6543
       with it. Note that if we have a BT and no other BTs or ETs then this issue
6544
       will not be caught until we do the put_image and notice that the stack is not
6545
       empty. */
6546
287
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
6547
0
        code = gs_end_transparency_group(pgs);
6548
0
        if (code < 0)
6549
0
            return code;
6550
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6551
0
    }
6552
6553
287
    if (gs_currenttextknockout(pgs) && (blend_issue ||
6554
286
         (pgs->fillconstantalpha != 1.0 && text_fill) ||
6555
286
         (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
6556
1
         text_mode != 3 && /* don't bother with invisible text */
6557
1
         pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED)
6558
1
        if (draw) {
6559
1
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape,
6560
1
                false);
6561
1
        }
6562
287
    *ppenum = (gs_text_enum_t *)penum;
6563
287
    return code;
6564
287
}
6565
6566
static  int
6567
pdf14_initialize_device(gx_device *new_dev)
6568
958k
{
6569
958k
    pdf14_device *pdev = (pdf14_device*)new_dev;
6570
6571
958k
    pdev->ctx = NULL;
6572
958k
    pdev->color_model_stack = NULL;
6573
958k
    pdev->smaskcolor = NULL;
6574
6575
958k
    return 0;
6576
958k
}
6577
6578
/*
6579
 * Implement copy_mono by filling lots of small rectangles.
6580
 */
6581
static int
6582
pdf14_copy_mono(gx_device * dev,
6583
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
6584
        int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
6585
11.2M
{
6586
11.2M
    const byte *sptr;
6587
11.2M
    const byte *line;
6588
11.2M
    int sbit, first_bit;
6589
11.2M
    int code, sbyte, bit, count;
6590
11.2M
    int run_length, startx, current_bit, bit_value;
6591
11.2M
    gx_color_index current_color;
6592
6593
11.2M
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
6594
11.2M
    line = base + (sourcex >> 3);
6595
11.2M
    sbit = sourcex & 7;
6596
11.2M
    first_bit = 7 - sbit;
6597
6598
    /* Loop through the height of the specified area. */
6599
85.1M
    while (h-- > 0) {
6600
        /* Set up for the start of each line of the area. */
6601
73.9M
        sptr = line;
6602
73.9M
        sbyte = *sptr++;
6603
        /* The +1 here is 'sacrificial', we are going to decrement it by 1 immediately in
6604
         * the loop below so adding 1 means that we don't fall into the bit == 0
6605
         * case and incorrectly read a new byte from the source. This weirdness is because
6606
         * the original code wouold read off the end of the buffer if the number of bits in
6607
         * the raster was an exact multiple of 8. If it was also a multiple of the word
6608
         * size we might read unallocated memory. Moving the 'sbyte = *sptr++' from the end
6609
         * of the loop to the beginning meant we would not read past the end of the buffer
6610
         * because we would drop out of the 'do ... while (count-- > 0)' loop before
6611
         * reading another byte.
6612
         */
6613
73.9M
        bit = first_bit + 1;
6614
73.9M
        count = w;
6615
73.9M
        run_length = 0;
6616
73.9M
        startx = x;
6617
73.9M
        current_bit = 0;
6618
73.9M
        current_color = zero;
6619
6620
        /* Loop across each pixel of a line. */
6621
1.05G
        do {
6622
            /* Move to the next input bit. */
6623
1.05G
            if (bit == 0) {
6624
90.9M
                bit = 7;
6625
90.9M
                sbyte = *sptr++;
6626
90.9M
            }
6627
961M
            else
6628
961M
                bit--;
6629
1.05G
            bit_value = (sbyte >> bit) & 1;
6630
1.05G
            if (bit_value == current_bit) {
6631
                /* The value did not change, simply increment our run length */
6632
868M
                run_length++;
6633
868M
            } else {
6634
                /* The value changed, fill the current rectangle. */
6635
184M
                if (run_length != 0) {
6636
176M
                    if (current_color != gx_no_color_index) {
6637
75.9M
                        code = (*dev_proc(dev, fill_rectangle))
6638
75.9M
                                (dev, startx, y, run_length, 1, current_color);
6639
75.9M
                        if (code < 0)
6640
0
                            return code;
6641
75.9M
                    }
6642
176M
                    startx += run_length;
6643
176M
                }
6644
184M
                run_length = 1;
6645
184M
                current_color = bit_value ? one : zero;
6646
184M
                current_bit = bit_value;
6647
184M
            }
6648
1.05G
        } while (--count > 0);
6649
        /* Fill the last rectangle in the line. */
6650
73.9M
        if (run_length != 0 && current_color != gx_no_color_index) {
6651
32.9M
            code = (*dev_proc(dev, fill_rectangle))
6652
32.9M
                        (dev, startx, y, run_length, 1, current_color);
6653
32.9M
            if (code < 0)
6654
0
                return code;
6655
32.9M
        }
6656
        /* Move to the next line */
6657
73.9M
        line += sraster;
6658
73.9M
        y++;
6659
73.9M
    }
6660
11.2M
    return 0;
6661
11.2M
}
6662
6663
/* Added to avoid having to go back and forth between fixed and int
6664
   in some of the internal methods used for dealing with tiling
6665
   and devn colors */
6666
static int
6667
pdf14_fill_rectangle_devn(gx_device *dev, int x, int y, int w, int h,
6668
    const gx_drawing_color *pdcolor)
6669
962
{
6670
962
    pdf14_device *pdev = (pdf14_device *)dev;
6671
962
    pdf14_buf *buf;
6672
962
    int code;
6673
6674
962
    fit_fill_xywh(dev, x, y, w, h);
6675
962
    if (w <= 0 || h <= 0)
6676
0
        return 0;
6677
6678
962
    code = pdf14_initialize_ctx(dev, NULL);
6679
962
    if (code < 0)
6680
0
        return code;
6681
962
    buf = pdev->ctx->stack;
6682
6683
962
    if (buf->knockout)
6684
0
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
6685
0
            true);
6686
962
    else
6687
962
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
6688
962
}
6689
6690
/* Step through and do rect fills with the devn colors as
6691
   we hit each transition in the bitmap. It is possible
6692
   that one of the colors is not devn, but is pure and
6693
   is set to gx_no_color_index. This type of mix happens
6694
   for example from tile_clip_fill_rectangle_hl_color */
6695
static int
6696
pdf14_copy_mono_devn(gx_device *dev,
6697
    const byte *base, int sourcex, int sraster,
6698
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6699
    const gx_drawing_color *pdcolor1)
6700
248
{
6701
248
    const byte *sptr;
6702
248
    const byte *line;
6703
248
    int sbit, first_bit;
6704
248
    int code, sbyte, bit, count;
6705
248
    int run_length, startx, current_bit, bit_value;
6706
248
    const gx_drawing_color *current_color;
6707
6708
248
    if ((x | y) < 0) {
6709
0
        if (x < 0) {
6710
0
            w += x;
6711
0
            sourcex -= x;
6712
0
            x = 0;
6713
0
        }
6714
0
        if (y < 0) {
6715
0
            h += y;
6716
0
            base -= (int)(y * sraster);
6717
0
            y = 0;
6718
0
        }
6719
0
    }
6720
248
    if (w > (dev)->width - x)
6721
0
        w = (dev)->width - x;
6722
248
    if (h > (dev)->height - y)
6723
0
        h = (dev)->height - y;
6724
248
    if (w <= 0 || h <= 0)
6725
0
        return 0;
6726
6727
248
    line = base + (sourcex >> 3);
6728
248
    sbit = sourcex & 7;
6729
248
    first_bit = 7 - sbit;
6730
6731
    /* Loop through the height of the specified area. */
6732
815
    while (h-- > 0) {
6733
        /* Set up for the start of each line of the area. */
6734
567
        sptr = line;
6735
567
        sbyte = *sptr++;
6736
567
        bit = first_bit;
6737
567
        count = w;
6738
567
        run_length = 0;
6739
567
        startx = x;
6740
567
        current_bit = 0;
6741
567
        current_color = pdcolor0;
6742
6743
        /* Loop across each pixel of a line. */
6744
6.15k
        do {
6745
6.15k
            bit_value = (sbyte >> bit) & 1;
6746
6.15k
            if (bit_value == current_bit) {
6747
                /* The value did not change, simply increment our run length */
6748
4.47k
                run_length++;
6749
4.47k
            } else {
6750
                /* The value changed, fill the current rectangle. */
6751
1.67k
                if (run_length != 0) {
6752
1.51k
                    if (current_color->type != gx_dc_type_pure &&
6753
717
                        current_color->colors.pure != gx_no_color_index) {
6754
717
                        code = pdf14_fill_rectangle_devn(dev, startx, y,
6755
717
                            run_length, 1, current_color);
6756
717
                        if (code < 0)
6757
0
                            return code;
6758
717
                    }
6759
1.51k
                    startx += run_length;
6760
1.51k
                }
6761
1.67k
                run_length = 1;
6762
1.67k
                current_color = bit_value ? pdcolor1 : pdcolor0;
6763
1.67k
                current_bit = bit_value;
6764
1.67k
            }
6765
6766
            /* Move to the next input bit. */
6767
6.15k
            if (bit == 0) {
6768
553
                bit = 7;
6769
553
                sbyte = *sptr++;
6770
553
            } else
6771
5.60k
                bit--;
6772
6.15k
        } while (--count > 0);
6773
6774
        /* Fill the last rectangle in the line. */
6775
567
        if (run_length != 0 && current_color->type != gx_dc_type_pure &&
6776
245
            current_color->colors.pure != gx_no_color_index) {
6777
245
            code = pdf14_fill_rectangle_devn(dev, startx, y,
6778
245
                run_length, 1, current_color);
6779
245
            if (code < 0)
6780
0
                return code;
6781
245
        }
6782
        /* Move to the next line */
6783
567
        line += sraster;
6784
567
        y++;
6785
567
    }
6786
248
    return 0;
6787
248
}
6788
6789
/* Step through the tiles doing essentially copy_mono but with devn colors */
6790
static int
6791
pdf14_impl_strip_tile_rectangle_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6792
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6793
    const gx_drawing_color *pdcolor1, int px, int py)
6794
248
{   /* Fill the rectangle in chunks. */
6795
248
    int width = tiles->size.x;
6796
248
    int height = tiles->size.y;
6797
248
    int raster = tiles->raster;
6798
248
    int rwidth = tiles->rep_width;
6799
248
    int rheight = tiles->rep_height;
6800
248
    int shift = tiles->shift;
6801
6802
248
    if (rwidth == 0 || rheight == 0)
6803
0
        return_error(gs_error_unregistered);
6804
248
    fit_fill_xy(dev, x, y, w, h);
6805
6806
248
     {
6807
248
        int xoff = (shift == 0 ? px :
6808
248
                px + (y + py) / rheight * tiles->rep_shift);
6809
248
        int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */
6810
0
            (x + xoff) & (rwidth - 1) :
6811
248
            (x + xoff) % rwidth);
6812
248
        int ry = ((rheight & (rheight - 1)) == 0 ? /* power of 2 */
6813
0
            (y + py) & (rheight - 1) :
6814
248
            (y + py) % rheight);
6815
248
        int icw = width - irx;
6816
248
        int ch = height - ry;
6817
248
        byte *row = tiles->data + ry * raster;
6818
248
        int code = 0;
6819
6820
248
        if (ch >= h) {      /* Shallow operation */
6821
248
            if (icw >= w) { /* Just one (partial) tile to transfer. */
6822
248
                code = pdf14_copy_mono_devn(dev, row, irx, raster, x, y,
6823
248
                    w, h, pdcolor0, pdcolor1);
6824
248
                if (code < 0)
6825
0
                    return_error(code);
6826
248
            } else {
6827
0
                int ex = x + w;
6828
0
                int fex = ex - width;
6829
0
                int cx = x + icw;
6830
6831
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6832
0
                    x, y, icw, h, pdcolor0, pdcolor1);
6833
0
                if (code < 0)
6834
0
                    return_error(code);
6835
6836
0
                while (cx <= fex) {
6837
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6838
0
                        width, h, pdcolor0, pdcolor1);
6839
0
                    if (code < 0)
6840
0
                        return_error(code);
6841
0
                    cx += width;
6842
0
                }
6843
0
                if (cx < ex) {
6844
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6845
0
                        ex - cx, h, pdcolor0, pdcolor1);
6846
0
                    if (code < 0)
6847
0
                        return_error(code);
6848
0
                }
6849
0
            }
6850
248
        } else if (icw >= w && shift == 0) {
6851
            /* Narrow operation, no shift */
6852
0
            int ey = y + h;
6853
0
            int fey = ey - height;
6854
0
            int cy = y + ch;
6855
6856
0
            code = pdf14_copy_mono_devn(dev, row, irx, raster,
6857
0
                x, y, w, ch, pdcolor0, pdcolor1);
6858
0
            if (code < 0)
6859
0
                return_error(code);
6860
0
            row = tiles->data;
6861
0
            do {
6862
0
                ch = (cy > fey ? ey - cy : height);
6863
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6864
0
                    x, cy, w, ch, pdcolor0, pdcolor1);
6865
0
                if (code < 0)
6866
0
                    return_error(code);
6867
0
            } while ((cy += ch) < ey);
6868
0
        } else {
6869
            /* Full operation.  If shift != 0, some scan lines */
6870
            /* may be narrow.  We could test shift == 0 in advance */
6871
            /* and use a slightly faster loop, but right now */
6872
            /* we don't bother. */
6873
0
            int ex = x + w, ey = y + h;
6874
0
            int fex = ex - width, fey = ey - height;
6875
0
            int cx, cy;
6876
6877
0
            for (cy = y;;) {
6878
0
                if (icw >= w) {
6879
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6880
0
                        x, cy, w, ch, pdcolor0, pdcolor1);
6881
0
                    if (code < 0)
6882
0
                        return_error(code);
6883
0
                } else {
6884
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6885
0
                        x, cy, icw, ch, pdcolor0, pdcolor1);
6886
0
                    if (code < 0)
6887
0
                        return_error(code);
6888
0
                    cx = x + icw;
6889
0
                    while (cx <= fex) {
6890
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6891
0
                            cx, cy, width, ch, pdcolor0, pdcolor1);
6892
0
                        if (code < 0)
6893
0
                            return_error(code);
6894
0
                        cx += width;
6895
0
                    }
6896
0
                    if (cx < ex) {
6897
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6898
0
                            cx, cy, ex - cx, ch, pdcolor0, pdcolor1);
6899
0
                        if (code < 0)
6900
0
                            return_error(code);
6901
0
                    }
6902
0
                }
6903
0
                if ((cy += ch) >= ey)
6904
0
                    break;
6905
0
                ch = (cy > fey ? ey - cy : height);
6906
0
                if ((irx += shift) >= rwidth)
6907
0
                    irx -= rwidth;
6908
0
                icw = width - irx;
6909
0
                row = tiles->data;
6910
0
            }
6911
0
        }
6912
248
    }
6913
248
    return 0;
6914
248
}
6915
6916
/* pdf14 device supports devn */
6917
static int
6918
pdf14_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6919
    int x, int y, int w, int h,
6920
    const gx_drawing_color *pdcolor0,
6921
    const gx_drawing_color *pdcolor1, int px, int py)
6922
248
{
6923
248
    pdf14_device *pdev = (pdf14_device *)dev;
6924
248
    pdf14_buf *buf;
6925
248
    int num_comp;
6926
248
    int k;
6927
248
    bool same = false;
6928
248
    int code;
6929
6930
248
    code = pdf14_initialize_ctx(dev, NULL);
6931
248
    if (code < 0)
6932
0
        return code;
6933
248
    buf = pdev->ctx->stack;
6934
248
    num_comp = buf->n_chan - 1;
6935
6936
    /* if color0 is identical to color1, do rect fill */
6937
248
    if (pdcolor0->type == gx_dc_type_devn && pdcolor1->type == gx_dc_type_devn) {
6938
0
        same = true;
6939
0
        for (k = 0; k < num_comp; k++) {
6940
0
            if (pdcolor0->colors.devn.values[k] != pdcolor1->colors.devn.values[k]) {
6941
0
                same = false;
6942
0
                break;
6943
0
            }
6944
0
        }
6945
0
    }
6946
6947
248
    if (same) {
6948
0
        code = pdf14_fill_rectangle_devn(dev, x, y, w, h, pdcolor0);
6949
248
    } else {
6950
        /* Go through the tile stepping using code stolen from
6951
           gx_default_strip_tile_rectangle and call the rect fills
6952
           using code stolen from pdf14_copy_mono but using devn
6953
           colors */
6954
248
        code = pdf14_impl_strip_tile_rectangle_devn(dev, tiles,
6955
248
            x, y, w, h, pdcolor0, pdcolor1, px, py);
6956
248
    }
6957
248
    return code;
6958
248
}
6959
6960
/* Used in a few odd cases where the target device is planar and we have
6961
   a planar tile (pattern) and we are copying it into place here */
6962
static int
6963
pdf14_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
6964
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
6965
2.45k
{
6966
2.45k
    pdf14_device *pdev = (pdf14_device *)dev;
6967
2.45k
    pdf14_ctx *ctx;
6968
2.45k
    pdf14_buf *buf;
6969
2.45k
    int xo = x;
6970
2.45k
    int yo = y;
6971
2.45k
    pdf14_buf fake_tos;
6972
2.45k
    int deep;
6973
6974
2.45k
    int code = pdf14_initialize_ctx(dev, NULL);
6975
2.45k
    if (code < 0)
6976
0
        return code;
6977
6978
2.45k
    fit_fill_xywh(dev, x, y, w, h);
6979
2.45k
    if (w <= 0 || h <= 0)
6980
0
        return 0;
6981
6982
2.45k
    ctx = pdev->ctx;
6983
2.45k
    buf = ctx->stack;
6984
2.45k
    deep = ctx->deep;
6985
6986
2.45k
    fake_tos.deep = deep;
6987
2.45k
    fake_tos.alpha = (uint16_t)(0xffff * pdev->alpha + 0.5);
6988
2.45k
    fake_tos.backdrop = NULL;
6989
2.45k
    fake_tos.blend_mode = pdev->blend_mode;
6990
2.45k
    fake_tos.color_space = buf->color_space;
6991
2.45k
    fake_tos.data = (byte *)data + ((data_x - (x - xo))<<deep) - (y - yo) * raster; /* Nasty, cast away of const */
6992
2.45k
    fake_tos.dirty.p.x = x;
6993
2.45k
    fake_tos.dirty.p.y = y;
6994
2.45k
    fake_tos.dirty.q.x = x + w;
6995
2.45k
    fake_tos.dirty.q.y = y + h;
6996
2.45k
    fake_tos.has_alpha_g = 0;
6997
2.45k
    fake_tos.has_shape = 0;
6998
2.45k
    fake_tos.has_tags = device_encodes_tags(dev);
6999
2.45k
    fake_tos.idle = false;
7000
2.45k
    fake_tos.isolated = false;
7001
2.45k
    fake_tos.knockout = false;
7002
2.45k
    fake_tos.mask_id = 0;
7003
2.45k
    fake_tos.mask_stack = NULL;
7004
2.45k
    fake_tos.matte = NULL;
7005
2.45k
    fake_tos.matte_num_comps = 0;
7006
2.45k
    fake_tos.memory = dev->memory;
7007
2.45k
    fake_tos.n_chan = dev->color_info.num_components;
7008
2.45k
    fake_tos.n_planes = dev->color_info.num_components;
7009
2.45k
    fake_tos.num_spots = 0;
7010
2.45k
    fake_tos.group_color_info = NULL;
7011
2.45k
    fake_tos.planestride = raster * (size_t)plane_height;
7012
2.45k
    fake_tos.rect.p.x = x;
7013
2.45k
    fake_tos.rect.p.y = y;
7014
2.45k
    fake_tos.rect.q.x = x + w;
7015
2.45k
    fake_tos.rect.q.y = y + h;
7016
2.45k
    fake_tos.rowstride = raster;
7017
2.45k
    fake_tos.saved = NULL;
7018
2.45k
    fake_tos.shape = 0xffff;
7019
2.45k
    fake_tos.SMask_SubType = TRANSPARENCY_MASK_Alpha;
7020
2.45k
    fake_tos.transfer_fn = NULL;
7021
2.45k
    pdf14_compose_alphaless_group(&fake_tos, buf, x, x+w, y, y+h,
7022
2.45k
                                  pdev->ctx->memory, dev);
7023
2.45k
    return 0;
7024
2.45k
}
7025
7026
static int
7027
pdf14_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
7028
    const gs_gstate *pgs, const gx_drawing_color *pdcolor,
7029
    const gx_clip_path *pcpath)
7030
16.2M
{
7031
16.2M
    pdf14_device *pdev = (pdf14_device *)dev;
7032
16.2M
    pdf14_buf* buf;
7033
16.2M
    int code;
7034
16.2M
    int x = fixed2int(rect->p.x);
7035
16.2M
    int y = fixed2int(rect->p.y);
7036
16.2M
    int w = fixed2int(rect->q.x) - x;
7037
16.2M
    int h = fixed2int(rect->q.y) - y;
7038
7039
16.2M
    fit_fill_xywh(dev, x, y, w, h);
7040
16.2M
    if (w <= 0 || h <= 0)
7041
224k
        return 0;
7042
7043
16.0M
    code = pdf14_initialize_ctx(dev, pgs);
7044
16.0M
    if (code < 0)
7045
0
        return code;
7046
16.0M
    buf = pdev->ctx->stack;
7047
7048
16.0M
    if (buf->knockout)
7049
143k
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
7050
143k
                                                   true);
7051
15.9M
    else
7052
15.9M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
7053
16.0M
}
7054
7055
static  int
7056
pdf14_fill_rectangle(gx_device * dev,
7057
                    int x, int y, int w, int h, gx_color_index color)
7058
290M
{
7059
290M
    pdf14_device *pdev = (pdf14_device *)dev;
7060
290M
    pdf14_buf *buf;
7061
290M
    int code;
7062
7063
290M
    fit_fill_xywh(dev, x, y, w, h);
7064
290M
    if (w <= 0 || h <= 0)
7065
9.22M
        return 0;
7066
7067
281M
    code = pdf14_initialize_ctx(dev, NULL);
7068
281M
    if (code < 0)
7069
0
        return code;
7070
7071
281M
    buf = pdev->ctx->stack;
7072
7073
281M
    if (buf->knockout)
7074
1.63M
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, NULL,
7075
1.63M
                                                   false);
7076
280M
    else
7077
280M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, color, NULL, false);
7078
281M
}
7079
7080
static int
7081
pdf14_compute_group_device_int_rect(const gs_matrix *ctm,
7082
                                    const gs_rect *pbbox, gs_int_rect *rect)
7083
2.00M
{
7084
2.00M
    gs_rect dev_bbox;
7085
2.00M
    int code;
7086
7087
2.00M
    code = gs_bbox_transform(pbbox, ctm, &dev_bbox);
7088
2.00M
    if (code < 0)
7089
0
        return code;
7090
2.00M
    rect->p.x = (int)floor(dev_bbox.p.x);
7091
2.00M
    rect->p.y = (int)floor(dev_bbox.p.y);
7092
2.00M
    rect->q.x = (int)ceil(dev_bbox.q.x);
7093
2.00M
    rect->q.y = (int)ceil(dev_bbox.q.y);
7094
    /* Sanity check rect for insane ctms */
7095
2.00M
    if (rect->p.x < 0)
7096
205k
        rect->p.x = 0;
7097
2.00M
    if (rect->q.x < rect->p.x)
7098
2.22k
        rect->q.x = rect->p.x;
7099
2.00M
    if (rect->p.y < 0)
7100
1.83M
        rect->p.y = 0;
7101
2.00M
    if (rect->q.y < rect->p.y)
7102
38.2k
        rect->q.y = rect->p.y;
7103
2.00M
    return 0;
7104
2.00M
}
7105
7106
static  int
7107
compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
7108
                              const gs_rect *pbbox, gs_gstate *pgs)
7109
1.93M
{
7110
1.93M
    int code = pdf14_compute_group_device_int_rect(&ctm_only(pgs), pbbox, rect);
7111
7112
1.93M
    if (code < 0)
7113
0
        return code;
7114
1.93M
    rect_intersect(*rect, pdev->ctx->rect);
7115
    /* Make sure the rectangle is not anomalous (q < p) -- see gsrect.h */
7116
1.93M
    if (rect->q.x < rect->p.x)
7117
10.4k
        rect->q.x = rect->p.x;
7118
1.93M
    if (rect->q.y < rect->p.y)
7119
34.9k
        rect->q.y = rect->p.y;
7120
1.93M
    return 0;
7121
1.93M
}
7122
7123
static  int
7124
pdf14_begin_transparency_group(gx_device* dev,
7125
    const gs_transparency_group_params_t* ptgp,
7126
    const gs_rect* pbbox,
7127
    gs_gstate* pgs, gs_memory_t* mem)
7128
1.95M
{
7129
1.95M
    pdf14_device* pdev = (pdf14_device*)dev;
7130
1.95M
    float alpha = ptgp->group_opacity * ptgp->group_shape;
7131
1.95M
    gs_int_rect rect;
7132
1.95M
    int code;
7133
1.95M
    bool isolated = ptgp->Isolated;
7134
1.95M
    gs_transparency_color_t group_color_type;
7135
1.95M
    cmm_profile_t* group_profile;
7136
1.95M
    cmm_profile_t* tos_profile;
7137
1.95M
    gsicc_rendering_param_t render_cond;
7138
1.95M
    cmm_dev_profile_t* dev_profile;
7139
1.95M
    bool cm_back_drop = false;
7140
1.95M
    bool new_icc = false;
7141
1.95M
    pdf14_group_color_t* group_color_info;
7142
1.95M
    bool has_tags = device_encodes_tags(dev);
7143
7144
1.95M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7145
1.95M
    if (code < 0)
7146
0
        return code;
7147
1.95M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &tos_profile, &render_cond);
7148
7149
1.95M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
7150
386k
        pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* For immediate mode and clist reading */
7151
386k
    }
7152
7153
1.95M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED)
7154
386k
        rect = pdev->ctx->rect; /* Use parent group for text_group. */
7155
1.56M
    else
7156
1.56M
        code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7157
7158
1.95M
    if (code < 0)
7159
0
        return code;
7160
1.95M
    if_debug5m('v', pdev->memory,
7161
1.95M
        "[v]pdf14_begin_transparency_group, I = %d, K = %d, alpha = %g, bm = %d page_group = %d\n",
7162
1.95M
        ptgp->Isolated, ptgp->Knockout, (double)alpha, pgs->blend_mode, ptgp->page_group);
7163
7164
    /* If the group color is unknown then use the current device profile. */
7165
1.95M
    if (ptgp->group_color_type == UNKNOWN) {
7166
1.58M
        group_color_type = ICC;
7167
1.58M
        group_profile = tos_profile;
7168
1.58M
    }
7169
375k
    else {
7170
375k
        group_color_type = ptgp->group_color_type;
7171
375k
        group_profile = ptgp->iccprofile;
7172
375k
    }
7173
7174
    /* We have to handle case where the profile is in the clist */
7175
1.95M
    if (group_profile == NULL && pdev->pclist_device != NULL) {
7176
        /* Get the serialized data from the clist. */
7177
375k
        gx_device_clist_reader* pcrdev = (gx_device_clist_reader*)(pdev->pclist_device);
7178
375k
        group_profile = gsicc_read_serial_icc((gx_device*)pcrdev, ptgp->icc_hashcode);
7179
375k
        if (group_profile == NULL)
7180
0
            return gs_throw(gs_error_unknownerror, "ICC data not found in clist");
7181
        /* Keep a pointer to the clist device */
7182
375k
        group_profile->dev = (gx_device*)pcrdev;
7183
375k
        new_icc = true;
7184
375k
    }
7185
1.95M
    if (group_profile != NULL) {
7186
        /* If we have a non-isolated group and the color space is different,
7187
            we will need to CM the backdrop. */
7188
1.95M
        if (!gsicc_profiles_equal(group_profile, tos_profile)) {
7189
173k
            cm_back_drop = true;
7190
173k
        }
7191
1.95M
    }
7192
7193
    /* Always create the base color group information as it is only through
7194
       groups that we can have a color space change.  This will survive
7195
       the life of the context. */
7196
1.95M
    if (pdev->ctx->base_color == NULL) {
7197
495k
        pdev->ctx->base_color = pdf14_make_base_group_color(dev);
7198
495k
    }
7199
7200
    /* If this is not the page group and we don't yet have a group, we need
7201
       to create a buffer for the whole page so that we can handle stuff drawn
7202
       outside this current group (e.g. two non inclusive groups drawn independently) */
7203
1.95M
    if (pdev->ctx->stack == NULL && !ptgp->page_group) {
7204
58.0k
        code = pdf14_initialize_ctx(dev, NULL);
7205
58.0k
        if (code < 0)
7206
0
            return code;
7207
58.0k
        pdev->ctx->stack->isolated = true;
7208
58.0k
    }
7209
7210
1.95M
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptgp->icc_hashcode,
7211
1.95M
        group_profile, false);
7212
1.95M
    if (group_color_info == NULL)
7213
0
        return gs_error_VMerror;
7214
1.95M
    if_debug0m('v', dev->memory, "[v]Transparency group color space update\n");
7215
7216
1.95M
    code = pdf14_push_transparency_group(pdev->ctx, &rect, isolated, ptgp->Knockout,
7217
1.95M
                                        (uint16_t)floor (65535 * alpha + 0.5),
7218
1.95M
                                        (uint16_t)floor(65535 * ptgp->group_shape + 0.5),
7219
1.95M
                                        (uint16_t)floor(65535 * ptgp->group_opacity + 0.5),
7220
1.95M
                                        pgs->blend_mode, ptgp->idle,
7221
1.95M
                                         ptgp->mask_id, pdev->color_info.num_components - has_tags,
7222
1.95M
                                         cm_back_drop, ptgp->shade_group,
7223
1.95M
                                         group_profile, tos_profile, group_color_info, pgs, dev);
7224
1.95M
    if (new_icc)
7225
375k
        gsicc_adjust_profile_rc(group_profile, -1, "pdf14_begin_transparency_group");
7226
1.95M
    return code;
7227
1.95M
}
7228
7229
static void
7230
pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color)
7231
1.95M
{
7232
1.95M
    pdf14_device* pdev = (pdf14_device*)dev;
7233
7234
1.95M
    if (group_color != NULL &&
7235
1.95M
        !(group_color->group_color_mapping_procs == NULL &&
7236
1.95M
            group_color->group_color_comp_index == NULL)) {
7237
1.95M
        bool has_tags = device_encodes_tags(dev);
7238
1.95M
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7239
1.95M
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7240
1.95M
        pdev->color_info.polarity = group_color->polarity;
7241
1.95M
        if (pdev->num_planar_planes > 0)
7242
80.4k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7243
1.95M
        pdev->color_info.num_components = group_color->num_components + has_tags;
7244
1.95M
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7245
1.95M
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7246
1.95M
        pdev->blend_procs = group_color->blend_procs;
7247
1.95M
        pdev->ctx->additive = group_color->isadditive;
7248
1.95M
        pdev->pdf14_procs = group_color->unpack_procs;
7249
1.95M
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7250
1.95M
        pdev->color_info.depth = group_color->depth;
7251
1.95M
        pdev->color_info.max_color = group_color->max_color;
7252
1.95M
        pdev->color_info.max_gray = group_color->max_gray;
7253
1.95M
        memcpy(&(pdev->color_info.comp_bits), &(group_color->comp_bits),
7254
1.95M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7255
1.95M
        memcpy(&(pdev->color_info.comp_shift), &(group_color->comp_shift),
7256
1.95M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7257
1.95M
        if (group_color->icc_profile != NULL) {
7258
            /* make sure to decrement the device profile.  If it was allocated
7259
               with the push then it will be freed. */
7260
1.95M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7261
1.95M
                                    -1, "pdf14_pop_color_model");
7262
1.95M
            pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
7263
1.95M
                                    group_color->icc_profile;
7264
7265
1.95M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7266
1.95M
                                    1, "pdf14_pop_color_model");
7267
1.95M
        }
7268
1.95M
        pdev->num_std_colorants = group_color->num_std_colorants;
7269
1.95M
    }
7270
1.95M
}
7271
7272
static  int
7273
pdf14_end_transparency_group(gx_device* dev, gs_gstate* pgs)
7274
1.95M
{
7275
1.95M
    pdf14_device* pdev = (pdf14_device*)dev;
7276
1.95M
    int code;
7277
1.95M
    cmm_profile_t* group_profile;
7278
1.95M
    gsicc_rendering_param_t render_cond;
7279
1.95M
    cmm_dev_profile_t* dev_profile;
7280
1.95M
    int has_tags = device_encodes_tags(dev);
7281
7282
1.95M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7283
1.95M
    if (code < 0)
7284
0
        return code;
7285
7286
1.95M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
7287
1.95M
        &render_cond);
7288
1.95M
    if_debug0m('v', dev->memory, "[v]pdf14_end_transparency_group\n");
7289
7290
1.95M
    code = pdf14_pop_transparency_group(pgs, pdev->ctx, pdev->blend_procs,
7291
1.95M
        pdev->color_info.num_components - has_tags, group_profile, (gx_device*)pdev);
7292
1.95M
    if (code < 0)
7293
0
        return code;
7294
#ifdef DEBUG
7295
    pdf14_debug_mask_stack_state(pdev->ctx);
7296
#endif
7297
    /* If this group is the base group, then restore the color model
7298
       of the device at this time.  Note that during the actual device pop
7299
       we will need to use the profile of the buffer not the pdf14 device
7300
       as the source color space */
7301
1.95M
    if (pdev->ctx->stack->group_popped) {
7302
368k
        pdf14_pop_color_model(dev, pdev->ctx->base_color);
7303
1.58M
    } else {
7304
1.58M
        pdf14_pop_color_model(dev, pdev->ctx->stack->group_color_info);
7305
1.58M
    }
7306
7307
1.95M
    return code;
7308
1.95M
}
7309
7310
static pdf14_group_color_t*
7311
pdf14_push_color_model(gx_device *dev, gs_transparency_color_t group_color_type,
7312
                        int64_t icc_hashcode, cmm_profile_t *iccprofile,
7313
                        bool is_mask)
7314
2.31M
{
7315
2.31M
    pdf14_device *pdevproto = NULL;
7316
2.31M
    pdf14_device *pdev = (pdf14_device *)dev;
7317
2.31M
    const pdf14_procs_t *new_14procs = NULL;
7318
2.31M
    pdf14_group_color_t *group_color;
7319
2.31M
    gx_color_polarity_t new_polarity;
7320
2.31M
    uchar new_num_comps;
7321
2.31M
    bool new_additive;
7322
2.31M
    gx_device_clist_reader *pcrdev;
7323
2.31M
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7324
2.31M
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7325
2.31M
    int k;
7326
2.31M
    bool has_tags = device_encodes_tags(dev);
7327
2.31M
    bool deep = pdev->ctx->deep;
7328
7329
2.31M
    if_debug0m('v', dev->memory, "[v]pdf14_push_color_model\n");
7330
7331
2.31M
    assert(dev->color_info.num_components == dev->num_planar_planes || dev->num_planar_planes == 0);
7332
7333
2.31M
    group_color = gs_alloc_struct(dev->memory->stable_memory,
7334
2.31M
                               pdf14_group_color_t, &st_pdf14_clr,
7335
2.31M
                               "pdf14_push_color_model");
7336
2.31M
    if (group_color == NULL)
7337
0
        return NULL;
7338
7339
2.31M
    memset(group_color, 0, sizeof(pdf14_group_color_t));
7340
7341
2.31M
    switch (group_color_type) {
7342
0
        case GRAY_SCALE:
7343
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7344
0
            new_num_comps = 1;
7345
0
            pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7346
0
            new_additive = true;
7347
0
            new_14procs = &gray_pdf14_procs;
7348
0
            break;
7349
0
        case DEVICE_RGB:
7350
0
        case CIE_XYZ:
7351
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7352
0
            new_num_comps = 3;
7353
0
            pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7354
0
            new_additive = true;
7355
0
            new_14procs = &rgb_pdf14_procs;
7356
0
            break;
7357
0
        case DEVICE_CMYK:
7358
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7359
0
            new_num_comps = 4;
7360
0
            pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7361
0
            new_additive = false;
7362
            /* This is needed due to the mismatched compressed encode decode
7363
                between the device procs and the pdf14 procs */
7364
0
            if (dev->color_info.num_components > 4){
7365
0
                new_14procs = &cmykspot_pdf14_procs;
7366
0
            } else {
7367
0
                new_14procs = &cmyk_pdf14_procs;
7368
0
            }
7369
0
            break;
7370
2.31M
        case ICC:
7371
            /* If we are coming from the clist reader, then we need to get
7372
                the ICC data now  */
7373
2.31M
            if (iccprofile == NULL && pdev->pclist_device != NULL) {
7374
                /* Get the serialized data from the clist.  Not the whole
7375
                    profile. */
7376
358k
                pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
7377
358k
                iccprofile = gsicc_read_serial_icc((gx_device *) pcrdev,
7378
358k
                                                    icc_hashcode);
7379
358k
                if (iccprofile == NULL)
7380
0
                    return NULL;
7381
                /* Keep a pointer to the clist device */
7382
358k
                iccprofile->dev = (gx_device *) pcrdev;
7383
1.96M
            } else {
7384
                /* Go ahead and rc increment right now.  This way when
7385
                    we pop, we will make sure to decrement and avoid a
7386
                    leak for the above profile that we just created.  This
7387
                    goes with the assignment to the device's profile.
7388
                    Note that we still do the increment for the group_color
7389
                    assignment below. */
7390
1.96M
                if (iccprofile == NULL)
7391
0
                    return NULL;
7392
1.96M
                gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7393
1.96M
            }
7394
2.31M
            new_num_comps = iccprofile->num_comps;
7395
2.31M
            if (new_num_comps == 4) {
7396
216k
                new_additive = false;
7397
216k
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7398
2.10M
            } else {
7399
2.10M
                new_additive = true;
7400
2.10M
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7401
2.10M
            }
7402
2.31M
            switch (new_num_comps) {
7403
542k
                case 1:
7404
542k
                    if (pdev->sep_device && !is_mask) {
7405
0
                        pdevproto = (pdf14_device *)&gs_pdf14_Grayspot_device;
7406
0
                        new_14procs = &grayspot_pdf14_procs;
7407
542k
                    } else {
7408
542k
                        pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7409
542k
                        new_14procs = &gray_pdf14_procs;
7410
542k
                    }
7411
542k
                    break;
7412
1.55M
                case 3:
7413
1.55M
                    if (pdev->sep_device) {
7414
58.4k
                        pdevproto = (pdf14_device *)&gs_pdf14_RGBspot_device;
7415
58.4k
                        new_14procs = &rgbspot_pdf14_procs;
7416
58.4k
                    }
7417
1.50M
                    else {
7418
1.50M
                        pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7419
1.50M
                        new_14procs = &rgb_pdf14_procs;
7420
1.50M
                    }
7421
1.55M
                    break;
7422
216k
                case 4:
7423
216k
                    if (pdev->sep_device) {
7424
21.9k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYKspot_device;
7425
21.9k
                        new_14procs = &cmykspot_pdf14_procs;
7426
194k
                    } else {
7427
194k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7428
194k
                        new_14procs = &cmyk_pdf14_procs;
7429
194k
                    }
7430
216k
                    break;
7431
0
                default:
7432
0
                    return NULL;
7433
0
                    break;
7434
2.31M
            }
7435
2.31M
            break;
7436
2.31M
        default:
7437
0
            return NULL;
7438
0
            break;
7439
2.31M
    }
7440
7441
    /* We might just have changed the colorspace of the device, which means
7442
     * the number of colorants have changed. */
7443
2.31M
    group_color->num_std_colorants = new_num_comps;
7444
2.31M
    pdev->num_std_colorants = new_num_comps;
7445
7446
2.31M
    if (has_tags)
7447
0
        new_num_comps++;
7448
7449
2.31M
    if (group_color_type == ICC && iccprofile != NULL) {
7450
2.31M
        group_color->icc_profile = iccprofile;
7451
2.31M
        gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7452
2.31M
    }
7453
7454
    /* If we are a sep device and this is not a softmask, ensure we maintain the
7455
       spot colorants and know how to index into them */
7456
2.31M
    if (pdev->sep_device && !is_mask) {
7457
80.4k
        int num_spots = dev->color_info.num_components - has_tags -
7458
80.4k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps;
7459
7460
80.4k
        if (num_spots > 0)
7461
383
            new_num_comps += num_spots;
7462
80.4k
    }
7463
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7464
8.40M
    for (k = 0; k < new_num_comps; k++) {
7465
6.08M
        comp_bits[k] = 8<<deep;
7466
6.08M
        comp_shift[k] = (new_num_comps - k - 1) * (8<<deep);
7467
6.08M
    }
7468
7469
    /* Set device values now and store settings in group_color.  Then they
7470
       are available when we pop the previous group */
7471
2.31M
    if_debug2m('v', pdev->memory,
7472
2.31M
                "[v]pdf14_push_color_model, num_components_old = %d num_components_new = %d\n",
7473
2.31M
                pdev->color_info.num_components,new_num_comps);
7474
2.31M
    {
7475
2.31M
        gx_device local_device;
7476
7477
2.31M
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7478
2.31M
        local_device.initialize_device_procs((gx_device *)&local_device);
7479
2.31M
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7480
2.31M
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7481
2.31M
    }
7482
2.31M
    group_color->blend_procs = pdev->blend_procs = pdevproto->blend_procs;
7483
2.31M
    group_color->polarity = pdev->color_info.polarity = new_polarity;
7484
2.31M
    group_color->isadditive = pdev->ctx->additive = new_additive;
7485
2.31M
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7486
2.31M
    group_color->unpack_procs = pdev->pdf14_procs = new_14procs;
7487
2.31M
    if (pdev->num_planar_planes > 0)
7488
107k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7489
2.31M
    group_color->num_components = new_num_comps - has_tags;
7490
2.31M
    pdev->color_info.num_components = new_num_comps;
7491
2.31M
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7492
2.31M
    assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7493
2.31M
    pdev->color_info.depth = new_num_comps * (8<<deep);
7494
2.31M
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7495
2.31M
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7496
2.31M
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7497
2.31M
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7498
2.31M
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
7499
2.31M
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
7500
2.31M
    group_color->depth = pdev->color_info.depth;
7501
2.31M
    group_color->decode = dev_proc(pdev, decode_color);
7502
2.31M
    group_color->encode = dev_proc(pdev, encode_color);
7503
2.31M
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
7504
2.31M
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
7505
2.31M
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
7506
2.31M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7507
2.31M
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
7508
2.31M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7509
2.31M
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
7510
7511
    /* If the CS was ICC based, we need to update the device ICC profile
7512
        in the ICC manager, since that is the profile that is used for the
7513
        PDF14 device */
7514
2.31M
    if (group_color_type == ICC && iccprofile != NULL) {
7515
        /* iccprofile was incremented above if we had not just created it.
7516
           When we do the pop we will decrement and if we just created it, it
7517
           will be destroyed */
7518
2.31M
        gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_push_color_model");
7519
2.31M
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = iccprofile;
7520
2.31M
    }
7521
2.31M
    return group_color;
7522
2.31M
}
7523
7524
static int
7525
pdf14_clist_push_color_model(gx_device *dev, gx_device* cdev, gs_gstate *pgs,
7526
                             const gs_pdf14trans_t *pdf14pct, gs_memory_t* mem,
7527
                             bool is_mask)
7528
51.8k
{
7529
51.8k
    pdf14_device* pdev = (pdf14_device*)dev;
7530
51.8k
    pdf14_group_color_t* new_group_color;
7531
51.8k
    gsicc_rendering_param_t render_cond;
7532
51.8k
    cmm_dev_profile_t* dev_profile;
7533
51.8k
    pdf14_device* pdevproto;
7534
51.8k
    gx_device_clist_writer* cldev = (gx_device_clist_writer*)pdev->pclist_device;
7535
51.8k
    const pdf14_procs_t* new_14procs;
7536
51.8k
    bool update_color_info;
7537
51.8k
    gx_color_polarity_t new_polarity;
7538
51.8k
    int new_num_comps;
7539
51.8k
    bool new_additive = false;
7540
51.8k
    byte new_depth;
7541
51.8k
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7542
51.8k
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7543
51.8k
    int k;
7544
51.8k
    bool has_tags = device_encodes_tags(dev);
7545
51.8k
    bool deep = device_is_deep(dev);
7546
51.8k
    gs_transparency_color_t group_color_type = pdf14pct->params.group_color_type;
7547
51.8k
    cmm_profile_t *new_profile = pdf14pct->params.iccprofile;
7548
51.8k
    cmm_profile_t *old_profile = NULL;
7549
7550
51.8k
    assert(dev->num_planar_planes == 0 || dev->num_planar_planes == dev->color_info.num_components);
7551
7552
51.8k
    dev_proc(dev, get_profile)(dev, &dev_profile);
7553
51.8k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &old_profile,
7554
51.8k
        &render_cond);
7555
51.8k
    if_debug0m('v', dev->memory, "[v]pdf14_clist_push_color_model\n");
7556
7557
    /* Allocate a new one */
7558
51.8k
    new_group_color = gs_alloc_struct(dev->memory->stable_memory, pdf14_group_color_t,
7559
51.8k
        &st_pdf14_clr, "pdf14_clist_push_color_model");
7560
7561
51.8k
    if (new_group_color == NULL)
7562
0
        return_error(gs_error_VMerror);
7563
7564
    /* Link to old one */
7565
51.8k
    new_group_color->previous = pdev->color_model_stack;
7566
7567
    /* Reassign new one to dev */
7568
51.8k
    pdev->color_model_stack = new_group_color;
7569
7570
    /* Initialize with values */
7571
51.8k
    new_group_color->get_cmap_procs = pgs->get_cmap_procs;
7572
51.8k
    new_group_color->group_color_mapping_procs =
7573
51.8k
        dev_proc(pdev, get_color_mapping_procs);
7574
51.8k
    new_group_color->group_color_comp_index =
7575
51.8k
        dev_proc(pdev, get_color_comp_index);
7576
51.8k
    new_group_color->blend_procs = pdev->blend_procs;
7577
51.8k
    new_group_color->polarity = pdev->color_info.polarity;
7578
51.8k
    new_group_color->num_components = pdev->color_info.num_components - has_tags;
7579
51.8k
    new_group_color->unpack_procs = pdev->pdf14_procs;
7580
51.8k
    new_group_color->depth = pdev->color_info.depth;
7581
51.8k
    new_group_color->max_color = pdev->color_info.max_color;
7582
51.8k
    new_group_color->max_gray = pdev->color_info.max_gray;
7583
51.8k
    new_group_color->decode = dev_proc(pdev, decode_color);
7584
51.8k
    new_group_color->encode = dev_proc(pdev, encode_color);
7585
51.8k
    memcpy(&(new_group_color->comp_bits), &(pdev->color_info.comp_bits),
7586
51.8k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7587
51.8k
    memcpy(&(new_group_color->comp_shift), &(pdev->color_info.comp_shift),
7588
51.8k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7589
7590
51.8k
    if (new_profile == NULL)
7591
31.7k
        new_group_color->icc_profile = NULL;
7592
7593
    /* isadditive is only used in ctx */
7594
51.8k
    if (pdev->ctx) {
7595
0
        new_group_color->isadditive = pdev->ctx->additive;
7596
0
    }
7597
7598
51.8k
    memset(comp_bits, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7599
51.8k
    memset(comp_shift, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7600
7601
51.8k
    if (group_color_type == ICC && new_profile == NULL)
7602
0
        return gs_throw(gs_error_undefinedresult, "Missing ICC data");
7603
51.8k
    if_debug0m('v', cldev->memory, "[v]pdf14_clist_push_color_model\n");
7604
    /* Check if we need to alter the device procs at this stage.  Many of the procs
7605
       are based upon the color space of the device.  We want to remain in the
7606
       color space defined by the color space of the soft mask or transparency
7607
       group as opposed to the device color space. Later, when we pop the softmask
7608
       we will collapse it to a single band and then compose with it to the device
7609
       color space (or the parent layer space).  In the case where we pop an
7610
       isolated transparency group, we will do the blending in the proper color
7611
       space and then transform the data when we pop the group.  Remember that only
7612
       isolated groups can have color spaces that are different than their parent. */
7613
51.8k
    update_color_info = false;
7614
51.8k
    switch (group_color_type) {
7615
0
    case GRAY_SCALE:
7616
0
        if (pdev->color_info.num_components != 1) {
7617
0
            update_color_info = true;
7618
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7619
0
            new_num_comps = 1;
7620
0
            pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7621
0
            new_additive = true;
7622
0
            new_14procs = &gray_pdf14_procs;
7623
0
            new_depth = 8 << deep;
7624
0
        }
7625
0
        break;
7626
0
    case DEVICE_RGB:
7627
0
    case CIE_XYZ:
7628
0
        if (pdev->color_info.num_components != 3) {
7629
0
            update_color_info = true;
7630
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7631
0
            new_num_comps = 3;
7632
0
            pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7633
0
            new_additive = true;
7634
0
            new_14procs = &rgb_pdf14_procs;
7635
0
            new_depth = 24 << deep;
7636
0
        }
7637
0
        break;
7638
0
    case DEVICE_CMYK:
7639
0
        if (pdev->color_info.num_components != 4) {
7640
0
            update_color_info = true;
7641
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7642
0
            new_num_comps = 4;
7643
0
            pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7644
0
            new_additive = false;
7645
            /* This is needed due to the mismatched compressed encode decode
7646
               between the device procs and the pdf14 procs */
7647
0
            if (dev->color_info.num_components > 4) {
7648
0
                new_14procs = &cmykspot_pdf14_procs;
7649
0
            }
7650
0
            else {
7651
0
                new_14procs = &cmyk_pdf14_procs;
7652
0
            }
7653
0
            new_depth = 32 << deep;
7654
0
        }
7655
0
        break;
7656
20.1k
    case ICC:
7657
        /* Check if the profile is different. */
7658
20.1k
        if (!gsicc_profiles_equal(old_profile, new_profile)) {
7659
18.3k
            update_color_info = true;
7660
18.3k
            new_num_comps = new_profile->num_comps;
7661
18.3k
            new_depth = new_profile->num_comps * (8 << deep);
7662
18.3k
            switch (new_num_comps) {
7663
16.3k
            case 1:
7664
16.3k
                if (pdev->sep_device && !is_mask) {
7665
0
                    pdevproto = (pdf14_device*)&gs_pdf14_Grayspot_device;
7666
0
                    new_14procs = &grayspot_pdf14_procs;
7667
0
                }
7668
16.3k
                else {
7669
16.3k
                    pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7670
16.3k
                    new_14procs = &gray_pdf14_procs;
7671
16.3k
                }
7672
16.3k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7673
16.3k
                new_additive = true;
7674
16.3k
                break;
7675
1.78k
            case 3:
7676
1.78k
                if (pdev->sep_device) {
7677
505
                    pdevproto = (pdf14_device*)&gs_pdf14_RGBspot_device;
7678
505
                    new_14procs = &rgbspot_pdf14_procs;
7679
505
                }
7680
1.28k
                else {
7681
1.28k
                    pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7682
1.28k
                    new_14procs = &rgb_pdf14_procs;
7683
1.28k
                }
7684
1.78k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7685
1.78k
                new_additive = true;
7686
1.78k
                break;
7687
227
            case 4:
7688
227
                if (pdev->sep_device) {
7689
7
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYKspot_device;
7690
7
                    new_14procs = &cmykspot_pdf14_procs;
7691
7
                }
7692
220
                else {
7693
220
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7694
220
                    new_14procs = &cmyk_pdf14_procs;
7695
220
                }
7696
227
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7697
227
                new_additive = false;
7698
227
                break;
7699
0
            default:
7700
0
                return gs_throw(gs_error_undefinedresult,
7701
18.3k
                    "ICC Number of colorants illegal");
7702
18.3k
            }
7703
18.3k
        }
7704
20.1k
        break;
7705
31.7k
    case UNKNOWN:
7706
31.7k
        return 0;
7707
0
        break;
7708
0
    default:
7709
0
        return_error(gs_error_rangecheck);
7710
0
        break;
7711
51.8k
    }
7712
7713
20.1k
    if (!update_color_info) {
7714
        /* Profile not updated */
7715
1.81k
        new_group_color->icc_profile = NULL;
7716
1.81k
        if_debug0m('v', pdev->memory, "[v]procs not updated\n");
7717
1.81k
        return 0;
7718
1.81k
    }
7719
7720
18.3k
    if (has_tags) {
7721
0
        new_num_comps++;
7722
        /* In planar mode, planes need to all be the same depth. Otherwise use 8 bits for tags. */
7723
0
        if (pdev->num_planar_planes > 0)
7724
0
            new_depth += deep ? 16 : 8;
7725
0
        else
7726
0
            new_depth += 8;
7727
0
    }
7728
18.3k
    if (pdev->sep_device && !is_mask) {
7729
512
        int num_spots;
7730
7731
512
        if (old_profile == NULL)
7732
0
            return_error(gs_error_undefined);
7733
7734
512
        num_spots = pdev->color_info.num_components - has_tags - old_profile->num_comps;
7735
7736
512
        if (num_spots > 0) {
7737
46
            new_num_comps += num_spots;
7738
46
            new_depth = (8 << deep) * new_num_comps;
7739
46
        }
7740
512
    }
7741
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7742
40.9k
    for (k = 0; k < new_num_comps; k++) {
7743
22.6k
        comp_bits[k] = 8 << deep;
7744
22.6k
        comp_shift[k] = (new_num_comps - 1 - k) * (8 << deep);
7745
22.6k
    }
7746
18.3k
    if_debug2m('v', pdev->memory,
7747
18.3k
        "[v]pdf14_clist_push_color_model, num_components_old = %d num_components_new = %d\n",
7748
18.3k
        pdev->color_info.num_components, new_num_comps);
7749
    /* Set new information in the device */
7750
18.3k
    {
7751
18.3k
        gx_device local_device;
7752
7753
18.3k
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7754
18.3k
        local_device.initialize_device_procs((gx_device *)&local_device);
7755
18.3k
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7756
18.3k
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7757
18.3k
    }
7758
18.3k
    pdev->blend_procs = pdevproto->blend_procs;
7759
18.3k
    pdev->color_info.polarity = new_polarity;
7760
18.3k
    pdev->color_info.max_color = deep ? 65535 : 255;
7761
18.3k
    pdev->color_info.max_gray = deep ? 65535 : 255;
7762
18.3k
    pdev->pdf14_procs = new_14procs;
7763
18.3k
    if (pdev->num_planar_planes > 0)
7764
2.67k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7765
18.3k
    pdev->color_info.num_components = new_num_comps;
7766
18.3k
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7767
18.3k
    pdev->color_info.depth = new_depth;
7768
18.3k
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7769
18.3k
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7770
18.3k
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7771
18.3k
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7772
18.3k
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7773
7774
    /* If we have a compressed color codec, and we are doing a soft mask
7775
       push operation then go ahead and update the color encode and
7776
       decode for the pdf14 device to not used compressed color
7777
       encoding while in the soft mask.  We will just check for gray
7778
       and compressed.  Note that we probably don't have_tags if we
7779
       are dealing with compressed color.  But is is possible so
7780
       we add it in to catch for future use. */
7781
18.3k
    cldev->clist_color_info.depth = pdev->color_info.depth;
7782
18.3k
    cldev->clist_color_info.polarity = pdev->color_info.polarity;
7783
18.3k
    cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7784
18.3k
    cldev->clist_color_info.num_components = pdev->color_info.num_components;
7785
18.3k
    cldev->clist_color_info.max_color = pdev->color_info.max_color;
7786
18.3k
    cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7787
    /* For the ICC profiles, we want to update the ICC profile for the
7788
       device.  We store the original in group_color.
7789
       That will be stored in the clist and restored during the reading phase. */
7790
18.3k
    if (group_color_type == ICC) {
7791
18.3k
        gsicc_adjust_profile_rc(new_profile, 1, "pdf14_clist_push_color_model");
7792
18.3k
        new_group_color->icc_profile =
7793
18.3k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
7794
18.3k
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = new_profile;
7795
18.3k
    }
7796
18.3k
    if (pdev->ctx) {
7797
0
        pdev->ctx->additive = new_additive;
7798
0
    }
7799
18.3k
    return 1;  /* Lets us detect that we did do an update */
7800
18.3k
}
7801
7802
static int
7803
pdf14_clist_pop_color_model(gx_device *dev, gs_gstate *pgs)
7804
51.8k
{
7805
7806
51.8k
    pdf14_device *pdev = (pdf14_device *)dev;
7807
51.8k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7808
51.8k
    gx_device_clist_writer * cldev = (gx_device_clist_writer *)pdev->pclist_device;
7809
7810
51.8k
    if (group_color == NULL)
7811
0
        return_error(gs_error_Fatal);  /* Unmatched group pop */
7812
7813
51.8k
    if_debug0m('v', pdev->memory, "[v]pdf14_clist_pop_color_model\n");
7814
    /* The color procs are always pushed.  Simply restore them. */
7815
51.8k
    if (group_color->group_color_mapping_procs == NULL &&
7816
0
        group_color->group_color_comp_index == NULL) {
7817
0
        if_debug0m('v', dev->memory, "[v]pdf14_clist_pop_color_model ERROR \n");
7818
51.8k
    } else {
7819
51.8k
        bool has_tags = device_encodes_tags(dev);
7820
51.8k
        if_debug2m('v', pdev->memory,
7821
51.8k
                   "[v]pdf14_clist_pop_color_model, num_components_old = %d num_components_new = %d\n",
7822
51.8k
                   pdev->color_info.num_components,group_color->num_components);
7823
51.8k
        pgs->get_cmap_procs = group_color->get_cmap_procs;
7824
51.8k
        gx_set_cmap_procs(pgs, dev);
7825
51.8k
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7826
51.8k
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7827
51.8k
        pdev->color_info.polarity = group_color->polarity;
7828
51.8k
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7829
51.8k
        pdev->color_info.depth = group_color->depth;
7830
51.8k
        if (pdev->num_planar_planes > 0)
7831
6.42k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7832
51.8k
        pdev->color_info.num_components = group_color->num_components + has_tags;
7833
51.8k
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7834
51.8k
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7835
51.8k
        pdev->blend_procs = group_color->blend_procs;
7836
51.8k
        pdev->pdf14_procs = group_color->unpack_procs;
7837
51.8k
        pdev->color_info.max_color = group_color->max_color;
7838
51.8k
        pdev->color_info.max_gray = group_color->max_gray;
7839
51.8k
        set_dev_proc(pdev, encode_color, group_color->encode);
7840
51.8k
        set_dev_proc(pdev, decode_color, group_color->decode);
7841
51.8k
        memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
7842
51.8k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7843
51.8k
        memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
7844
51.8k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7845
7846
        /* clist writer fill rect has no access to gs_gstate */
7847
        /* and it forwards the target device.  this information */
7848
        /* is passed along to use in this case */
7849
51.8k
        cldev->clist_color_info.depth = pdev->color_info.depth;
7850
51.8k
        cldev->clist_color_info.polarity = pdev->color_info.polarity;
7851
51.8k
        cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7852
51.8k
        cldev->clist_color_info.num_components = pdev->color_info.num_components;
7853
51.8k
        cldev->clist_color_info.max_color = pdev->color_info.max_color;
7854
51.8k
        cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7855
51.8k
        memcpy(&(cldev->clist_color_info.comp_bits),&(group_color->comp_bits),
7856
51.8k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7857
51.8k
        memcpy(&(cldev->clist_color_info.comp_shift),&(group_color->comp_shift),
7858
51.8k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7859
51.8k
        if (pdev->ctx){
7860
0
            pdev->ctx->additive = group_color->isadditive;
7861
0
        }
7862
       /* The device profile must be restored. */
7863
51.8k
        if (group_color->icc_profile != NULL) {
7864
18.3k
            gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7865
18.3k
                                    -1, "pdf14_clist_pop_color_model");
7866
18.3k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
7867
18.3k
        }
7868
51.8k
        if_debug0m('v', dev->memory, "[v]procs updated\n");
7869
51.8k
    }
7870
51.8k
   pdf14_pop_group_color(dev, pgs);
7871
51.8k
    return 0;
7872
51.8k
}
7873
7874
/* When a transparency group is popped, the parent colorprocs must be restored.
7875
   Since the color mapping procs are all based upon the device, we must have a
7876
   nested list based upon the transparency group color space.  This nesting
7877
   must be outside the nested ctx structures to allow the nesting for the
7878
   clist writer */
7879
static void
7880
pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs)
7881
51.8k
{
7882
51.8k
    pdf14_device *pdev = (pdf14_device *)dev;
7883
51.8k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7884
7885
51.8k
    if_debug0m('v', dev->memory, "[v]pdf14_pop_group_color\n");
7886
7887
    /* Update the link */
7888
51.8k
    pdev->color_model_stack = group_color->previous;
7889
7890
    /* Free the old one */
7891
51.8k
    gs_free_object(dev->memory->stable_memory, group_color, "pdf14_clr_free");
7892
51.8k
}
7893
7894
static  int
7895
pdf14_begin_transparency_mask(gx_device *dev,
7896
                              const gx_transparency_mask_params_t *ptmp,
7897
                              const gs_rect *pbbox,
7898
                              gs_gstate *pgs, gs_memory_t *mem)
7899
3.56M
{
7900
3.56M
    pdf14_device *pdev = (pdf14_device *)dev;
7901
3.56M
    uint16_t bg_alpha = 0;   /* By default the background alpha (area outside mask) is zero */
7902
3.56M
    byte *transfer_fn;
7903
3.56M
    gs_int_rect rect;
7904
3.56M
    int code;
7905
3.56M
    int group_color_numcomps;
7906
3.56M
    gs_transparency_color_t group_color_type;
7907
3.56M
    bool deep = device_is_deep(dev);
7908
3.56M
    pdf14_group_color_t* group_color_info;
7909
7910
3.56M
    code = pdf14_initialize_ctx(dev, pgs);
7911
3.56M
    if (code < 0)
7912
0
        return code;
7913
7914
3.56M
    if (ptmp->subtype == TRANSPARENCY_MASK_None) {
7915
3.20M
        pdf14_ctx *ctx = pdev->ctx;
7916
7917
        /* free up any maskbuf on the current tos */
7918
3.20M
        if (ctx->mask_stack != NULL && ctx->mask_stack->mask_buf != NULL ) {
7919
268k
            pdf14_buf_free(ctx->mask_stack->mask_buf);
7920
268k
            ctx->mask_stack->mask_buf = NULL;
7921
268k
        }
7922
3.20M
        return 0;
7923
3.20M
    }
7924
361k
    transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, (256+deep)<<deep,
7925
361k
                                         "pdf14_begin_transparency_mask");
7926
361k
    if (transfer_fn == NULL)
7927
0
        return_error(gs_error_VMerror);
7928
361k
    code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7929
361k
    if (code < 0)
7930
0
        return code;
7931
    /* If we have background components the background alpha may be nonzero */
7932
361k
    if (ptmp->Background_components)
7933
57.1k
        bg_alpha = (int)(65535 * ptmp->GrayBackground + 0.5);
7934
361k
    if_debug1m('v', dev->memory,
7935
361k
               "pdf14_begin_transparency_mask, bg_alpha = %d\n", bg_alpha);
7936
361k
    memcpy(transfer_fn, ptmp->transfer_fn, (256+deep)<<deep);
7937
   /* If the group color is unknown, then we must use the previous group color
7938
       space or the device process color space */
7939
361k
    if (ptmp->group_color_type == UNKNOWN){
7940
0
        if (pdev->ctx->stack){
7941
            /* Use previous group color space */
7942
0
            group_color_numcomps = pdev->ctx->stack->n_chan-1;  /* Remove alpha */
7943
0
        } else {
7944
            /* Use process color space */
7945
0
            group_color_numcomps = pdev->color_info.num_components;
7946
0
        }
7947
0
        switch (group_color_numcomps) {
7948
0
            case 1:
7949
0
                group_color_type = GRAY_SCALE;
7950
0
                break;
7951
0
            case 3:
7952
0
                group_color_type = DEVICE_RGB;
7953
0
                break;
7954
0
            case 4:
7955
0
                group_color_type = DEVICE_CMYK;
7956
0
            break;
7957
0
            default:
7958
                /* We can end up here if we are in a deviceN color space and
7959
                   we have a sep output device */
7960
0
                group_color_type = DEVICEN;
7961
0
            break;
7962
0
         }
7963
361k
    } else {
7964
361k
        group_color_type = ptmp->group_color_type;
7965
361k
        group_color_numcomps = ptmp->group_color_numcomps;
7966
361k
    }
7967
7968
361k
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptmp->icc_hashcode,
7969
361k
                                               ptmp->iccprofile, true);
7970
361k
    if (group_color_info == NULL)
7971
0
        return gs_error_VMerror;
7972
7973
    /* Note that the soft mask always follows the group color requirements even
7974
       when we have a separable device */
7975
361k
    code = pdf14_push_transparency_mask(pdev->ctx, &rect, bg_alpha,
7976
361k
                                        transfer_fn, ptmp->function_is_identity,
7977
361k
                                        ptmp->idle, ptmp->replacing,
7978
361k
                                        ptmp->mask_id, ptmp->subtype,
7979
361k
                                        group_color_numcomps,
7980
361k
                                        ptmp->Background_components,
7981
361k
                                        ptmp->Background,
7982
361k
                                        ptmp->Matte_components,
7983
361k
                                        ptmp->Matte,
7984
361k
                                        ptmp->GrayBackground,
7985
361k
                                        group_color_info);
7986
361k
    if (code < 0)
7987
0
        return code;
7988
7989
361k
    return 0;
7990
361k
}
7991
7992
static  int
7993
pdf14_end_transparency_mask(gx_device *dev, gs_gstate *pgs)
7994
361k
{
7995
361k
    pdf14_device *pdev = (pdf14_device *)dev;
7996
361k
    pdf14_group_color_t *group_color;
7997
361k
    int ok;
7998
361k
    bool has_tags = device_encodes_tags(dev);
7999
8000
361k
    if_debug0m('v', dev->memory, "pdf14_end_transparency_mask\n");
8001
361k
    ok = pdf14_pop_transparency_mask(pdev->ctx, pgs, dev);
8002
#ifdef DEBUG
8003
    pdf14_debug_mask_stack_state(pdev->ctx);
8004
#endif
8005
8006
    /* May need to reset some color stuff related
8007
     * to a mismatch between the Smask color space
8008
     * and the Smask blending space */
8009
361k
    if (pdev->ctx->stack != NULL ) {
8010
361k
        group_color = pdev->ctx->stack->group_color_info;
8011
361k
        if (!(group_color->group_color_mapping_procs == NULL &&
8012
361k
            group_color->group_color_comp_index == NULL)) {
8013
361k
            pgs->get_cmap_procs = group_color->get_cmap_procs;
8014
361k
            gx_set_cmap_procs(pgs, dev);
8015
361k
            set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
8016
361k
            set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
8017
361k
            pdev->color_info.polarity = group_color->polarity;
8018
361k
            pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
8019
361k
            if (pdev->num_planar_planes > 0)
8020
26.7k
                pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
8021
361k
            pdev->color_info.num_components = group_color->num_components + has_tags;
8022
361k
            assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
8023
361k
            assert(pdev->color_info.num_components - has_tags == group_color->num_components);
8024
361k
            pdev->num_std_colorants = group_color->num_std_colorants;
8025
361k
            pdev->color_info.depth = group_color->depth;
8026
361k
            pdev->blend_procs = group_color->blend_procs;
8027
361k
            pdev->ctx->additive = group_color->isadditive;
8028
361k
            pdev->pdf14_procs = group_color->unpack_procs;
8029
361k
            pdev->color_info.max_color = group_color->max_color;
8030
361k
            pdev->color_info.max_gray = group_color->max_gray;
8031
361k
            set_dev_proc(pdev, encode_color, group_color->encode);
8032
361k
            set_dev_proc(pdev, decode_color, group_color->decode);
8033
361k
            memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
8034
361k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8035
361k
            memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
8036
361k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8037
            /* Take care of the ICC profile */
8038
361k
            if (group_color->icc_profile != NULL) {
8039
361k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8040
361k
                                        -1, "pdf14_end_transparency_mask");
8041
361k
                dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
8042
361k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8043
361k
                                         1, "pdf14_end_transparency_mask");
8044
361k
            }
8045
361k
        }
8046
361k
    }
8047
361k
    return ok;
8048
361k
}
8049
8050
static  int
8051
do_mark_fill_rectangle_ko_simple(gx_device *dev, int x, int y, int w, int h,
8052
                                 gx_color_index color,
8053
                                 const gx_device_color *pdc, bool devn)
8054
1.77M
{
8055
1.77M
    pdf14_device *pdev = (pdf14_device *)dev;
8056
1.77M
    pdf14_buf *buf = pdev->ctx->stack;
8057
1.77M
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8058
1.77M
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8059
138k
        blend_mode == BLEND_MODE_Compatible ||
8060
138k
        blend_mode == BLEND_MODE_CompatibleOverprint;
8061
1.77M
    int i, j, k;
8062
1.77M
    byte *bline, *bg_ptr, *line, *dst_ptr;
8063
1.77M
    byte src[PDF14_MAX_PLANES];
8064
1.77M
    byte dst[PDF14_MAX_PLANES] = { 0 };
8065
1.77M
    byte dst2[PDF14_MAX_PLANES] = { 0 };
8066
1.77M
    intptr_t rowstride = buf->rowstride;
8067
1.77M
    intptr_t planestride = buf->planestride;
8068
1.77M
    int num_chan = buf->n_chan;
8069
1.77M
    int num_comp = num_chan - 1;
8070
1.77M
    intptr_t shape_off = num_chan * planestride;
8071
1.77M
    bool has_shape = buf->has_shape;
8072
1.77M
    bool has_alpha_g = buf->has_alpha_g;
8073
1.77M
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8074
1.77M
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8075
1.77M
                                   (has_shape ? planestride : 0);
8076
1.77M
    bool has_tags = buf->has_tags;
8077
1.77M
    bool additive = pdev->ctx->additive;
8078
1.77M
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8079
1.77M
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
8080
1.77M
    int shift = 8;
8081
1.77M
    byte shape = 0; /* Quiet compiler. */
8082
1.77M
    byte src_alpha;
8083
1.77M
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8084
1.77M
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
8085
1.45M
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8086
1.77M
    gx_color_index comps;
8087
1.77M
    bool has_backdrop = buf->backdrop != NULL;
8088
8089
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8090
       subtractive) and we are doing overprint with drawn_comps == 0
8091
       then this is a no-operation */
8092
1.77M
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8093
0
        return 0;
8094
8095
1.77M
    if (buf->data == NULL)
8096
2
        return 0;
8097
#if 0
8098
    if (sizeof(color) <= sizeof(ulong))
8099
        if_debug6m('v', dev->memory,
8100
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %lx, nc %d,\n",
8101
                   x, y, w, h, (ulong)color, num_chan);
8102
    else
8103
        if_debug7m('v', dev->memory,
8104
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8105
                   x, y, w, h,
8106
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8107
                   num_chan);
8108
#endif
8109
    /*
8110
     * Unpack the gx_color_index values.  Complement the components for subtractive
8111
     * color spaces.
8112
     */
8113
1.77M
    if (devn) {
8114
143k
        if (has_tags) {
8115
0
            curr_tag = pdc->tag;
8116
0
        }
8117
143k
        if (additive) {
8118
77.4k
            for (j = 0; j < num_comp; j++) {
8119
58.0k
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
8120
58.0k
            }
8121
124k
        } else {
8122
620k
            for (j = 0; j < num_comp; j++) {
8123
496k
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
8124
496k
            }
8125
124k
        }
8126
1.63M
    } else {
8127
1.63M
        if (has_tags) {
8128
0
            curr_tag = (color >> (num_comp * 8)) & 0xff;
8129
0
        }
8130
1.63M
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
8131
1.63M
    }
8132
8133
1.77M
    if (!has_tags)
8134
1.77M
        tag_off = 0;
8135
8136
1.77M
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
8137
1.77M
    if (has_shape) {
8138
147
        shape = (byte)floor (255 * pdev->shape + 0.5);
8139
1.77M
    } else {
8140
1.77M
        shape_off = 0;
8141
1.77M
    }
8142
8143
1.77M
    if (!has_alpha_g)
8144
0
        alpha_g_off = 0;
8145
1.77M
    src_alpha = 255 - src_alpha;
8146
1.77M
    shape = 255 - shape;
8147
8148
    /* Fit the mark into the bounds of the buffer */
8149
1.77M
    if (x < buf->rect.p.x) {
8150
0
        w += x - buf->rect.p.x;
8151
0
        x = buf->rect.p.x;
8152
0
    }
8153
1.77M
    if (y < buf->rect.p.y) {
8154
10
      h += y - buf->rect.p.y;
8155
10
      y = buf->rect.p.y;
8156
10
    }
8157
1.77M
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8158
1.77M
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8159
    /* Update the dirty rectangle with the mark. */
8160
1.77M
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8161
1.77M
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8162
1.77M
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8163
1.77M
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8164
8165
    /* composite with backdrop only. */
8166
1.77M
    if (has_backdrop)
8167
1.77M
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8168
0
    else
8169
0
        bline = NULL;
8170
8171
1.77M
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8172
8173
3.75M
    for (j = 0; j < h; ++j) {
8174
1.97M
        bg_ptr = bline;
8175
1.97M
        dst_ptr = line;
8176
97.6M
        for (i = 0; i < w; ++i) {
8177
            /* Complement the components for subtractive color spaces */
8178
95.6M
            if (has_backdrop) {
8179
95.6M
                if (additive) {
8180
350M
                    for (k = 0; k < num_comp; ++k)
8181
256M
                        dst[k] = bg_ptr[k * planestride];
8182
94.8M
                } else {
8183
3.69M
                    for (k = 0; k < num_comp; ++k)
8184
2.95M
                        dst2[k] = dst[k] = 255 - bg_ptr[k * planestride];
8185
738k
                }
8186
95.6M
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8187
95.6M
            }
8188
95.6M
            if (buf->isolated || !has_backdrop) {
8189
0
                art_pdf_knockoutisolated_group_8(dst, src, num_comp);
8190
95.6M
            } else {
8191
95.6M
                art_pdf_composite_knockout_8(dst, src, num_comp,
8192
95.6M
                                            blend_mode, pdev->blend_procs, pdev);
8193
95.6M
            }
8194
            /* Complement the results for subtractive color spaces */
8195
95.6M
            if (additive) {
8196
94.8M
                if (!overprint) {
8197
445M
                    for (k = 0; k < num_chan; ++k)
8198
350M
                        dst_ptr[k * planestride] = dst[k];
8199
94.8M
                } else {
8200
                    /* Hybrid additive with subtractive spots */
8201
                    /* We may have to do the compatible overprint blending */
8202
7.14k
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8203
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8204
0
                            blend_mode, pdev->blend_procs, pdev);
8205
0
                    }
8206
28.5k
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8207
21.4k
                        if ((comps & 0x1) != 0) {
8208
21.4k
                            dst_ptr[k * planestride] = dst[k];
8209
21.4k
                        } else {
8210
                            /* Compatible overprint blend result. */
8211
0
                            dst_ptr[k * planestride] = dst2[k];
8212
0
                        }
8213
21.4k
                    }
8214
7.14k
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8215
7.14k
                }
8216
94.8M
            } else {
8217
738k
                if (overprint) {
8218
                    /* We may have to do the compatible overprint blending */
8219
0
                    if (!buf->isolated && drawn_comps != (( (size_t) 1 << (size_t) dev->color_info.num_components)-(size_t) 1)) {
8220
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8221
0
                            blend_mode, pdev->blend_procs, pdev);
8222
0
                    }
8223
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8224
0
                        if ((comps & 0x1) != 0) {
8225
0
                            dst_ptr[k * planestride] = 255 - dst[k];
8226
0
                        } else {
8227
                            /* Compatible overprint blend result. */
8228
0
                            dst_ptr[k * planestride] = 255 - dst2[k];
8229
0
                        }
8230
0
                    }
8231
738k
                } else {
8232
3.69M
                    for (k = 0; k < num_comp; ++k)
8233
2.95M
                        dst_ptr[k * planestride] = 255 - dst[k];
8234
738k
                }
8235
738k
                dst_ptr[num_comp * planestride] = dst[num_comp];
8236
738k
            }
8237
95.6M
            if (tag_off) {
8238
                /* If src alpha is 100% then set to curr_tag, else or */
8239
                /* other than Normal BM, we always OR */
8240
0
                if (src[num_comp] == 255 && tag_blend) {
8241
0
                    dst_ptr[tag_off] = curr_tag;
8242
0
                } else {
8243
0
                    dst_ptr[tag_off] |= curr_tag;
8244
0
                }
8245
0
            }
8246
            /* Knockout group alpha and shape too */
8247
95.6M
            if (alpha_g_off)
8248
95.6M
                dst_ptr[alpha_g_off] = 255 - src_alpha;
8249
95.6M
            if (shape_off)
8250
306
                dst_ptr[shape_off] = 255 - shape;
8251
95.6M
            ++dst_ptr;
8252
95.6M
            if (has_backdrop)
8253
95.6M
                ++bg_ptr;
8254
95.6M
        }
8255
1.97M
        bline += rowstride;
8256
1.97M
        line += rowstride;
8257
1.97M
    }
8258
#if 0
8259
/* #if RAW_DUMP */
8260
    /* Dump the current buffer to see what we have. */
8261
    dump_raw_buffer(pdev->ctx->memory,
8262
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8263
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8264
                    pdev->ctx->stack->n_planes,
8265
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8266
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8267
                    pdev->ctx->stack->deep);
8268
    global_index++;
8269
#endif
8270
1.77M
    return 0;
8271
1.77M
}
8272
8273
static  int
8274
do_mark_fill_rectangle_ko_simple16(gx_device *dev, int x, int y, int w, int h,
8275
                                   gx_color_index color,
8276
                                   const gx_device_color *pdc, bool devn)
8277
0
{
8278
0
    pdf14_device *pdev = (pdf14_device *)dev;
8279
0
    pdf14_buf *buf = pdev->ctx->stack;
8280
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8281
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8282
0
        blend_mode == BLEND_MODE_Compatible ||
8283
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
8284
0
    int i, j, k;
8285
0
    uint16_t *bline, *bg_ptr, *line, *dst_ptr;
8286
0
    uint16_t src[PDF14_MAX_PLANES];
8287
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
8288
0
    uint16_t dst2[PDF14_MAX_PLANES] = { 0 };
8289
0
    intptr_t rowstride = buf->rowstride;
8290
0
    intptr_t planestride = buf->planestride;
8291
0
    int num_chan = buf->n_chan;
8292
0
    int num_comp = num_chan - 1;
8293
0
    intptr_t shape_off = num_chan * planestride;
8294
0
    bool has_shape = buf->has_shape;
8295
0
    bool has_alpha_g = buf->has_alpha_g;
8296
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8297
0
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8298
0
                                   (has_shape ? planestride : 0);
8299
0
    bool has_tags = buf->has_tags;
8300
0
    bool additive = pdev->ctx->additive;
8301
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8302
0
    uint16_t shape = 0; /* Quiet compiler. */
8303
0
    uint16_t src_alpha;
8304
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8305
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
8306
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8307
0
    gx_color_index comps;
8308
0
    bool has_backdrop = buf->backdrop != NULL;
8309
8310
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8311
       subtractive) and we are doing overprint with drawn_comps == 0
8312
       then this is a no-operation */
8313
0
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8314
0
        return 0;
8315
8316
0
    if (buf->data == NULL)
8317
0
        return 0;
8318
#if 0
8319
    if (sizeof(color) <= sizeof(ulong))
8320
        if_debug6m('v', dev->memory,
8321
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %lx, nc %d,\n",
8322
                   x, y, w, h, (ulong)color, num_chan);
8323
    else
8324
        if_debug7m('v', dev->memory,
8325
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8326
                   x, y, w, h,
8327
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8328
                   num_chan);
8329
#endif
8330
    /*
8331
     * Unpack the gx_color_index values.  Complement the components for subtractive
8332
     * color spaces.
8333
     */
8334
0
    if (devn) {
8335
0
        if (has_tags) {
8336
0
            curr_tag = pdc->tag;
8337
0
        }
8338
0
        if (additive) {
8339
0
            for (j = 0; j < num_comp; j++) {
8340
0
                src[j] = pdc->colors.devn.values[j];
8341
0
            }
8342
0
        } else {
8343
0
            for (j = 0; j < num_comp; j++) {
8344
0
                src[j] = 65535 - pdc->colors.devn.values[j];
8345
0
            }
8346
0
        }
8347
0
    } else {
8348
0
        if (has_tags) {
8349
0
            curr_tag = (color >> (num_comp * 16)) & 0xff;
8350
0
        }
8351
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
8352
0
    }
8353
8354
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
8355
0
    if (has_shape) {
8356
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
8357
0
    } else {
8358
0
        shape_off = 0;
8359
0
    }
8360
8361
0
    if (!has_tags) {
8362
0
        tag_off = 0;
8363
0
    }
8364
8365
0
    if (!has_alpha_g)
8366
0
        alpha_g_off = 0;
8367
0
    src_alpha = 65535 - src_alpha;
8368
0
    shape = 65535 - shape;
8369
8370
    /* Fit the mark into the bounds of the buffer */
8371
0
    if (x < buf->rect.p.x) {
8372
0
        w += x - buf->rect.p.x;
8373
0
        x = buf->rect.p.x;
8374
0
    }
8375
0
    if (y < buf->rect.p.y) {
8376
0
      h += y - buf->rect.p.y;
8377
0
      y = buf->rect.p.y;
8378
0
    }
8379
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8380
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8381
    /* Update the dirty rectangle with the mark. */
8382
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8383
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8384
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8385
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8386
8387
8388
    /* composite with backdrop only. */
8389
0
    if (has_backdrop)
8390
0
        bline = (uint16_t*)(void*)(buf->backdrop + (x - buf->rect.p.x) * 2 + (y - buf->rect.p.y) * rowstride);
8391
0
    else
8392
0
        bline = NULL;
8393
8394
0
    line = (uint16_t *)(void *)(buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride);
8395
0
    planestride >>= 1;
8396
0
    rowstride >>= 1;
8397
0
    alpha_g_off >>= 1;
8398
0
    shape_off >>= 1;
8399
0
    tag_off >>= 1;
8400
8401
0
    for (j = 0; j < h; ++j) {
8402
0
        bg_ptr = bline;
8403
0
        dst_ptr = line;
8404
0
        for (i = 0; i < w; ++i) {
8405
            /* Complement the components for subtractive color spaces */
8406
0
            if (has_backdrop) {
8407
0
                if (additive) {
8408
0
                    for (k = 0; k < num_comp; ++k)
8409
0
                        dst[k] = bg_ptr[k * planestride];
8410
0
                } else {
8411
0
                    for (k = 0; k < num_comp; ++k)
8412
0
                        dst2[k] = dst[k] = 65535 - bg_ptr[k * planestride];
8413
0
                }
8414
0
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8415
0
            }
8416
0
            if (buf->isolated || !has_backdrop) {
8417
0
                art_pdf_knockoutisolated_group_16(dst, src, num_comp);
8418
0
            } else {
8419
0
                art_pdf_composite_knockout_16(dst, src, num_comp,
8420
0
                                              blend_mode, pdev->blend_procs, pdev);
8421
0
            }
8422
            /* Complement the results for subtractive color spaces */
8423
0
            if (additive) {
8424
0
                if (!overprint) {
8425
0
                    for (k = 0; k < num_chan; ++k)
8426
0
                        dst_ptr[k * planestride] = dst[k];
8427
0
                } else {
8428
                    /* Hybrid additive with subtractive spots */
8429
                    /* We may have to do the compatible overprint blending */
8430
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8431
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8432
0
                            blend_mode, pdev->blend_procs, pdev);
8433
0
                    }
8434
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8435
0
                        if ((comps & 0x1) != 0) {
8436
0
                            dst_ptr[k * planestride] = dst[k];
8437
0
                        } else {
8438
                            /* Compatible overprint blend result. */
8439
0
                            dst_ptr[k * planestride] = dst2[k];
8440
0
                        }
8441
0
                    }
8442
0
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8443
0
                }
8444
0
            } else {
8445
0
                if (overprint) {
8446
                    /* We may have to do the compatible overprint blending */
8447
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8448
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8449
0
                            blend_mode, pdev->blend_procs, pdev);
8450
0
                    }
8451
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8452
0
                        if ((comps & 0x1) != 0) {
8453
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
8454
0
                        } else {
8455
                            /* Compatible overprint blend result. */
8456
0
                            dst_ptr[k * planestride] = 65535 - dst2[k];
8457
0
                        }
8458
0
                    }
8459
0
                } else {
8460
0
                    for (k = 0; k < num_comp; ++k)
8461
0
                        dst_ptr[k * planestride] = 65535 - dst[k];
8462
0
                }
8463
0
                dst_ptr[num_comp * planestride] = dst[num_comp];
8464
0
            }
8465
0
            if (tag_off) {
8466
                /* FIXME: As we are knocking out, possibly, we should be
8467
                 * always overwriting tag values here? */
8468
                /* If src alpha is 100% then set to curr_tag, else or */
8469
                /* other than Normal BM, we always OR */
8470
0
                if (src[num_comp] == 65535 && tag_blend) {
8471
0
                    dst_ptr[tag_off] = curr_tag;
8472
0
                } else {
8473
0
                    dst_ptr[tag_off] |= curr_tag;
8474
0
                }
8475
0
            }
8476
            /* Knockout group alpha and shape too */
8477
0
            if (alpha_g_off)
8478
0
                dst_ptr[alpha_g_off] = 65535 - src_alpha;
8479
0
            if (shape_off)
8480
0
                dst_ptr[shape_off] = 65535 - shape;
8481
0
            ++dst_ptr;
8482
0
            if (has_backdrop)
8483
0
                ++bg_ptr;
8484
0
        }
8485
0
        bline += rowstride;
8486
0
        line += rowstride;
8487
0
    }
8488
#if 0
8489
/* #if RAW_DUMP */
8490
    /* Dump the current buffer to see what we have. */
8491
    dump_raw_buffer(pdev->ctx->memory,
8492
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8493
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8494
                    pdev->ctx->stack->n_planes,
8495
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8496
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8497
                    pdev->ctx->stack->deep);
8498
    global_index++;
8499
#endif
8500
0
    return 0;
8501
0
}
8502
8503
static  int
8504
pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, int w, int h,
8505
                                    gx_color_index color,
8506
                                    const gx_device_color *pdc, bool devn)
8507
1.77M
{
8508
1.77M
    pdf14_device *pdev = (pdf14_device *)dev;
8509
1.77M
    pdf14_buf *buf = pdev->ctx->stack;
8510
8511
1.77M
    if (buf->deep)
8512
0
        return do_mark_fill_rectangle_ko_simple16(dev, x, y, w, h, color, pdc, devn);
8513
1.77M
    else
8514
1.77M
        return do_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, pdc, devn);
8515
1.77M
}
8516
8517
/**
8518
 * Here we have logic to override the cmap_procs with versions that
8519
 * do not apply the transfer function. These copies should track the
8520
 * versions in gxcmap.c.
8521
 **/
8522
static  cmap_proc_gray(pdf14_cmap_gray_direct);
8523
static  cmap_proc_rgb(pdf14_cmap_rgb_direct);
8524
static  cmap_proc_cmyk(pdf14_cmap_cmyk_direct);
8525
static  cmap_proc_separation(pdf14_cmap_separation_direct);
8526
static  cmap_proc_devicen(pdf14_cmap_devicen_direct);
8527
static  cmap_proc_is_halftoned(pdf14_cmap_is_halftoned);
8528
8529
static  const gx_color_map_procs pdf14_cmap_many = {
8530
     pdf14_cmap_gray_direct,
8531
     pdf14_cmap_rgb_direct,
8532
     pdf14_cmap_cmyk_direct,
8533
     pdf14_cmap_separation_direct,
8534
     pdf14_cmap_devicen_direct,
8535
     pdf14_cmap_is_halftoned
8536
    };
8537
8538
/**
8539
 * Note: copied from gxcmap.c because it's inlined.
8540
 **/
8541
static  inline void
8542
map_components_to_colorants(const frac * pcc,
8543
                            const gs_devicen_color_map * pcolor_component_map,
8544
                            frac * plist,
8545
                            int num_additives)
8546
1.01M
{
8547
1.01M
    int i = pcolor_component_map->num_colorants - 1;
8548
1.01M
    int pos;
8549
8550
    /* Clear all output colorants first */
8551
5.06M
    for (; i >= num_additives; i--) {
8552
4.05M
        plist[i] = frac_0;
8553
4.05M
    }
8554
1.01M
    for (; i >= 0; i--) {
8555
3.19k
        plist[i] = frac_1;
8556
3.19k
    }
8557
    /* Map color components into output list */
8558
2.17M
    for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
8559
1.16M
        pos = pcolor_component_map->color_map[i];
8560
1.16M
        if (pos >= 0) {
8561
1.16M
            if (pos < num_additives)
8562
0
                plist[pos] = frac_1 - pcc[i];
8563
1.16M
            else
8564
1.16M
                plist[pos] = pcc[i];
8565
1.16M
        }
8566
1.16M
    }
8567
1.01M
}
8568
8569
/* See Section 7.6.4 of PDF 1.7 spec */
8570
static inline bool
8571
pdf14_state_opaque(gx_device *pdev, const gs_gstate *pgs)
8572
23.1M
{
8573
23.1M
    if (pgs->fillconstantalpha != 1.0 ||
8574
23.0M
        pgs->strokeconstantalpha != 1.0 ||
8575
23.0M
        !(pgs->blend_mode == BLEND_MODE_Normal ||
8576
157k
          pgs->blend_mode == BLEND_MODE_CompatibleOverprint))
8577
211k
        return 0;
8578
8579
    /* We can only be opaque if we're not in an SMask. */
8580
22.9M
    return dev_proc(pdev, dev_spec_op)(pdev,
8581
22.9M
                                       gxdso_in_smask,
8582
22.9M
                                       NULL, 0) != 1;
8583
23.1M
}
8584
8585
static  void
8586
pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs,
8587
                       gx_device * dev, gs_color_select_t select)
8588
8.20M
{
8589
8.20M
    int i, nc, ncomps;
8590
8.20M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8591
8.20M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8592
8.20M
    gx_color_index color;
8593
8.20M
    gx_device *trans_device;
8594
8.20M
    const gx_device *map_dev;
8595
8.20M
    const gx_cm_color_map_procs *procs;
8596
8597
    /* If trans device is set, we need to use its procs. */
8598
8.20M
    if (pgs->trans_device != NULL) {
8599
4.15M
        trans_device = pgs->trans_device;
8600
4.15M
    } else {
8601
4.04M
        trans_device = dev;
8602
4.04M
    }
8603
8.20M
    ncomps = trans_device->color_info.num_components;
8604
8605
    /* map to the color model */
8606
8.20M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8607
8.20M
    procs->map_gray(map_dev, gray, cm_comps);
8608
8609
8.20M
    nc = ncomps;
8610
8.20M
    if (device_encodes_tags(trans_device))
8611
0
        nc--;
8612
8.20M
    if (pdf14_state_opaque(trans_device, pgs)) {
8613
8.92M
        for (i = 0; i < nc; i++)
8614
4.46M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8615
4.46M
    } else {
8616
7.49M
        for (i = 0; i < nc; i++)
8617
3.74M
            cv[i] = frac2cv(cm_comps[i]);
8618
3.74M
    }
8619
    /* Copy tags untransformed. */
8620
8.20M
    if (nc < ncomps)
8621
0
        cv[nc] = dev->graphics_type_tag;
8622
8623
    /* If output device supports devn, we need to make sure we send it the
8624
       proper color type.  We now support Gray + spots as devn colors */
8625
8.20M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8626
374k
        for (i = 0; i < ncomps; i++)
8627
187k
            pdc->colors.devn.values[i] = cv[i];
8628
11.9M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8629
11.7M
            pdc->colors.devn.values[i] = 0;
8630
187k
        pdc->type = gx_dc_type_devn;
8631
8.01M
    } else {
8632
        /* encode as a color index */
8633
8.01M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8634
        /* check if the encoding was successful; we presume failure is rare */
8635
8.01M
        if (color != gx_no_color_index)
8636
8.01M
            color_set_pure(pdc, color);
8637
8.01M
    }
8638
8.20M
}
8639
8640
static  void
8641
pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
8642
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
8643
3.93M
{
8644
3.93M
    int i, nc, ncomps;
8645
3.93M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8646
3.93M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8647
3.93M
    gx_color_index color;
8648
3.93M
    gx_device *trans_device;
8649
3.93M
    const gx_device *map_dev;
8650
3.93M
    const gx_cm_color_map_procs *procs;
8651
8652
    /* If trans device is set, we need to use its procs. */
8653
3.93M
    if (pgs->trans_device != NULL){
8654
602k
        trans_device = pgs->trans_device;
8655
3.33M
    } else {
8656
3.33M
        trans_device = dev;
8657
3.33M
    }
8658
3.93M
    ncomps = trans_device->color_info.num_components;
8659
    /* map to the color model */
8660
3.93M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8661
3.93M
    procs->map_rgb(map_dev, pgs, r, g, b, cm_comps);
8662
8663
3.93M
    nc = ncomps;
8664
3.93M
    if (device_encodes_tags(trans_device))
8665
0
        nc--;
8666
3.93M
    if (pdf14_state_opaque(trans_device, pgs)) {
8667
9.75M
        for (i = 0; i < nc; i++)
8668
7.32M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8669
2.43M
    } else {
8670
5.97M
        for (i = 0; i < nc; i++)
8671
4.47M
            cv[i] = frac2cv(cm_comps[i]);
8672
1.49M
    }
8673
    /* Copy tags untransformed. */
8674
3.93M
    if (nc < ncomps)
8675
0
        cv[nc] = dev->graphics_type_tag;
8676
8677
    /* If output device supports devn, we need to make sure we send it the
8678
       proper color type.  We now support RGB + spots as devn colors */
8679
3.93M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8680
11.7M
        for (i = 0; i < ncomps; i++)
8681
8.82M
            pdc->colors.devn.values[i] = cv[i];
8682
182M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8683
179M
            pdc->colors.devn.values[i] = 0;
8684
2.93M
        pdc->type = gx_dc_type_devn;
8685
2.93M
    } else {
8686
        /* encode as a color index */
8687
996k
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8688
        /* check if the encoding was successful; we presume failure is rare */
8689
996k
        if (color != gx_no_color_index)
8690
996k
            color_set_pure(pdc, color);
8691
996k
    }
8692
3.93M
}
8693
8694
static  void
8695
pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc,
8696
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select,
8697
     const gs_color_space *pcs)
8698
10.9M
{
8699
10.9M
    int i, nc, ncomps;
8700
10.9M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8701
10.9M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8702
10.9M
    gx_color_index color;
8703
10.9M
    gx_device *trans_device;
8704
10.9M
    const gx_device *map_dev;
8705
10.9M
    const gx_cm_color_map_procs *procs;
8706
8707
8708
    /* If trans device is set, we need to use its procs. */
8709
10.9M
    if (pgs->trans_device != NULL){
8710
8.57M
        trans_device = pgs->trans_device;
8711
8.57M
    } else {
8712
2.40M
        trans_device = dev;
8713
2.40M
    }
8714
10.9M
    ncomps = trans_device->color_info.num_components;
8715
8716
    /* Map to the color model. Transfer function is only used
8717
       if we are drawing with an opaque color. */
8718
10.9M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8719
10.9M
    procs->map_cmyk(map_dev, c, m, y, k, cm_comps);
8720
8721
10.9M
    nc = ncomps;
8722
10.9M
    if (device_encodes_tags(trans_device))
8723
0
        nc--;
8724
10.9M
    if (pdf14_state_opaque(trans_device, pgs)) {
8725
48.7M
        for (i = 0; i < nc; i++)
8726
39.0M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8727
9.75M
    } else {
8728
6.11M
        for (i = 0; i < nc; i++)
8729
4.89M
            cv[i] = frac2cv(cm_comps[i]);
8730
1.22M
    }
8731
    /* Copy tags untransformed. */
8732
10.9M
    if (nc < ncomps)
8733
0
        cv[nc] = dev->graphics_type_tag;
8734
8735
    /* if output device supports devn, we need to make sure we send it the
8736
       proper color type */
8737
10.9M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8738
41.7M
        for (i = 0; i < ncomps; i++)
8739
33.3M
            pdc->colors.devn.values[i] = cv[i];
8740
509M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8741
500M
            pdc->colors.devn.values[i] = 0;
8742
8.34M
        pdc->type = gx_dc_type_devn;
8743
8.34M
    } else {
8744
        /* encode as a color index */
8745
2.62M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8746
        /* check if the encoding was successful; we presume failure is rare */
8747
2.62M
        if (color != gx_no_color_index)
8748
2.62M
            color_set_pure(pdc, color);
8749
2.62M
    }
8750
10.9M
}
8751
8752
static int
8753
pdf14_get_num_spots(gx_device * dev)
8754
1.01M
{
8755
1.01M
    cmm_dev_profile_t *dev_profile;
8756
1.01M
    cmm_profile_t *icc_profile;
8757
1.01M
    gsicc_rendering_param_t render_cond;
8758
8759
1.01M
    dev_proc(dev, get_profile)(dev, &dev_profile);
8760
1.01M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
8761
1.01M
        &render_cond);
8762
1.01M
    return dev->color_info.num_components - icc_profile->num_comps - device_encodes_tags(dev);
8763
1.01M
}
8764
8765
static  void
8766
pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs,
8767
                 gx_device * dev, gs_color_select_t select, const gs_color_space *pcs)
8768
1.54k
{
8769
1.54k
    int i, nc, ncomps = dev->color_info.num_components;
8770
1.54k
    int num_spots = pdf14_get_num_spots(dev);
8771
1.54k
    bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
8772
1.54k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8773
1.54k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8774
1.54k
    gx_color_index color;
8775
1.54k
    int n = 0;
8776
8777
1.54k
    nc = ncomps;
8778
1.54k
    if (device_encodes_tags(dev))
8779
0
        nc--;
8780
8781
1.54k
    n = additive ? nc - num_spots : 0;
8782
1.54k
    if (pgs->color_component_map.sep_type == SEP_ALL) {
8783
0
        frac comp_value = all;
8784
8785
0
        for (i = pgs->color_component_map.num_colorants - 1; i >= nc - num_spots; i--)
8786
0
            cm_comps[i] = comp_value;
8787
        /*
8788
         * Invert the photometric interpretation for additive
8789
         * color spaces because separations are always subtractive.
8790
         */
8791
0
        if (additive)
8792
0
            comp_value = frac_1 - comp_value;
8793
        /* Use the "all" value for all components */
8794
0
        for (; i >= 0; i--)
8795
0
            cm_comps[i] = comp_value;
8796
1.54k
    } else {
8797
1.54k
        frac comp_value[GX_DEVICE_COLOR_MAX_COMPONENTS];
8798
8799
1.54k
        if (pgs->color_component_map.sep_type == SEP_NONE) {
8800
0
            color_set_null(pdc);
8801
0
            return;
8802
0
        }
8803
8804
        /* map to the color model */
8805
3.09k
        for (i = pgs->color_component_map.num_components - 1; i >= 0; i--)
8806
1.54k
            comp_value[i] = all;
8807
1.54k
        map_components_to_colorants(comp_value, &(pgs->color_component_map), cm_comps, n);
8808
1.54k
    }
8809
8810
    /* apply the transfer function(s); convert to color values */
8811
4.74k
    for (i = 0; i < n; i++)
8812
3.19k
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8813
4.54k
    for (; i < nc; i++)
8814
3.00k
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8815
8816
    /* Copy tags untransformed. */
8817
1.54k
    if (nc < ncomps)
8818
0
        cv[nc] = dev->graphics_type_tag;
8819
8820
    /* if output device supports devn, we need to make sure we send it the
8821
       proper color type */
8822
1.54k
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0) > 0) {
8823
7.74k
        for (i = 0; i < ncomps; i++)
8824
6.19k
            pdc->colors.devn.values[i] = cv[i];
8825
94.4k
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8826
92.8k
            pdc->colors.devn.values[i] = 0;
8827
1.54k
        pdc->type = gx_dc_type_devn;
8828
1.54k
    } else {
8829
        /* encode as a color index */
8830
0
        color = dev_proc(dev, encode_color)(dev, cv);
8831
        /* check if the encoding was successful; we presume failure is rare */
8832
0
        if (color != gx_no_color_index)
8833
0
            color_set_pure(pdc, color);
8834
0
    }
8835
1.54k
}
8836
8837
static  void
8838
pdf14_cmap_devicen_direct(const frac * pcc,
8839
    gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
8840
    gs_color_select_t select, const gs_color_space *pcs)
8841
1.01M
{
8842
1.01M
    int i, nc, ncomps = dev->color_info.num_components;
8843
1.01M
    int num_spots = pdf14_get_num_spots(dev);
8844
1.01M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8845
1.01M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8846
1.01M
    gx_color_index color;
8847
1.01M
    gx_device *trans_device;
8848
1.01M
    int num_add_colorants = 0;
8849
8850
     /*  We may be coming from the clist writer which often forwards us the
8851
         target device. If this occurs we actually need to get to the color
8852
         space defined by the transparency group and we use the operators
8853
         defined by the transparency device to do the job.
8854
       */
8855
1.01M
    if (pgs->trans_device != NULL){
8856
1.01M
        trans_device = pgs->trans_device;
8857
1.01M
    } else {
8858
0
        trans_device = dev;
8859
0
    }
8860
1.01M
    ncomps = trans_device->color_info.num_components;
8861
1.01M
    nc = ncomps;
8862
1.01M
    if (device_encodes_tags(trans_device))
8863
0
        nc--;
8864
8865
1.01M
    if (trans_device->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
8866
0
        num_add_colorants = nc - num_spots;
8867
8868
    /* map to the color model */
8869
1.01M
    map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps, num_add_colorants);
8870
8871
    /* apply the transfer function(s); convert to color values */
8872
    /* The additive ones (if there are any) need to be inverted. */
8873
1.01M
    for (i = 0; i < num_add_colorants; i++)
8874
1.01M
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8875
5.06M
    for (; i < nc; i++)
8876
4.05M
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8877
    /* Copy tags untransformed. */
8878
1.01M
    if (nc < ncomps)
8879
0
        cv[nc] = dev->graphics_type_tag;
8880
8881
    /* if output device supports devn, we need to make sure we send it the
8882
       proper color type */
8883
1.01M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8884
237k
        for (i = 0; i < ncomps; i++)
8885
189k
            pdc->colors.devn.values[i] = cv[i];
8886
2.89M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8887
2.84M
            pdc->colors.devn.values[i] = 0;
8888
47.4k
        pdc->type = gx_dc_type_devn;
8889
965k
    } else {
8890
    /* encode as a color index */
8891
965k
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8892
        /* check if the encoding was successful; we presume failure is rare */
8893
965k
        if (color != gx_no_color_index)
8894
965k
            color_set_pure(pdc, color);
8895
965k
    }
8896
1.01M
}
8897
8898
static  bool
8899
pdf14_cmap_is_halftoned(const gs_gstate * pgs, gx_device * dev)
8900
63.5k
{
8901
63.5k
    return false;
8902
63.5k
}
8903
8904
static  const gx_color_map_procs *
8905
pdf14_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev)
8906
1.50M
{
8907
    /* The pdf14 marking device itself is always continuous tone. */
8908
1.50M
    return &pdf14_cmap_many;
8909
1.50M
}
8910
8911
static int
8912
pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op,
8913
                  void *data, int size)
8914
96.3M
{
8915
96.3M
    pdf14_device * p14dev = (pdf14_device *)pdev;
8916
8917
96.3M
    if (dev_spec_op == gxdso_supports_pattern_transparency)
8918
919k
        return 1;
8919
95.4M
    if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path)
8920
9.42k
        return 1;
8921
95.4M
    if (dev_spec_op == gxdso_is_pdf14_device) {
8922
948
        if (data != NULL && size == sizeof(gx_device *))
8923
281
            *(gx_device **)data = pdev;
8924
948
        return 1;
8925
948
    }
8926
95.4M
    if (dev_spec_op == gxdso_device_child) {
8927
2.05k
        pdf14_device *dev = (pdf14_device *)pdev;
8928
2.05k
        gxdso_device_child_request *d = (gxdso_device_child_request *)data;
8929
2.05k
        if (d->target == pdev) {
8930
2.05k
            d->target = dev->target;
8931
2.05k
            return 1;
8932
2.05k
        }
8933
2.05k
    }
8934
95.4M
    if (dev_spec_op == gxdso_supports_devn
8935
47.7M
     || dev_spec_op == gxdso_skip_icc_component_validation) {
8936
47.7M
        cmm_dev_profile_t *dev_profile;
8937
47.7M
        int code;
8938
47.7M
        code = dev_proc(pdev, get_profile)((gx_device*) pdev, &dev_profile);
8939
47.7M
        if (code == 0) {
8940
47.7M
            return dev_profile->supports_devn;
8941
47.7M
        } else {
8942
0
            return 0;
8943
0
        }
8944
47.7M
    }
8945
47.6M
    if (dev_spec_op == gxdso_pdf14_sep_device) {
8946
330k
        pdf14_device* dev = (pdf14_device*)pdev;
8947
8948
330k
        if (strcmp(dev->dname, "pdf14cmykspot") == 0 ||
8949
330k
            strcmp(dev->dname, "pdf14clistcmykspot") == 0)
8950
167k
            return 1;
8951
162k
        return 0;
8952
330k
    }
8953
47.3M
    if (dev_spec_op == gxdso_is_encoding_direct)
8954
1.21M
        return 1;
8955
8956
    /* We don't want to pass on these spec_ops either, because the child might respond
8957
     * with an inappropriate response when the PDF14 device is active. For example; the
8958
     * JPEG passthrough will give utterly wrong results if we pass that to a device which
8959
     * supports JPEG passthrough, because the pdf14 device needs to render the image.
8960
     */
8961
46.1M
    if (dev_spec_op == gxdso_in_pattern_accumulator)
8962
300k
        return 0;
8963
45.8M
    if (dev_spec_op == gxdso_copy_color_is_fast)
8964
976k
        return 0;
8965
44.8M
    if(dev_spec_op == gxdso_pattern_handles_clip_path)
8966
9.23k
        return 0;
8967
44.8M
    if(dev_spec_op == gxdso_supports_hlcolor)
8968
841
        return 0;
8969
44.8M
    if(dev_spec_op == gxdso_pattern_can_accum)
8970
83.0k
        return 0;
8971
44.7M
    if(dev_spec_op == gxdso_JPEG_passthrough_query)
8972
1.27k
        return 0;
8973
44.7M
    if (dev_spec_op == gxdso_overprint_active) {
8974
3.30M
        if (p14dev->pclist_device != NULL) {
8975
3.29M
            return dev_proc(p14dev->pclist_device, dev_spec_op)(p14dev->pclist_device, dev_spec_op, data, size);
8976
3.29M
        } else {
8977
8.76k
            return p14dev->overprint || p14dev->stroke_overprint;
8978
8.76k
        }
8979
3.30M
    }
8980
8981
    /* These should be coming only from the abuf device
8982
       during fill-stroke operation. Any other use will
8983
       result in bad things. */
8984
41.4M
    if (dev_spec_op == gxdso_abuf_optrans)
8985
0
    {
8986
0
        int ret = p14dev->op_state;
8987
0
        overprint_abuf_state_t *state_data = (overprint_abuf_state_t *)data;
8988
0
        pdf14_abuf_state_t *pdf14_abuf = (pdf14_abuf_state_t *)&state_data->storage[0];
8989
0
        const gs_gstate* cpgs = state_data->pgs;
8990
0
        union {
8991
0
            const gs_gstate* cpgs;
8992
0
            gs_gstate* pgs;
8993
0
        } const_breaker;
8994
0
        gs_gstate* pgs;
8995
0
        int code = 0;
8996
0
        int code1 = 0;
8997
8998
        /* A compile time assert to check our storage types are appropriately sized. */
8999
0
        typedef char compile_time_assert[sizeof(pdf14_abuf_state_t) <= sizeof(state_data->storage) ? 1 : -1];
9000
9001
        /* I don't really like this, but there is no easy way around it. The device
9002
           in the pgs needs to be the pdf14 device to ensure that the compositor
9003
           actions occur with the gs_transparency calls. We have to call at that
9004
           level (as opposed to the gx_ or pdf14_ level) to ensure that the clist
9005
           operations are invoked. We could change the gs_trans calls to take a
9006
           device to avoid this dance but that changes the device procs. */
9007
0
        gx_device *curr_dev;
9008
9009
0
        const_breaker.cpgs = cpgs;
9010
0
        pgs = const_breaker.pgs;
9011
0
        curr_dev = pgs->device;
9012
0
        pgs->device = pdev;
9013
9014
0
        switch (state_data->op_trans) {
9015
9016
0
            case OP_FS_TRANS_PREFILL:
9017
0
                pdf14_abuf->orig_state = p14dev->op_state;
9018
0
                pdf14_abuf->blend_mode = cpgs->blend_mode;
9019
0
                pdf14_abuf->fill_alpha = cpgs->fillconstantalpha;
9020
0
                pdf14_abuf->stroke_alpha = cpgs->strokeconstantalpha;
9021
0
                pdf14_abuf->pgs = pgs; /* ref count? only used for this back and forth so ok */
9022
0
                if (pdf14_abuf->fill_alpha == 1.0 && pdf14_abuf->stroke_alpha == 1.0 &&
9023
0
                    pdf14_abuf->blend_mode == BLEND_MODE_Normal)
9024
0
                    pdf14_abuf->group_needed = false;
9025
0
                else
9026
0
                    pdf14_abuf->group_needed = true;
9027
9028
0
                if (pdf14_abuf->group_needed) {
9029
0
                    code = pdf14_fill_stroke_prefill(pdev, pgs, state_data->ppath,
9030
0
                        state_data->pcpath, pdf14_abuf->fill_alpha,
9031
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode,
9032
0
                        &(pdf14_abuf->op_ca_eq_CA), &(pdf14_abuf->path_empty),
9033
0
                        state_data->alpha_buf_path_scale);
9034
0
                    if (code < 0)
9035
0
                        goto cleanup;
9036
0
                    if (pdf14_abuf->path_empty)
9037
0
                        pdf14_abuf->group_needed = 0;
9038
0
                }
9039
0
                code = gs_update_trans_marking_params(pgs);
9040
0
                break;
9041
9042
0
            case OP_FS_TRANS_PRESTROKE:
9043
0
                if (pdf14_abuf->group_needed) {
9044
0
                    pdf14_fill_stroke_prestroke(pdev, pdf14_abuf->pgs, pdf14_abuf->stroke_alpha,
9045
0
                                                pdf14_abuf->blend_mode, pdf14_abuf->op_ca_eq_CA);
9046
0
                }
9047
0
                code = gs_update_trans_marking_params(pgs);
9048
0
                break;
9049
9050
0
            case OP_FS_TRANS_POSTSTROKE:
9051
0
                if (pdf14_abuf->group_needed) {
9052
0
                    code = pdf14_fill_stroke_poststroke(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9053
0
                                                        pdf14_abuf->op_ca_eq_CA);
9054
0
                }
9055
0
                if (code >= 0)
9056
0
                    code = gs_update_trans_marking_params(pgs);
9057
9058
                /* fallthrough */
9059
9060
0
            case OP_FS_TRANS_CLEANUP:
9061
0
cleanup:
9062
0
                if (pdf14_abuf->group_needed) {
9063
0
                    code1 = pdf14_fill_stroke_cleanup(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9064
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode, (PDF14_OP_FS_STATE)pdf14_abuf->orig_state);
9065
0
                    if (code1 < 0)
9066
0
                        code = gs_note_error(gs_error_Fatal);
9067
0
                }
9068
0
                break;
9069
0
        }
9070
0
        pgs->device = curr_dev;
9071
9072
0
        return (code < 0) ? code : ret;
9073
0
    }
9074
9075
41.4M
    if (dev_spec_op == gxdso_in_smask_construction)
9076
3.47M
        return p14dev->in_smask_construction > 0;
9077
37.9M
    if (dev_spec_op == gxdso_in_smask)
9078
23.7M
        return p14dev->in_smask_construction > 0 || p14dev->depth_within_smask;
9079
14.2M
    if (dev_spec_op == gxdso_replacecolor) {
9080
14.0M
        gx_device *tdev = p14dev->target;
9081
14.0M
        cmm_dev_profile_t *tdev_profile;
9082
14.0M
        int code;
9083
9084
         /* If in a softmask or softmask construction do not allow
9085
           replacement. */
9086
14.0M
        if (p14dev->in_smask_construction > 0 || p14dev->depth_within_smask)
9087
213k
            return 0;
9088
9089
        /* If the target CS is different than the pdf14 profile add this information
9090
           for the target device that will be handling the replacement. While not
9091
           perfect this at least lets you do the replacehment and have some information
9092
           about what the situation is. */
9093
13.7M
        code = dev_proc(tdev, get_profile)((gx_device*) tdev, &tdev_profile);
9094
13.7M
        if (code != 0)
9095
0
            return 0;
9096
9097
13.7M
        if (tdev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode !=
9098
13.7M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode) {
9099
2.77M
            color_replace_t* replace_data = (color_replace_t*)data;
9100
            /* Not ref counted as data is on the stack (from gx_remap_ICC) and we should be fine during this
9101
               color remap operation. */
9102
2.77M
            replace_data->pdf14_iccprofile = p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
9103
2.77M
        }
9104
9105
        /* Pass on to target device */
9106
13.7M
        return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9107
13.7M
    }
9108
192k
    if (dev_spec_op == gxdso_device_insert_child) {
9109
128
        gx_device *tdev = p14dev->target;
9110
128
        p14dev->target = (gx_device *)data;
9111
128
        rc_increment(p14dev->target);
9112
128
        rc_decrement_only(tdev, "pdf14_dev_spec_op");
9113
128
        return 0;
9114
128
    }
9115
192k
    if (dev_spec_op == gxdso_interpolate_threshold)
9116
4.71k
        return p14dev->interpolate_threshold;
9117
9118
187k
    if (dev_spec_op == gxdso_overprintsim_state) {
9119
4.69k
        unsigned char *data_uchar = (unsigned char *) data;
9120
4.69k
        data_uchar[0] = (unsigned char) p14dev->overprint_sim;
9121
4.69k
        if (p14dev->ctx != NULL)
9122
7
            data_uchar[1] = (unsigned char)p14dev->ctx->num_spots; /* pdf14 page device */
9123
4.68k
        else
9124
4.68k
            data_uchar[1] = (unsigned char)p14dev->devn_params.page_spot_colors;  /* pdf14 clist device */
9125
4.69k
        return 1;
9126
4.69k
    }
9127
9128
182k
    return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9129
187k
}
9130
9131
/* Needed to set color monitoring in the target device's profile */
9132
int
9133
gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring)
9134
0
{
9135
0
    pdf14_device * p14dev = (pdf14_device *)pdev;
9136
0
    gx_device *targ = p14dev->target;
9137
0
    cmm_dev_profile_t *dev_profile;
9138
0
    int code = dev_proc(targ, get_profile)((gx_device*) targ, &dev_profile);
9139
9140
0
    if (code == 0)
9141
0
        dev_profile->pageneutralcolor = monitoring;
9142
0
    return code;
9143
0
}
9144
9145
static int
9146
gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
9147
        gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct)
9148
958k
{
9149
958k
    pdf14_device dev_proto;
9150
958k
    pdf14_device * p14dev;
9151
958k
    int code;
9152
958k
    bool has_tags;
9153
958k
    cmm_profile_t *icc_profile;
9154
958k
    gsicc_rendering_param_t render_cond;
9155
958k
    cmm_dev_profile_t *dev_profile;
9156
958k
    uchar k;
9157
958k
    int max_bitmap;
9158
958k
    bool use_pdf14_accum = false;
9159
958k
    bool deep;
9160
9161
    /* Guard against later seg faults, this should not be possible */
9162
958k
    if (target == NULL)
9163
0
        return gs_throw_code(gs_error_Fatal);
9164
9165
958k
    has_tags = device_encodes_tags(target);
9166
958k
    deep = device_is_deep(target);
9167
958k
    max_bitmap = target->space_params.MaxBitmap == 0 ? MAX_BITMAP :
9168
958k
                                 target->space_params.MaxBitmap;
9169
    /* If the device is not a printer class device, it won't support saved-pages */
9170
    /* and so we may need to make a clist device in order to prevent very large  */
9171
    /* or high resolution pages from having allocation problems.                 */
9172
    /* We use MaxBitmap to decide when a clist is needed.*/
9173
958k
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_saved_pages, NULL, 0) <= 0 &&
9174
6.12k
        gx_device_is_pattern_clist(target) == 0 &&
9175
6.12k
        gx_device_is_pattern_accum(target) == 0 &&
9176
3.46k
        gs_device_is_memory(target) == 0) {
9177
9178
3.46k
        uint32_t pdf14_trans_buffer_size =
9179
3.46k
              (ESTIMATED_PDF14_ROW_SPACE(max(1, target->width),
9180
3.46k
                                         target->color_info.num_components,
9181
3.46k
                                         deep ? 16 : 8) >> 3);
9182
9183
3.46k
        if (target->height < max_ulong / pdf14_trans_buffer_size)
9184
3.46k
                pdf14_trans_buffer_size *= target->height;
9185
0
        else
9186
0
                max_bitmap = 0;     /* Force decision to clist */
9187
3.46k
        if (pdf14_trans_buffer_size > max_bitmap)
9188
3.23k
            use_pdf14_accum = true;
9189
3.46k
    }
9190
958k
    code = dev_proc(target, get_profile)(target,  &dev_profile);
9191
958k
    if (code < 0)
9192
0
        return code;
9193
958k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9194
958k
                          &render_cond);
9195
958k
    if_debug0m('v', mem, "[v]gs_pdf14_device_push\n");
9196
9197
    /* Get the proto from which to copy the device. This will always
9198
     * ignore tags! */
9199
958k
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
9200
958k
                                  pdf14pct, use_pdf14_accum);
9201
958k
    if (code < 0)
9202
0
        return code;
9203
958k
    code = gs_copydevice((gx_device **) &p14dev,
9204
958k
                         (const gx_device *) &dev_proto, mem);
9205
958k
    if (code < 0)
9206
0
        return code;
9207
9208
958k
    p14dev->graphics_type_tag = target->graphics_type_tag;
9209
9210
    /* Copying the params across will add tags to the colorinfo as required. */
9211
958k
    code = gs_pdf14_device_copy_params((gx_device *)p14dev, target);
9212
958k
    if (code < 0)
9213
0
        return code;
9214
9215
958k
    gx_device_set_target((gx_device_forward *)p14dev, target);
9216
958k
    p14dev->pad = target->pad;
9217
958k
    p14dev->log2_align_mod = target->log2_align_mod;
9218
958k
    if (target->num_planar_planes == 0)
9219
890k
        p14dev->num_planar_planes = 0;
9220
67.7k
    else
9221
67.7k
        p14dev->num_planar_planes = p14dev->color_info.num_components;
9222
958k
    p14dev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
9223
9224
958k
    p14dev->alpha = 1.0;
9225
958k
    p14dev->shape = 1.0;
9226
958k
    p14dev->opacity = 1.0;
9227
958k
    p14dev->fillconstantalpha = 1.0;
9228
958k
    p14dev->strokeconstantalpha = 1.0;
9229
9230
    /* Simulated overprint case.  We have to use CMYK-based profile.  Also if the target
9231
       profile is NCLR, we are going to use a pdf14 device that is CMYK based and
9232
       do the mapping to the NCLR profile when the put_image occurs */
9233
958k
    if ((p14dev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
9234
958k
        icc_profile->data_cs == gsNCHANNEL) {
9235
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "gs_pdf14_device_push");
9236
0
        gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9237
0
            -1, "gs_pdf14_device_push");
9238
0
        p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
9239
958k
    } else {
9240
        /* If the target profile was CIELAB (and we are not using a blend CS),
9241
           then overide with default RGB for proper blending.  During put_image
9242
           we will convert from RGB to CIELAB.  Need to check that we have a
9243
           default profile, which will not be the case if we are coming from the clist reader */
9244
958k
        if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab)
9245
0
            && pgs->icc_manager->default_rgb != NULL &&
9246
0
            p14dev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
9247
0
            p14dev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
9248
0
            gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "gs_pdf14_device_push");
9249
0
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9250
0
                -1, "gs_pdf14_device_push");
9251
0
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_rgb;
9252
0
        }
9253
958k
    }
9254
9255
958k
    if (pdf14pct->params.overprint_sim_push &&
9256
0
        pdf14pct->params.num_spot_colors_int > 0) {
9257
0
        p14dev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
9258
0
        p14dev->procs.ret_devn_params = pdf14_ret_devn_params;
9259
0
        p14dev->op_pequiv_cmyk_colors.all_color_info_valid = false;
9260
0
        p14dev->target_support_devn = p14dev->icc_struct->supports_devn;
9261
0
        p14dev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
9262
0
    }
9263
9264
    /* The number of color planes should not exceed that of the target.
9265
       Unless we are using a blend CS */
9266
958k
    if (!(p14dev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || p14dev->overprint_sim)) {
9267
958k
        if (p14dev->color_info.num_components > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev)) {
9268
0
            p14dev->color_info.num_components = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev);
9269
0
            if (p14dev->num_planar_planes != 0)
9270
0
                p14dev->num_planar_planes = p14dev->color_info.num_components;
9271
0
        }
9272
958k
        if (p14dev->color_info.max_components > target->color_info.max_components)
9273
67.6k
            p14dev->color_info.max_components = target->color_info.max_components;
9274
958k
    }
9275
958k
    p14dev->color_info.depth = p14dev->color_info.num_components * (8<<deep);
9276
    /* If we have a tag device then go ahead and do a special encoder
9277
       decoder for the pdf14 device to make sure we maintain this
9278
       information in the encoded color information.  We could use
9279
       the target device's methods but the PDF14 device has to maintain
9280
       8 bit color always and we could run into other issues if the number
9281
       of colorants became large.  If we need to do compressed color with
9282
       tags that will be a special project at that time */
9283
958k
    if (deep) {
9284
0
        set_dev_proc(p14dev, encode_color, pdf14_encode_color16);
9285
0
        set_dev_proc(p14dev, decode_color, pdf14_decode_color16);
9286
0
    }
9287
958k
    if (has_tags) {
9288
0
        set_dev_proc(p14dev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
9289
0
    }
9290
    /* if the device has separations already defined (by SeparationOrderNames) */
9291
    /* we need to copy them (allocating new names) so the colorants are in the */
9292
    /* same order as the target device.                                        */
9293
958k
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
9294
67.7k
        code = devn_copy_params(target, (gx_device *)p14dev);
9295
67.7k
        if (code < 0) {
9296
50
            *pdev = NULL;
9297
50
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9298
50
            rc_decrement(p14dev, "gs_pdf14_device_push");
9299
50
            return code;
9300
50
        }
9301
67.7k
    }
9302
    /* by definition pdf14_encode _is_ standard */
9303
958k
    p14dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
9304
958k
    gx_device_fill_in_procs((gx_device *)p14dev);
9305
958k
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
9306
958k
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
9307
958k
    gx_set_cmap_procs(pgs, (gx_device *)p14dev);
9308
9309
    /* Components shift, etc have to be based upon 8 (or 16) bit */
9310
3.19M
    for (k = 0; k < p14dev->color_info.num_components; k++) {
9311
2.23M
        p14dev->color_info.comp_bits[k] = 8<<deep;
9312
2.23M
        p14dev->color_info.comp_shift[k] =
9313
2.23M
                            (p14dev->color_info.num_components - 1 - k) * (8<<deep);
9314
2.23M
    }
9315
958k
    if (use_pdf14_accum) {
9316
        /* we will disable this device later, but we don't want to allocate large buffers */
9317
3.23k
        p14dev->width = 1;
9318
3.23k
        p14dev->height = 1;
9319
3.23k
    }
9320
9321
958k
    p14dev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
9322
958k
    code = dev_proc((gx_device *) p14dev, open_device) ((gx_device *) p14dev);
9323
958k
    *pdev = (gx_device *) p14dev;
9324
958k
    pdf14_set_marking_params((gx_device *)p14dev, pgs);
9325
958k
    p14dev->color_model_stack = NULL;
9326
9327
    /* In case we have alphabits set */
9328
958k
    p14dev->color_info.anti_alias = target->color_info.anti_alias;
9329
9330
958k
    if (pdf14pct->params.is_pattern) {
9331
7.02k
        code = pdf14_initialize_ctx((gx_device*)p14dev, pgs);
9332
7.02k
        if (code < 0) {
9333
0
            *pdev = NULL;
9334
0
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9335
0
            rc_decrement(p14dev, "gs_pdf14_device_push");
9336
0
            return code;
9337
0
        }
9338
7.02k
    }
9339
9340
    /* We should never go into this when using a blend color space */
9341
958k
    if (use_pdf14_accum) {
9342
3.23k
        const gx_device_pdf14_accum *accum_proto = NULL;
9343
3.23k
        gx_device *new_target = NULL;
9344
3.23k
        gx_device_color pdcolor;
9345
3.23k
        frac pconc_white = frac_1;
9346
3.23k
        bool UsePlanarBuffer = false;
9347
9348
3.23k
        if_debug0m('v', mem, "[v]gs_pdf14_device_push: Inserting clist device.\n");
9349
9350
        /* get the prototype for the accumulator device based on colorspace */
9351
3.23k
        switch (target->color_info.max_components) { /* use max_components in case is devn device */
9352
672
            case 1:
9353
672
                accum_proto = &pdf14_accum_Gray;
9354
672
                break;
9355
2.56k
            case 3:
9356
2.56k
                accum_proto = &pdf14_accum_RGB;
9357
2.56k
                break;
9358
0
            case 4:
9359
0
                accum_proto = &pdf14_accum_CMYK;
9360
0
                break;
9361
0
            default:
9362
0
                accum_proto = &pdf14_accum_CMYKspot;
9363
0
                UsePlanarBuffer = true;
9364
3.23k
        }
9365
3.23k
        if (accum_proto == NULL ||
9366
3.23k
            (code = gs_copydevice(&new_target, (gx_device *)accum_proto, mem->stable_memory)) < 0)
9367
0
            goto no_clist_accum;
9368
9369
3.23k
        ((gx_device_pdf14_accum *)new_target)->save_p14dev = (gx_device *)p14dev;  /* non-clist p14dev */
9370
        /* Fill in values from the target device before opening */
9371
3.23k
        new_target->color_info = p14dev->color_info;
9372
3.23k
        ((gx_device_pdf14_accum *)new_target)->devn_params = p14dev->devn_params;
9373
3.23k
        new_target->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
9374
3.23k
        set_linear_color_bits_mask_shift(new_target);
9375
3.23k
        gs_pdf14_device_copy_params(new_target, target);
9376
3.23k
        ((gx_device_pdf14_accum *)new_target)->page_uses_transparency = true;
9377
3.23k
        gx_device_fill_in_procs(new_target);
9378
9379
3.23k
        memcpy(&(new_target->space_params), &(target->space_params), sizeof(gdev_space_params));
9380
3.23k
        max_bitmap = max(target->space_params.MaxBitmap, target->space_params.BufferSpace);
9381
3.23k
        ((gx_device_pdf14_accum *)new_target)->space_params.BufferSpace = max_bitmap;
9382
9383
        /* This is used to mark the various internal subclass devices as having already
9384
         * been pushed, so that opening the device won't result in us trying to push
9385
         * them again, which leads to trouble.
9386
         */
9387
3.23k
        code = mark_internal_subclass_devices(new_target);
9388
3.23k
        if (code < 0)
9389
0
            return code;
9390
9391
        /* if the device has separations already defined (by SeparationOrderNames) */
9392
        /* we need to copy them (allocating new names) so the colorants are in the */
9393
        /* same order as the target device.                                        */
9394
3.23k
        if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
9395
0
            code = devn_copy_params(target, (gx_device *)*pdev);
9396
0
            if (code < 0)
9397
0
                return code;
9398
0
        }
9399
        /* UsePlanarBuffer is true in case this is CMYKspot */
9400
3.23k
        if ((code = gdev_prn_open_planar(new_target, UsePlanarBuffer ? new_target->color_info.num_components : 0)) < 0 ||
9401
3.23k
             !PRINTER_IS_CLIST((gx_device_printer *)new_target)) {
9402
0
            gs_free_object(mem->stable_memory, new_target, "pdf14-accum");
9403
0
            goto no_clist_accum;
9404
0
        }
9405
        /* Do the initial fillpage into the pdf14-accum device we just created */
9406
3.23k
        dev_proc(new_target, set_graphics_type_tag)((gx_device *)new_target, GS_UNTOUCHED_TAG);
9407
3.23k
        if ((code = gx_remap_concrete_DGray(gs_currentcolorspace_inline((gs_gstate *)pgs),
9408
3.23k
                                            &pconc_white,
9409
3.23k
                                            &pdcolor, pgs, new_target, gs_color_select_all,
9410
3.23k
                                            dev_profile)) < 0)
9411
0
            goto no_clist_accum;
9412
9413
3.23k
        (*dev_proc(new_target, fillpage))(new_target, pgs, &pdcolor);
9414
3.23k
        code = clist_composite(new_target, pdev, (gs_composite_t *)pdf14pct, pgs, mem, NULL);
9415
3.23k
        if (code < 0)
9416
0
            goto no_clist_accum;
9417
9418
3.23k
        pdf14_disable_device((gx_device *)p14dev);           /* make the non-clist device forward */
9419
3.23k
        pdf14_close((gx_device *)p14dev);                    /* and free up the little memory it had */
9420
3.23k
    }
9421
958k
    return code;
9422
9423
0
no_clist_accum:
9424
        /* FIXME: We allocated a really small p14dev, but that won't work */
9425
0
    return gs_throw_code(gs_error_Fatal); /* punt for now */
9426
958k
}
9427
9428
/*
9429
 * In a modest violation of good coding practice, the gs_composite_common
9430
 * fields are "known" to be simple (contain no pointers to garbage
9431
 * collected memory), and we also know the gs_pdf14trans_params_t structure
9432
 * to be simple, so we just create a trivial structure descriptor for the
9433
 * entire gs_pdf14trans_s structure.
9434
 */
9435
#define private_st_gs_pdf14trans_t()\
9436
  gs_private_st_ptrs2(st_pdf14trans, gs_pdf14trans_t, "gs_pdf14trans_t",\
9437
      st_pdf14trans_enum_ptrs, st_pdf14trans_reloc_ptrs, params.transfer_function, params.iccprofile)
9438
9439
/* GC descriptor for gs_pdf14trans_t */
9440
private_st_gs_pdf14trans_t();
9441
9442
/*
9443
 * Check for equality of two PDF 1.4 transparency compositor objects.
9444
 *
9445
 * We are currently always indicating that PDF 1.4 transparency compositors are
9446
 * equal.  Two transparency compositors may have teh same data but still
9447
 * represent separate actions.  (E.g. two PDF14_BEGIN_TRANS_GROUP compositor
9448
 * operations in a row mean that we are creating a group inside of a group.
9449
 */
9450
static  bool
9451
c_pdf14trans_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
9452
0
{
9453
0
    return false;
9454
0
}
9455
9456
#ifdef DEBUG
9457
static const char * pdf14_opcode_names[] = PDF14_OPCODE_NAMES;
9458
#endif
9459
9460
#define put_value(dp, value)\
9461
5.91M
    BEGIN\
9462
5.91M
        memcpy(dp, &value, sizeof(value));\
9463
5.91M
        dp += sizeof(value);\
9464
5.91M
    END
9465
9466
static inline int
9467
c_pdf14trans_write_ctm(byte **ppbuf, const gs_pdf14trans_params_t *pparams)
9468
728k
{
9469
    /* Note: We can't skip writing CTM if it is equal to pgs->ctm,
9470
       because clist writer may skip this command for some bands.
9471
       For a better result we need individual CTM for each band.
9472
     */
9473
728k
    byte *pbuf = *ppbuf;
9474
728k
    int len, code;
9475
9476
728k
    len = cmd_write_ctm_return_length_nodevice(&pparams->ctm);
9477
728k
    pbuf--; /* For cmd_write_ctm. */
9478
728k
    code = cmd_write_ctm(&pparams->ctm, pbuf, len);
9479
728k
    if (code < 0)
9480
0
        return code;
9481
728k
    pbuf += len + 1;
9482
728k
    *ppbuf = pbuf;
9483
728k
    return 0;
9484
728k
}
9485
9486
/*
9487
 * Convert a PDF 1.4 transparency compositor to string form for use by the command
9488
 * list device. This is also where we update the pdf14_needed. When set the clist
9489
 * painting procs will update the trans_bbox state for bands that are affected.
9490
*/
9491
static  int
9492
c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
9493
                   gx_device_clist_writer *cdev)
9494
1.68M
{
9495
1.68M
    const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
9496
1.68M
    int need, avail = *psize;
9497
1.68M
    byte buf[MAX_CLIST_TRANSPARENCY_BUFFER_SIZE]; /* Must be large enough
9498
        to fit the data written below. We don't implement a dynamic check for
9499
        the buffer owerflow, assuming that the consistency is verified in the
9500
        coding phase. See the definition of MAX_CLIST_TRANSPARENCY_BUFFER_SIZE. */
9501
1.68M
    byte * pbuf = buf;
9502
1.68M
    int opcode = pparams->pdf14_op;
9503
1.68M
    int mask_size = 0;
9504
1.68M
    uint mask_id = 0;
9505
1.68M
    int code;
9506
1.68M
    bool found_icc;
9507
1.68M
    int64_t hashcode = 0;
9508
1.68M
    cmm_profile_t *icc_profile;
9509
1.68M
    gsicc_rendering_param_t render_cond;
9510
1.68M
    cmm_dev_profile_t *dev_profile;
9511
    /* We maintain and update working copies until we actually write the clist */
9512
1.68M
    int pdf14_needed = cdev->pdf14_needed;
9513
1.68M
    int trans_group_level = cdev->pdf14_trans_group_level;
9514
1.68M
    int smask_level = cdev->pdf14_smask_level;
9515
1.68M
    bool deep = device_is_deep((gx_device *)cdev);
9516
9517
1.68M
    code = dev_proc((gx_device *) cdev, get_profile)((gx_device *) cdev,
9518
1.68M
                                                     &dev_profile);
9519
1.68M
    if (code < 0)
9520
0
        return code;
9521
1.68M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9522
1.68M
                          &render_cond);
9523
1.68M
    *pbuf++ = opcode;     /* 1 byte */
9524
1.68M
    if (trans_group_level < 0 && opcode != PDF14_PUSH_DEVICE)
9525
0
        return_error(gs_error_unregistered);  /* prevent spurious transparency ops (Bug 702327) */
9526
9527
1.68M
    switch (opcode) {
9528
0
        default:      /* Should not occur. */
9529
0
            break;
9530
18.8k
        case PDF14_PUSH_DEVICE:
9531
18.8k
            trans_group_level = 0;
9532
18.8k
            cdev->pdf14_smask_level = 0;
9533
18.8k
            cdev->page_pdf14_needed = false;
9534
18.8k
            put_value(pbuf, pparams->num_spot_colors);
9535
18.8k
            put_value(pbuf, pparams->num_spot_colors_int);
9536
18.8k
            put_value(pbuf, pparams->overprint_sim_push);
9537
18.8k
            put_value(pbuf, pparams->is_pattern);
9538
9539
            /* If we happen to be going to a color space like CIELAB then
9540
               we are going to do our blending in default RGB and convert
9541
               to CIELAB at the end.  To do this, we need to store the
9542
               default RGB profile in the clist so that we can grab it
9543
               later on during the clist read back and put image command */
9544
18.8k
            if (icc_profile->data_cs == gsCIELAB || icc_profile->islab) {
9545
                /* Get the default RGB profile.  Set the device hash code
9546
                   so that we can extract it during the put_image operation. */
9547
0
                cdev->trans_dev_icc_hash = gsicc_get_hash(pparams->iccprofile);
9548
0
                found_icc =
9549
0
                    clist_icc_searchtable(cdev, gsicc_get_hash(pparams->iccprofile));
9550
0
                if (!found_icc) {
9551
                    /* Add it to the table */
9552
0
                    clist_icc_addentry(cdev, gsicc_get_hash(pparams->iccprofile),
9553
0
                                       pparams->iccprofile);
9554
0
                }
9555
0
            }
9556
18.8k
            break;
9557
17.8k
        case PDF14_POP_DEVICE:
9558
17.8k
            pdf14_needed = false;   /* reset pdf14_needed */
9559
17.8k
            trans_group_level = -1;   /* reset so we need to PUSH_DEVICE next */
9560
17.8k
            smask_level = 0;
9561
17.8k
            put_value(pbuf, pparams->is_pattern);
9562
17.8k
            break;
9563
392k
        case PDF14_END_TRANS_GROUP:
9564
397k
        case PDF14_END_TRANS_TEXT_GROUP:
9565
397k
            trans_group_level--;  /* if now at page level, pdf14_needed will be updated */
9566
397k
            if (smask_level == 0 && trans_group_level == 0)
9567
23.2k
                pdf14_needed = cdev->page_pdf14_needed;
9568
397k
            break;      /* No data */
9569
6.63k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9570
397k
        case PDF14_BEGIN_TRANS_GROUP:
9571
397k
            pdf14_needed = true;   /* the compositor will be needed while reading */
9572
397k
            trans_group_level++;
9573
397k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9574
397k
            if (code < 0)
9575
0
                return code;
9576
397k
            *pbuf++ = (pparams->Isolated & 1) + ((pparams->Knockout & 1) << 1);
9577
397k
            *pbuf++ = pparams->blend_mode;
9578
397k
            *pbuf++ = pparams->group_color_type;
9579
397k
            *pbuf++ = pparams->page_group;
9580
397k
            put_value(pbuf, pparams->group_color_numcomps);
9581
397k
            put_value(pbuf, pparams->opacity);
9582
397k
            put_value(pbuf, pparams->shape);
9583
397k
            put_value(pbuf, pparams->bbox);
9584
397k
            put_value(pbuf, pparams->shade_group);
9585
397k
            put_value(pbuf, pparams->text_group);
9586
397k
            mask_id = pparams->mask_id;
9587
397k
            put_value(pbuf, mask_id);
9588
            /* Color space information maybe ICC based
9589
               in this case we need to store the ICC
9590
               profile or the ID if it is cached already */
9591
397k
            if (pparams->group_color_type == ICC) {
9592
                /* Check if it is already in the ICC clist table */
9593
10.8k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9594
10.8k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9595
10.8k
                if (!found_icc) {
9596
                    /* Add it to the table */
9597
3.53k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9598
3.53k
                    put_value(pbuf, hashcode);
9599
7.29k
                } else {
9600
                    /* It will be in the clist. Just write out the hashcode */
9601
7.29k
                    put_value(pbuf, hashcode);
9602
7.29k
                }
9603
386k
            } else {
9604
386k
                put_value(pbuf, hashcode);
9605
386k
            }
9606
397k
            break;
9607
330k
        case PDF14_BEGIN_TRANS_MASK:
9608
330k
            if (pparams->subtype != TRANSPARENCY_MASK_None) {
9609
281k
                pdf14_needed = true;   /* the compositor will be needed while reading */
9610
281k
                smask_level++;
9611
281k
            }
9612
330k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9613
330k
            if (code < 0)
9614
0
                return code;
9615
330k
            put_value(pbuf, pparams->subtype);
9616
330k
            *pbuf++ = pparams->group_color_type;
9617
330k
            put_value(pbuf, pparams->group_color_numcomps);
9618
330k
            *pbuf++ = pparams->replacing;
9619
330k
            *pbuf++ = (pparams->function_is_identity) | (deep<<1);
9620
330k
            *pbuf++ = pparams->Background_components;
9621
330k
            *pbuf++ = pparams->Matte_components;
9622
330k
            put_value(pbuf, pparams->bbox);
9623
330k
            mask_id = pparams->mask_id;
9624
330k
            put_value(pbuf, mask_id);
9625
330k
            if (pparams->Background_components) {
9626
1.04k
                const int l = sizeof(pparams->Background[0]) * pparams->Background_components;
9627
9628
1.04k
                memcpy(pbuf, pparams->Background, l);
9629
1.04k
                pbuf += l;
9630
1.04k
                memcpy(pbuf, &pparams->GrayBackground, sizeof(pparams->GrayBackground));
9631
1.04k
                pbuf += sizeof(pparams->GrayBackground);
9632
1.04k
            }
9633
330k
            if (pparams->Matte_components) {
9634
46
                const int m = sizeof(pparams->Matte[0]) * pparams->Matte_components;
9635
9636
46
                memcpy(pbuf, pparams->Matte, m);
9637
46
                pbuf += m;
9638
46
            }
9639
330k
            if (!pparams->function_is_identity)
9640
1.23k
                mask_size = (256+deep)<<deep;
9641
            /* Color space information may be ICC based
9642
               in this case we need to store the ICC
9643
               profile or the ID if it is cached already */
9644
330k
            if (pparams->group_color_type == ICC) {
9645
                /* Check if it is already in the ICC clist table */
9646
281k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9647
281k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9648
281k
                if (!found_icc) {
9649
                    /* Add it to the table */
9650
2.18k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9651
2.18k
                    put_value(pbuf, hashcode);
9652
279k
                } else {
9653
                    /* It will be in the clist. Just write out the hashcode */
9654
279k
                    put_value(pbuf, hashcode);
9655
279k
                }
9656
281k
            } else {
9657
48.7k
                put_value(pbuf, hashcode);
9658
48.7k
            }
9659
330k
            break;
9660
281k
        case PDF14_END_TRANS_MASK:
9661
281k
            smask_level--;
9662
281k
            if (smask_level == 0 && trans_group_level == 0)
9663
6.58k
                pdf14_needed = cdev->page_pdf14_needed;
9664
281k
            break;
9665
194k
        case PDF14_SET_BLEND_PARAMS:
9666
194k
            if (pparams->blend_mode != BLEND_MODE_Normal || pparams->opacity != 1.0 ||
9667
0
                pparams->shape != 1.0)
9668
194k
                pdf14_needed = true;    /* the compositor will be needed while reading */
9669
0
            else if (smask_level == 0 && trans_group_level == 0)
9670
0
                pdf14_needed = false;   /* At page level, set back to false */
9671
194k
            if (smask_level == 0 && trans_group_level == 0)
9672
69.6k
                cdev->page_pdf14_needed = pdf14_needed;         /* save for after popping to page level */
9673
            /* Changed is now two bytes due to overprint stroke fill. Write as int */
9674
194k
            put_value(pbuf, pparams->changed);
9675
194k
            if (pparams->changed & PDF14_SET_BLEND_MODE)
9676
35.0k
                *pbuf++ = pparams->blend_mode;
9677
194k
            if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
9678
17.1k
                *pbuf++ = pparams->text_knockout;
9679
194k
            if (pparams->changed & PDF14_SET_AIS)
9680
194k
                put_value(pbuf, pparams->ais);
9681
194k
            if (pparams->changed & PDF14_SET_OVERPRINT)
9682
194k
                put_value(pbuf, pparams->overprint);
9683
194k
            if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
9684
194k
                put_value(pbuf, pparams->stroke_overprint);
9685
194k
            if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
9686
194k
                put_value(pbuf, pparams->fillconstantalpha);
9687
194k
            if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
9688
194k
                put_value(pbuf, pparams->strokeconstantalpha);
9689
194k
            if (pparams->changed & PDF14_SET_FILLSTROKE_STATE)
9690
194k
                put_value(pbuf, pparams->op_fs_state);
9691
194k
            break;
9692
0
        case PDF14_PUSH_TRANS_STATE:
9693
0
            break;
9694
41.2k
        case PDF14_POP_TRANS_STATE:
9695
41.2k
            break;
9696
0
        case PDF14_PUSH_SMASK_COLOR:
9697
0
            return 0;   /* We really should never be here */
9698
0
            break;
9699
0
        case PDF14_POP_SMASK_COLOR:
9700
0
            return 0;   /* We really should never be here */
9701
0
            break;
9702
1.68M
    }
9703
9704
    /* check for fit */
9705
1.68M
    need = (pbuf - buf) + mask_size;
9706
1.68M
    *psize = need;
9707
1.68M
    if (need > avail) {
9708
255k
        if (avail)
9709
0
            return_error(gs_error_rangecheck);
9710
255k
        else
9711
255k
            return gs_error_rangecheck;
9712
255k
    }
9713
9714
    /* If we are writing more than the maximum ever expected,
9715
     * return a rangecheck error. Second check is for Coverity
9716
     */
9717
1.42M
    if ((need + 3 > MAX_CLIST_COMPOSITOR_SIZE) ||
9718
1.42M
        (need + 3 - mask_size > MAX_CLIST_TRANSPARENCY_BUFFER_SIZE) )
9719
0
        return_error(gs_error_rangecheck);
9720
9721
    /* Copy our serialized data into the output buffer */
9722
1.42M
    memcpy(data, buf, need - mask_size);
9723
1.42M
    if (mask_size)  /* Include the transfer mask data if present */
9724
948
        memcpy(data + need - mask_size, pparams->transfer_fn, mask_size);
9725
1.42M
    if_debug3m('v', cdev->memory,
9726
1.42M
               "[v] c_pdf14trans_write: opcode = %s mask_id=%d need = %d\n",
9727
1.42M
               pdf14_opcode_names[opcode], mask_id, need);
9728
1.42M
    cdev->pdf14_needed = pdf14_needed;          /* all OK to update */
9729
1.42M
    cdev->pdf14_trans_group_level = trans_group_level;
9730
1.42M
    cdev->pdf14_smask_level = smask_level;
9731
1.42M
    return 0;
9732
1.42M
}
9733
9734
#undef put_value
9735
9736
/* Function prototypes */
9737
static int gs_create_pdf14trans( gs_composite_t ** ppct,
9738
                const gs_pdf14trans_params_t * pparams,
9739
                gs_memory_t * mem );
9740
9741
#define read_value(dp, value)\
9742
108M
    BEGIN\
9743
108M
        memcpy(&value, dp, sizeof(value));\
9744
108M
        dp += sizeof(value);\
9745
108M
    END
9746
9747
/*
9748
 * Convert the string representation of the PDF 1.4 transparency parameter
9749
 * into the full compositor.
9750
 */
9751
static  int
9752
c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
9753
                                uint size, gs_memory_t * mem )
9754
32.8M
{
9755
32.8M
    gs_pdf14trans_params_t params = {0};
9756
32.8M
    const byte * start = data;
9757
32.8M
    int used, code = 0;
9758
32.8M
    bool deep;
9759
9760
32.8M
    if (size < 1)
9761
0
        return_error(gs_error_rangecheck);
9762
9763
    /* Read PDF 1.4 compositor data from the clist */
9764
32.8M
    params.pdf14_op = *data++;
9765
32.8M
    if_debug2m('v', mem, "[v] c_pdf14trans_read: opcode = %s  avail = %d",
9766
32.8M
               pdf14_opcode_names[params.pdf14_op], size);
9767
32.8M
    memset(&params.ctm, 0, sizeof(params.ctm));
9768
32.8M
    switch (params.pdf14_op) {
9769
0
        default:      /* Should not occur. */
9770
0
            break;
9771
1.49M
        case PDF14_PUSH_DEVICE:
9772
1.49M
            read_value(data, params.num_spot_colors);
9773
1.49M
            read_value(data, params.num_spot_colors_int);
9774
1.49M
            read_value(data, params.overprint_sim_push);
9775
1.49M
            read_value(data, params.is_pattern);
9776
1.49M
            break;
9777
0
        case PDF14_ABORT_DEVICE:
9778
0
            break;
9779
1.49M
        case PDF14_POP_DEVICE:
9780
1.49M
            read_value(data, params.is_pattern);
9781
1.49M
            break;
9782
1.96M
        case PDF14_END_TRANS_GROUP:
9783
2.38M
        case PDF14_END_TRANS_TEXT_GROUP:
9784
#ifdef DEBUG
9785
            code += 0; /* A good place for a breakpoint. */
9786
#endif
9787
2.38M
            break;      /* No data */
9788
0
        case PDF14_PUSH_TRANS_STATE:
9789
0
            break;
9790
2.89M
        case PDF14_POP_TRANS_STATE:
9791
2.89M
            break;
9792
579k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9793
2.38M
        case PDF14_BEGIN_TRANS_GROUP:
9794
            /*
9795
             * We are currently not using the bbox or the colorspace so they were
9796
             * not placed in the clist
9797
             */
9798
2.38M
            data = cmd_read_matrix(&params.ctm, data);
9799
2.38M
            params.Isolated = (*data) & 1;
9800
2.38M
            params.Knockout = (*data++ >> 1) & 1;
9801
2.38M
            params.blend_mode = *data++;
9802
2.38M
            params.group_color_type = *data++;  /* Trans group color */
9803
2.38M
            params.page_group = *data++;
9804
2.38M
            read_value(data,params.group_color_numcomps);  /* color group size */
9805
2.38M
            read_value(data, params.opacity);
9806
2.38M
            read_value(data, params.shape);
9807
2.38M
            read_value(data, params.bbox);
9808
2.38M
            read_value(data, params.shade_group);
9809
2.38M
            read_value(data, params.text_group);
9810
2.38M
            read_value(data, params.mask_id);
9811
2.38M
            read_value(data, params.icc_hash);
9812
2.38M
            break;
9813
4.28M
        case PDF14_BEGIN_TRANS_MASK:
9814
                /* This is the largest transparency parameter at this time (potentially
9815
                 * 1531 bytes in size if Background_components =
9816
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and Matte_components =
9817
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and we have a transfer function as well).
9818
                 *
9819
                 * NOTE:
9820
                 * The clist reader must be able to handle this sized device.
9821
                 * If any changes are made here the #define MAX_CLIST_COMPOSITOR_SIZE
9822
                 * may also need to be changed correspondingly (defined in gstparam.h)
9823
                 * Also... if another compositor param should exceed this size, this
9824
                 * same condition applies.
9825
                 */
9826
4.28M
            data = cmd_read_matrix(&params.ctm, data);
9827
4.28M
            read_value(data, params.subtype);
9828
4.28M
            params.group_color_type = *data++;
9829
4.28M
            read_value(data, params.group_color_numcomps);
9830
4.28M
            params.replacing = *data++;
9831
4.28M
            params.function_is_identity = *data & 1;
9832
4.28M
            deep = (*data++)>>1;
9833
4.28M
            params.Background_components = *data++;
9834
4.28M
            params.Matte_components = *data++;
9835
4.28M
            read_value(data, params.bbox);
9836
4.28M
            read_value(data, params.mask_id);
9837
4.28M
            if (params.Background_components) {
9838
79.9k
                const int l = sizeof(params.Background[0]) * params.Background_components;
9839
9840
79.9k
                memcpy(params.Background, data, l);
9841
79.9k
                data += l;
9842
79.9k
                memcpy(&params.GrayBackground, data, sizeof(params.GrayBackground));
9843
79.9k
                data += sizeof(params.GrayBackground);
9844
79.9k
            }
9845
4.28M
            if (params.Matte_components) {
9846
3.20k
                const int m = sizeof(params.Matte[0]) * params.Matte_components;
9847
9848
3.20k
                memcpy(params.Matte, data, m);
9849
3.20k
                data += m;
9850
3.20k
            }
9851
4.28M
            read_value(data, params.icc_hash);
9852
4.28M
            if (params.function_is_identity) {
9853
4.24M
                int i;
9854
9855
4.24M
                if (deep) {
9856
0
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++)
9857
0
                        ((uint16_t *)params.transfer_fn)[i] = i*0x10000/MASK_TRANSFER_FUNCTION_SIZE;
9858
0
                    ((uint16_t *)params.transfer_fn)[i] = 0xffff;
9859
4.24M
                } else {
9860
1.09G
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
9861
1.08G
                        params.transfer_fn[i] = (byte)floor(i *
9862
1.08G
                            (255.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)) + 0.5);
9863
1.08G
                    }
9864
4.24M
                }
9865
4.24M
            } else {
9866
32.1k
                memcpy(params.transfer_fn, data, (256+deep)<<deep);
9867
32.1k
                data += (256+deep)<<deep;
9868
32.1k
            }
9869
4.28M
            break;
9870
412k
        case PDF14_END_TRANS_MASK:
9871
412k
            break;
9872
0
        case PDF14_PUSH_SMASK_COLOR:
9873
0
            return 0;
9874
0
            break;
9875
0
        case PDF14_POP_SMASK_COLOR:
9876
0
            return 0;
9877
0
            break;
9878
17.5M
        case PDF14_SET_BLEND_PARAMS:
9879
17.5M
            read_value(data, params.changed);
9880
17.5M
            if (params.changed & PDF14_SET_BLEND_MODE)
9881
3.20M
                params.blend_mode = *data++;
9882
17.5M
            if (params.changed & PDF14_SET_TEXT_KNOCKOUT)
9883
1.44M
                params.text_knockout = *data++;
9884
17.5M
            if (params.changed & PDF14_SET_AIS)
9885
17.5M
                read_value(data, params.ais);
9886
17.5M
            if (params.changed & PDF14_SET_OVERPRINT)
9887
17.5M
                read_value(data, params.overprint);
9888
17.5M
            if (params.changed & PDF14_SET_STROKEOVERPRINT)
9889
17.5M
                read_value(data, params.stroke_overprint);
9890
17.5M
            if (params.changed & PDF14_SET_FILLCONSTANTALPHA)
9891
17.5M
                read_value(data, params.fillconstantalpha);
9892
17.5M
            if (params.changed & PDF14_SET_STROKECONSTANTALPHA)
9893
17.5M
                read_value(data, params.strokeconstantalpha);
9894
17.5M
            if (params.changed & PDF14_SET_FILLSTROKE_STATE)
9895
17.5M
                read_value(data, params.op_fs_state);
9896
17.5M
            break;
9897
32.8M
    }
9898
32.8M
    code = gs_create_pdf14trans(ppct, &params, mem);
9899
32.8M
    if (code < 0)
9900
0
        return code;
9901
32.8M
    used = data - start;
9902
32.8M
    if_debug2m('v', mem, " mask_id=%d used = %d\n", params.mask_id, used);
9903
9904
    /* If we read more than the maximum expected, return a rangecheck error */
9905
32.8M
    if ( used + 3 > MAX_CLIST_COMPOSITOR_SIZE )
9906
0
        return_error(gs_error_rangecheck);
9907
32.8M
    else
9908
32.8M
        return used;
9909
32.8M
}
9910
9911
/*
9912
 * Adjust the compositor's CTM.
9913
 */
9914
static int
9915
c_pdf14trans_adjust_ctm(gs_composite_t * pct0, int x0, int y0, gs_gstate *pgs)
9916
20.1M
{
9917
20.1M
    gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pct0;
9918
20.1M
    gs_matrix mat = pct->params.ctm;
9919
9920
20.1M
    if_debug6m('L', pgs->memory, " [%g %g %g %g %g %g]\n",
9921
20.1M
               mat.xx, mat.xy, mat.yx, mat.yy,
9922
20.1M
               mat.tx, mat.ty);
9923
20.1M
    mat.tx -= x0;
9924
20.1M
    mat.ty -= y0;
9925
20.1M
    gs_gstate_setmatrix(pgs, &mat);
9926
20.1M
    return 0;
9927
20.1M
}
9928
9929
/*
9930
 * Create a PDF 1.4 transparency compositor.
9931
 *
9932
 * Note that this routine will be called only if the device is not already
9933
 * a PDF 1.4 transparency compositor.
9934
 * Return an error if it is not a PDF14_PUSH_DEVICE operation.
9935
 */
9936
static  int
9937
c_pdf14trans_create_default_compositor(const gs_composite_t * pct,
9938
    gx_device ** pp14dev, gx_device * tdev, gs_gstate * pgs,
9939
    gs_memory_t * mem)
9940
977k
{
9941
977k
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
9942
977k
    int code = 0;
9943
9944
    /*
9945
     * We only handle the push operation.  All other operations are ignored.
9946
     * The other operations will be handled by the composite routine
9947
     * for the PDF 1.4 compositing device.
9948
     */
9949
977k
    switch (pdf14pct->params.pdf14_op) {
9950
958k
        case PDF14_PUSH_DEVICE:
9951
958k
            code = gs_pdf14_device_push(mem, pgs, pp14dev, tdev, pdf14pct);
9952
            /* Change (non-error) code to 1 to indicate that we created
9953
             * a device. */
9954
958k
            if (code >= 0)
9955
958k
                code = 1;
9956
958k
            break;
9957
19.0k
        default:
9958
            /* No other compositor actions are allowed if this isn't a pdf14 compositor */
9959
19.0k
            *pp14dev = NULL;
9960
19.0k
            return_error(gs_error_unregistered);
9961
977k
    }
9962
958k
    return code;
9963
977k
}
9964
9965
/*
9966
 * Find an opening compositor op.
9967
 */
9968
static gs_compositor_closing_state
9969
find_opening_op(int opening_op, gs_composite_t **ppcte,
9970
                gs_compositor_closing_state return_code)
9971
2.13M
{
9972
    /* Assuming a right *BEGIN* - *END* operation balance. */
9973
2.13M
    gs_composite_t *pcte = *ppcte;
9974
9975
5.01M
    for (;;) {
9976
5.01M
        if (pcte->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
9977
4.67M
            gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pcte;
9978
4.67M
            int op = pct->params.pdf14_op;
9979
9980
4.67M
            *ppcte = pcte;
9981
4.67M
            if (op == opening_op)
9982
1.33M
                return return_code;
9983
3.33M
            if (op != PDF14_SET_BLEND_PARAMS) {
9984
1.98M
                if (opening_op == PDF14_BEGIN_TRANS_MASK)
9985
337
                    return COMP_ENQUEUE;
9986
1.98M
                if (opening_op == PDF14_BEGIN_TRANS_GROUP || opening_op == PDF14_BEGIN_TRANS_PAGE_GROUP) {
9987
234k
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK)
9988
216k
                        return COMP_ENQUEUE;
9989
234k
                }
9990
1.76M
                if (opening_op == PDF14_PUSH_DEVICE) {
9991
1.75M
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK &&
9992
1.71M
                        op != PDF14_BEGIN_TRANS_GROUP && op != PDF14_BEGIN_TRANS_PAGE_GROUP && op != PDF14_END_TRANS_GROUP &&
9993
249k
                        op != PDF14_END_TRANS_TEXT_GROUP)
9994
111k
                        return COMP_ENQUEUE;
9995
1.75M
                }
9996
1.76M
            }
9997
3.33M
        } else
9998
338k
            return COMP_ENQUEUE;
9999
3.00M
        pcte = pcte->prev;
10000
3.00M
        if (pcte == NULL)
10001
129k
            return COMP_EXEC_QUEUE; /* Not in queue. */
10002
3.00M
    }
10003
2.13M
}
10004
10005
/*
10006
 * Find an opening compositor op.
10007
 */
10008
static gs_compositor_closing_state
10009
find_same_op(const gs_composite_t *composite_action, int my_op, gs_composite_t **ppcte)
10010
14.4M
{
10011
14.4M
    const gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10012
14.4M
    gs_composite_t *pct = *ppcte;
10013
10014
14.4M
    for (;;) {
10015
14.4M
        if (pct->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
10016
11.9M
            gs_pdf14trans_t *pct_pdf14 = (gs_pdf14trans_t *)pct;
10017
10018
11.9M
            *ppcte = pct;
10019
11.9M
            if (pct_pdf14->params.pdf14_op != my_op)
10020
3.62M
                return COMP_ENQUEUE;
10021
8.32M
            if (pct_pdf14->params.csel == pct0->params.csel) {
10022
                /* If the new parameters completely replace the old ones
10023
                   then remove the old one from the queu */
10024
8.32M
                if ((pct_pdf14->params.changed & pct0->params.changed) ==
10025
8.32M
                    pct_pdf14->params.changed) {
10026
7.62M
                    return COMP_REPLACE_CURR;
10027
7.62M
                } else {
10028
701k
                    return COMP_ENQUEUE;
10029
701k
                }
10030
8.32M
            }
10031
8.32M
        } else
10032
2.44M
            return COMP_ENQUEUE;
10033
0
        pct = pct->prev;
10034
0
        if (pct == NULL)
10035
0
            return COMP_ENQUEUE; /* Not in queue. */
10036
0
    }
10037
14.4M
}
10038
10039
/*
10040
 * Check for closing compositor.
10041
 */
10042
static gs_compositor_closing_state
10043
c_pdf14trans_is_closing(const gs_composite_t * composite_action, gs_composite_t ** ppcte,
10044
                        gx_device *dev)
10045
27.7M
{
10046
27.7M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10047
27.7M
    int op0 = pct0->params.pdf14_op;
10048
10049
27.7M
    switch (op0) {
10050
0
        default: return_error(gs_error_unregistered); /* Must not happen. */
10051
1.05M
        case PDF14_PUSH_DEVICE:
10052
1.05M
            return COMP_ENQUEUE;
10053
0
        case PDF14_ABORT_DEVICE:
10054
0
            return COMP_ENQUEUE;
10055
1.05M
        case PDF14_POP_DEVICE:
10056
1.05M
            if (*ppcte == NULL)
10057
706k
                return COMP_ENQUEUE;
10058
343k
            else {
10059
343k
                gs_compositor_closing_state state = find_opening_op(PDF14_PUSH_DEVICE, ppcte, COMP_EXEC_IDLE);
10060
10061
343k
                if (state == COMP_EXEC_IDLE)
10062
92.0k
                    return COMP_DROP_QUEUE;
10063
251k
                return state;
10064
343k
            }
10065
427k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
10066
2.03M
        case PDF14_BEGIN_TRANS_GROUP:
10067
2.03M
            return COMP_ENQUEUE;
10068
1.64M
        case PDF14_END_TRANS_GROUP:
10069
2.03M
        case PDF14_END_TRANS_TEXT_GROUP:
10070
2.03M
            if (*ppcte == NULL)
10071
373k
                return COMP_EXEC_QUEUE;
10072
1.66M
            return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, COMP_MARK_IDLE);
10073
3.55M
        case PDF14_BEGIN_TRANS_MASK:
10074
3.55M
            return COMP_ENQUEUE;
10075
0
        case PDF14_PUSH_TRANS_STATE:
10076
0
            return COMP_ENQUEUE;
10077
2.42M
        case PDF14_POP_TRANS_STATE:
10078
2.42M
            return COMP_ENQUEUE;
10079
0
        case PDF14_PUSH_SMASK_COLOR:
10080
0
            return COMP_ENQUEUE;
10081
0
            break;
10082
0
        case PDF14_POP_SMASK_COLOR:
10083
0
            return COMP_ENQUEUE;
10084
0
            break;
10085
358k
        case PDF14_END_TRANS_MASK:
10086
358k
            if (*ppcte == NULL)
10087
229k
                return COMP_EXEC_QUEUE;
10088
128k
            return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte, COMP_MARK_IDLE);
10089
15.2M
        case PDF14_SET_BLEND_PARAMS:
10090
15.2M
            if (*ppcte == NULL)
10091
875k
                return COMP_ENQUEUE;
10092
            /* hack : ignore csel - here it is always zero : */
10093
14.4M
            return find_same_op(composite_action, PDF14_SET_BLEND_PARAMS, ppcte);
10094
27.7M
    }
10095
27.7M
}
10096
10097
/*
10098
 * Check whether a next operation is friendly to the compositor.
10099
 */
10100
static bool
10101
c_pdf14trans_is_friendly(const gs_composite_t * composite_action, byte cmd0, byte cmd1)
10102
3.29M
{
10103
3.29M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10104
3.29M
    int op0 = pct0->params.pdf14_op;
10105
10106
3.29M
    if (op0 == PDF14_PUSH_DEVICE || op0 == PDF14_END_TRANS_GROUP ||
10107
2.10M
        op0 == PDF14_END_TRANS_TEXT_GROUP) {
10108
        /* Halftone commands are always passed to the target printer device,
10109
           because transparency buffers are always contone.
10110
           So we're safe to execute them before queued transparency compositors. */
10111
1.20M
        if (cmd0 == cmd_opv_extend && (cmd1 == cmd_opv_ext_put_halftone ||
10112
348k
                                       cmd1 == cmd_opv_ext_put_ht_seg))
10113
570k
            return true;
10114
631k
        if (cmd0 == cmd_opv_set_misc && (cmd1 >> 6) == (cmd_set_misc_map >> 6))
10115
627k
            return true;
10116
631k
    }
10117
2.09M
    return false;
10118
3.29M
}
10119
10120
static composite_create_default_compositor_proc(c_pdf14trans_create_default_compositor);
10121
static composite_equal_proc(c_pdf14trans_equal);
10122
static composite_write_proc(c_pdf14trans_write);
10123
static composite_read_proc(c_pdf14trans_read);
10124
static composite_adjust_ctm_proc(c_pdf14trans_adjust_ctm);
10125
static composite_is_closing_proc(c_pdf14trans_is_closing);
10126
static composite_is_friendly_proc(c_pdf14trans_is_friendly);
10127
static composite_clist_write_update(c_pdf14trans_clist_write_update);
10128
static composite_clist_read_update(c_pdf14trans_clist_read_update);
10129
static composite_get_cropping_proc(c_pdf14trans_get_cropping);
10130
10131
/*
10132
 * Methods for the PDF 1.4 transparency compositor
10133
 *
10134
 * Note:  We have two set of methods.  They are the same except for the
10135
 * composite_clist_write_update method.  Once the clist write device is created,
10136
 * we use the second set of procedures.  This prevents the creation of multiple
10137
 * PDF 1.4 clist write compositor devices being chained together.
10138
 */
10139
const gs_composite_type_t   gs_composite_pdf14trans_type = {
10140
    GX_COMPOSITOR_PDF14_TRANS,
10141
    {
10142
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10143
        c_pdf14trans_equal,                      /* procs.equal */
10144
        c_pdf14trans_write,                      /* procs.write */
10145
        c_pdf14trans_read,                       /* procs.read */
10146
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10147
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10148
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10149
                /* Create a PDF 1.4 clist write device */
10150
        c_pdf14trans_clist_write_update,   /* procs.composite_clist_write_update */
10151
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10152
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10153
    }                                            /* procs */
10154
};
10155
10156
const gs_composite_type_t   gs_composite_pdf14trans_no_clist_writer_type = {
10157
    GX_COMPOSITOR_PDF14_TRANS,
10158
    {
10159
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10160
        c_pdf14trans_equal,                      /* procs.equal */
10161
        c_pdf14trans_write,                      /* procs.write */
10162
        c_pdf14trans_read,                       /* procs.read */
10163
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10164
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10165
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10166
                /* The PDF 1.4 clist writer already exists, Do not create it. */
10167
        gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */
10168
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10169
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10170
    }                                            /* procs */
10171
};
10172
10173
/*
10174
 * Verify that a compositor data structure is for the PDF 1.4 compositor.
10175
 */
10176
int
10177
gs_is_pdf14trans_compositor(const gs_composite_t * pct)
10178
233M
{
10179
233M
    return (pct->type == &gs_composite_pdf14trans_type
10180
180M
                || pct->type == &gs_composite_pdf14trans_no_clist_writer_type);
10181
233M
}
10182
10183
/*
10184
 * Create a PDF 1.4 transparency compositor data structure.
10185
 */
10186
static int
10187
gs_create_pdf14trans(
10188
    gs_composite_t **               ppct,
10189
    const gs_pdf14trans_params_t *  pparams,
10190
    gs_memory_t *                   mem )
10191
34.1M
{
10192
34.1M
    gs_pdf14trans_t *                pct;
10193
10194
34.1M
    pct = gs_alloc_struct(mem, gs_pdf14trans_t, &st_pdf14trans,
10195
34.1M
                             "gs_create_pdf14trans");
10196
34.1M
    if (pct == NULL)
10197
0
        return_error(gs_error_VMerror);
10198
34.1M
    pct->type = &gs_composite_pdf14trans_type;
10199
34.1M
    pct->id = gs_next_ids(mem, 1);
10200
34.1M
    pct->params = *pparams;
10201
34.1M
    pct->idle = false;
10202
34.1M
    *ppct = (gs_composite_t *)pct;
10203
34.1M
    return 0;
10204
34.1M
}
10205
10206
/*
10207
 * Send a PDF 1.4 transparency compositor action to the specified device.
10208
 */
10209
int
10210
send_pdf14trans(gs_gstate * pgs, gx_device * dev,
10211
    gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem)
10212
1.17M
{
10213
1.17M
    gs_composite_t * pct = NULL;
10214
1.17M
    int code;
10215
10216
1.17M
    pparams->ctm = ctm_only(pgs);
10217
1.17M
    code = gs_create_pdf14trans(&pct, pparams, mem);
10218
1.17M
    if (code < 0)
10219
0
        return code;
10220
1.17M
    code = dev_proc(dev, composite) (dev, pcdev, pct, pgs, mem, NULL);
10221
1.17M
    if (code == gs_error_handled)
10222
0
        code = 0;
10223
10224
1.17M
    gs_free_object(pgs->memory, pct, "send_pdf14trans");
10225
10226
1.17M
    return code;
10227
1.17M
}
10228
10229
/* ------------- PDF 1.4 transparency device for clist writing ------------- */
10230
10231
/*
10232
 * The PDF 1.4 transparency compositor device may have a different process
10233
 * color model than the output device.  If we are banding then we need to
10234
 * create two compositor devices.  The output side (clist reader) needs a
10235
 * compositor to actually composite the output.  We also need a compositor
10236
 * device before the clist writer.  This is needed to provide a process color
10237
 * model which matches the PDF 1.4 blending space.
10238
 *
10239
 * This section provides support for this device.
10240
 */
10241
10242
/*
10243
 * Define the default pre-clist (clist writer) PDF 1.4 compositing device.
10244
 * We actually use the same structure for both the clist writer and reader
10245
 * devices.  However we use separate names to identify the routines for each
10246
 * device.
10247
 */
10248
10249
static  dev_proc_composite(pdf14_clist_composite);
10250
static  dev_proc_composite(pdf14_clist_forward_composite);
10251
static  dev_proc_fill_path(pdf14_clist_fill_path);
10252
static  dev_proc_stroke_path(pdf14_clist_stroke_path);
10253
static  dev_proc_fill_stroke_path(pdf14_clist_fill_stroke_path);
10254
static  dev_proc_text_begin(pdf14_clist_text_begin);
10255
static  dev_proc_begin_typed_image(pdf14_clist_begin_typed_image);
10256
static  dev_proc_copy_planes(pdf14_clist_copy_planes);
10257
10258
static void
10259
pdf14_clist_init_procs(gx_device *dev,
10260
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
10261
                       dev_proc_get_color_comp_index(get_color_comp_index))
10262
9.40k
{
10263
9.40k
    set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
10264
9.40k
    set_dev_proc(dev, sync_output, gx_forward_sync_output);
10265
9.40k
    set_dev_proc(dev, output_page, gx_forward_output_page);
10266
9.40k
    set_dev_proc(dev, close_device, gx_forward_close_device);
10267
9.40k
    set_dev_proc(dev, map_rgb_color, pdf14_encode_color);
10268
9.40k
    set_dev_proc(dev, map_color_rgb, pdf14_decode_color);
10269
9.40k
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
10270
9.40k
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
10271
9.40k
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
10272
9.40k
    set_dev_proc(dev, get_params, gx_forward_get_params);
10273
9.40k
    set_dev_proc(dev, put_params, pdf14_put_params);
10274
9.40k
    set_dev_proc(dev, map_cmyk_color, pdf14_encode_color);
10275
9.40k
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
10276
9.40k
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
10277
9.40k
    set_dev_proc(dev, fill_path, pdf14_clist_fill_path);
10278
9.40k
    set_dev_proc(dev, stroke_path, pdf14_clist_stroke_path);
10279
9.40k
    set_dev_proc(dev, fill_mask, gx_forward_fill_mask);
10280
9.40k
    set_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid);
10281
9.40k
    set_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram);
10282
9.40k
    set_dev_proc(dev, fill_triangle, gx_forward_fill_triangle);
10283
9.40k
    set_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line);
10284
9.40k
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
10285
9.40k
    set_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2);
10286
9.40k
    set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box);
10287
9.40k
    set_dev_proc(dev, begin_typed_image, pdf14_clist_begin_typed_image);
10288
9.40k
    set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle);
10289
9.40k
    set_dev_proc(dev, composite, pdf14_clist_composite);
10290
9.40k
    set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params);
10291
9.40k
    set_dev_proc(dev, text_begin, pdf14_clist_text_begin);
10292
9.40k
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
10293
9.40k
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
10294
9.40k
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
10295
9.40k
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
10296
9.40k
    set_dev_proc(dev, discard_transparency_layer, gx_default_discard_transparency_layer);
10297
9.40k
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
10298
9.40k
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
10299
9.40k
    set_dev_proc(dev, encode_color, pdf14_encode_color);
10300
9.40k
    set_dev_proc(dev, decode_color, pdf14_decode_color);
10301
9.40k
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
10302
9.40k
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
10303
9.40k
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
10304
9.40k
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
10305
9.40k
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
10306
9.40k
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
10307
9.40k
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
10308
9.40k
    set_dev_proc(dev, copy_planes, pdf14_clist_copy_planes);
10309
9.40k
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
10310
9.40k
    set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color);
10311
9.40k
    set_dev_proc(dev, fill_stroke_path, pdf14_clist_fill_stroke_path);
10312
9.40k
}
10313
10314
static void
10315
pdf14_clist_Gray_initialize_device_procs(gx_device *dev)
10316
2.75k
{
10317
2.75k
    pdf14_clist_init_procs(dev,
10318
2.75k
                           gx_default_DevGray_get_color_mapping_procs,
10319
2.75k
                           gx_default_DevGray_get_color_comp_index);
10320
2.75k
}
10321
10322
static void
10323
pdf14_clist_RGB_initialize_device_procs(gx_device *dev)
10324
5.42k
{
10325
5.42k
    pdf14_clist_init_procs(dev,
10326
5.42k
                           gx_default_DevRGB_get_color_mapping_procs,
10327
5.42k
                           gx_default_DevRGB_get_color_comp_index);
10328
5.42k
}
10329
10330
static void
10331
pdf14_clist_CMYK_initialize_device_procs(gx_device *dev)
10332
13
{
10333
13
    pdf14_clist_init_procs(dev,
10334
13
                           gx_default_DevCMYK_get_color_mapping_procs,
10335
13
                           gx_default_DevCMYK_get_color_comp_index);
10336
13
}
10337
10338
static void
10339
pdf14_clist_CMYKspot_initialize_device_procs(gx_device *dev)
10340
1.20k
{
10341
1.20k
    pdf14_clist_init_procs(dev,
10342
1.20k
                           pdf14_cmykspot_get_color_mapping_procs,
10343
1.20k
                           pdf14_cmykspot_get_color_comp_index);
10344
1.20k
}
10345
10346
static void
10347
pdf14_clist_RGBspot_initialize_device_procs(gx_device *dev)
10348
0
{
10349
0
    pdf14_clist_init_procs(dev,
10350
0
                           pdf14_rgbspot_get_color_mapping_procs,
10351
0
                           pdf14_rgbspot_get_color_comp_index);
10352
0
}
10353
10354
#if 0 /* NOT USED */
10355
static int
10356
pdf14_clist_Grayspot_initialize_device_procs(gx_device *dev)
10357
{
10358
    pdf14_clist_init_procs(dev,
10359
                           pdf14_grayspot_get_color_mapping_procs,
10360
                           pdf14_grayspot_get_color_comp_index);
10361
}
10362
#endif  /* NOT USED */
10363
10364
const pdf14_clist_device pdf14_clist_Gray_device = {
10365
    std_device_color_stype_body(pdf14_clist_device,
10366
                                pdf14_clist_Gray_initialize_device_procs,
10367
                                "pdf14clistgray",
10368
                                &st_pdf14_device,
10369
                                XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256),
10370
    { 0 },      /* Procs */
10371
    NULL,     /* target */
10372
    { 0 },      /* devn_params - not used */
10373
    &gray_pdf14_procs,
10374
    &gray_blending_procs
10375
};
10376
10377
const pdf14_clist_device pdf14_clist_RGB_device = {
10378
    std_device_color_stype_body(pdf14_clist_device,
10379
                                pdf14_clist_RGB_initialize_device_procs,
10380
                                "pdf14clistRGB",
10381
                                &st_pdf14_device,
10382
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
10383
    { 0 },      /* Procs */
10384
    NULL,     /* target */
10385
    { 0 },      /* devn_params - not used */
10386
    &rgb_pdf14_procs,
10387
    &rgb_blending_procs
10388
};
10389
10390
const pdf14_clist_device pdf14_clist_RGBspot_device = {
10391
    std_device_part1_(pdf14_device,
10392
                      pdf14_clist_RGBspot_initialize_device_procs,
10393
                      "pdf14clistrgbspot",
10394
                      &st_pdf14_device,
10395
                      open_init_closed),
10396
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10397
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10398
    offset_margin_values(0, 0, 0, 0, 0, 0),
10399
    std_device_part3_(),
10400
    { 0 },      /* Procs */
10401
    NULL,     /* target */
10402
    /* DeviceN parameters */
10403
    { 8,      /* Not used - Bits per color */
10404
      DeviceRGBComponents,  /* Names of color model colorants */
10405
      3,      /* Number colorants for CMYK */
10406
      0,      /* MaxSeparations has not been specified */
10407
      -1,     /* PageSpotColors has not been specified */
10408
      {0},      /* SeparationNames */
10409
      0,      /* SeparationOrder names */
10410
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10411
    },
10412
    &rgbspot_pdf14_procs,
10413
    &rgb_blending_procs
10414
};
10415
10416
const pdf14_clist_device pdf14_clist_CMYK_device = {
10417
    std_device_std_color_full_body_type(pdf14_clist_device,
10418
                                        pdf14_clist_CMYK_initialize_device_procs,
10419
                                        "pdf14clistcmyk",
10420
                                        &st_pdf14_device,
10421
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
10422
                                        0, 0, 0, 0, 0, 0),
10423
    { 0 },      /* Procs */
10424
    NULL,     /* target */
10425
    { 0 },      /* devn_params - not used */
10426
    &cmyk_pdf14_procs,
10427
    &cmyk_blending_procs
10428
};
10429
10430
const pdf14_clist_device pdf14_clist_CMYKspot_device = {
10431
    std_device_part1_(pdf14_device,
10432
                      pdf14_clist_CMYKspot_initialize_device_procs,
10433
                      "pdf14clistcmykspot",
10434
                      &st_pdf14_device,
10435
                      open_init_closed),
10436
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10437
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10438
    offset_margin_values(0, 0, 0, 0, 0, 0),
10439
    std_device_part3_(),
10440
    { 0 },      /* Procs */
10441
    NULL,     /* target */
10442
    /* DeviceN parameters */
10443
    { 8,      /* Not used - Bits per color */
10444
      DeviceCMYKComponents, /* Names of color model colorants */
10445
      4,      /* Number colorants for CMYK */
10446
      0,      /* MaxSeparations has not been specified */
10447
      -1,     /* PageSpotColors has not been specified */
10448
      {0},      /* SeparationNames */
10449
      0,      /* SeparationOrder names */
10450
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10451
    },
10452
    &cmykspot_pdf14_procs,
10453
    &cmyk_blending_procs
10454
};
10455
10456
const pdf14_clist_device pdf14_clist_custom_device = {
10457
    std_device_part1_(pdf14_device,
10458
                      pdf14_clist_CMYKspot_initialize_device_procs,
10459
                      "pdf14clistcustom",
10460
                      &st_pdf14_device,
10461
                      open_init_closed),
10462
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10463
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10464
    offset_margin_values(0, 0, 0, 0, 0, 0),
10465
    std_device_part3_(),
10466
    { 0 },      /* Procs */
10467
    NULL,     /* target */
10468
    /* DeviceN parameters */
10469
    { 8,      /* Not used - Bits per color */
10470
      DeviceCMYKComponents, /* Names of color model colorants */
10471
      4,      /* Number colorants for CMYK */
10472
      0,      /* MaxSeparations has not been specified */
10473
      -1,     /* PageSpotColors has not been specified */
10474
      {0},      /* SeparationNames */
10475
      0,      /* SeparationOrder names */
10476
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10477
    },
10478
    &custom_pdf14_procs,
10479
    &custom_blending_procs
10480
};
10481
10482
/*
10483
 * the PDF 1.4 transparency spec says that color space for blending
10484
 * operations can be based upon either a color space specified in the
10485
 * group or a default value based upon the output device.  We are
10486
 * currently only using a color space based upon the device.
10487
 */
10488
static  int
10489
get_pdf14_clist_device_proto(gx_device          *dev,
10490
                             pdf14_clist_device *pdevproto,
10491
                             gs_gstate          *pgs,
10492
                       const gs_pdf14trans_t    *pdf14pct,
10493
                             bool                use_pdf14_accum)
10494
9.40k
{
10495
9.40k
    pdf14_blend_cs_t blend_cs_state;
10496
9.40k
    pdf14_default_colorspace_t dev_cs =
10497
9.40k
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
10498
9.40k
                                                 &blend_cs_state);
10499
9.40k
    bool deep = device_is_deep(dev);
10500
9.40k
    int num_spots = pdf14pct->params.num_spot_colors;
10501
10502
    /* overprint overide */
10503
9.40k
    if (pdf14pct->params.overprint_sim_push &&
10504
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10505
10506
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
10507
0
            dev_cs = PDF14_DeviceCMYKspot;
10508
0
            num_spots = pdf14pct->params.num_spot_colors_int;
10509
0
        } else
10510
0
            dev_cs = PDF14_DeviceCMYK;
10511
0
    }
10512
10513
9.40k
    switch (dev_cs) {
10514
2.75k
        case PDF14_DeviceGray:
10515
           /* We want gray to be single channel.  Low level
10516
               initialization of gray device prototype is
10517
               peculiar in that in dci_std_color_num_components
10518
               the comment is
10519
              "A device is monochrome only if it is bi-level"
10520
              Here we want monochrome anytime we have a gray device.
10521
              To avoid breaking things elsewhere, we will overide
10522
              the prototype intialization here */
10523
2.75k
            *pdevproto = pdf14_clist_Gray_device;
10524
2.75k
            pdevproto->color_info.max_components = 1;
10525
2.75k
            pdevproto->color_info.num_components =
10526
2.75k
                                    pdevproto->color_info.max_components;
10527
2.75k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10528
2.75k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
10529
2.75k
            pdevproto->color_info.dither_grays = pdevproto->color_info.max_gray+1;
10530
2.75k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10531
2.75k
            pdevproto->color_info.depth = deep ? 16 : 8;
10532
2.75k
            pdevproto->sep_device = false;
10533
2.75k
            break;
10534
5.42k
        case PDF14_DeviceRGB:
10535
5.42k
            *pdevproto = pdf14_clist_RGB_device;
10536
5.42k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10537
5.42k
            pdevproto->sep_device = false;
10538
5.42k
            if (deep) {
10539
0
                pdevproto->color_info.depth = 3*16;
10540
0
                pdevproto->color_info.max_color = 65535;
10541
0
                pdevproto->color_info.max_gray = 65535;
10542
0
                pdevproto->color_info.dither_colors = 65536;
10543
0
                pdevproto->color_info.dither_grays = 65536;
10544
0
            }
10545
5.42k
            break;
10546
13
        case PDF14_DeviceCMYK:
10547
13
            *pdevproto = pdf14_clist_CMYK_device;
10548
13
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10549
13
            pdevproto->sep_device = false;
10550
13
            if (deep) {
10551
0
                pdevproto->color_info.depth = 4*16;
10552
0
                pdevproto->color_info.max_color = 65535;
10553
0
                pdevproto->color_info.max_gray = 65535;
10554
0
                pdevproto->color_info.dither_colors = 65536;
10555
0
                pdevproto->color_info.dither_grays = 65536;
10556
0
            }
10557
13
            break;
10558
1.20k
        case PDF14_DeviceCMYKspot:
10559
1.20k
            *pdevproto = pdf14_clist_CMYKspot_device;
10560
            /*
10561
             * The number of components for the PDF14 device is the sum
10562
             * of the process components and the number of spot colors
10563
             * for the page. If we are using an NCLR ICC profile at
10564
             * the output device, those spot colors are skipped. They
10565
             * do not appear in the transparency buffer, but appear
10566
             * during put image transform of the page group to the target
10567
             * color space.
10568
             */
10569
1.20k
            if (num_spots >= 0) {
10570
1.20k
                pdevproto->devn_params.page_spot_colors = num_spots;
10571
1.20k
                pdevproto->color_info.num_components =
10572
1.20k
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10573
1.20k
                if (pdevproto->color_info.num_components >
10574
1.20k
                              pdevproto->color_info.max_components)
10575
0
                    pdevproto->color_info.num_components =
10576
0
                              pdevproto->color_info.max_components;
10577
1.20k
                pdevproto->color_info.depth =
10578
1.20k
                              pdevproto->color_info.num_components * (8<<deep);
10579
1.20k
            }
10580
1.20k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10581
1.20k
            pdevproto->sep_device = true;
10582
1.20k
            break;
10583
0
        case PDF14_DeviceRGBspot:
10584
0
            *pdevproto = pdf14_clist_RGBspot_device;
10585
            /*
10586
             * The number of components for the PDF14 device is the sum
10587
             * of the process components and the number of spot colors
10588
             * for the page. If we are using an NCLR ICC profile at
10589
             * the output device, those spot colors are skipped. They
10590
             * do not appear in the transparency buffer, but appear
10591
             * during put image transform of the page group to the target
10592
             * color space.
10593
             */
10594
0
            if (num_spots >= 0) {
10595
0
                pdevproto->devn_params.page_spot_colors = num_spots;
10596
0
                pdevproto->color_info.num_components =
10597
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10598
0
                if (pdevproto->color_info.num_components >
10599
0
                    pdevproto->color_info.max_components)
10600
0
                    pdevproto->color_info.num_components =
10601
0
                        pdevproto->color_info.max_components;
10602
0
                pdevproto->color_info.depth =
10603
0
                    pdevproto->color_info.num_components * (8 << deep);
10604
0
            }
10605
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10606
0
            pdevproto->sep_device = true;
10607
0
            break;
10608
0
        case PDF14_DeviceCustom:
10609
            /*
10610
             * We are using the output device's process color model.  The
10611
             * color_info for the PDF 1.4 compositing device needs to match
10612
             * the output device.
10613
             */
10614
0
            *pdevproto = pdf14_clist_custom_device;
10615
0
            pdevproto->color_info = dev->color_info;
10616
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
10617
0
            pdevproto->color_info.depth =
10618
0
                pdevproto->color_info.num_components * (8<<deep);
10619
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10620
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
10621
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
10622
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
10623
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10624
0
            break;
10625
0
        default:      /* Should not occur */
10626
0
            return_error(gs_error_rangecheck);
10627
9.40k
    }
10628
9.40k
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
10629
9.40k
    pdevproto->blend_cs_state = blend_cs_state;
10630
9.40k
    return 0;
10631
9.40k
}
10632
10633
static  int
10634
pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10635
                                gx_device ** ppdev, gx_device * target,
10636
                                const gs_pdf14trans_t * pdf14pct)
10637
9.40k
{
10638
9.40k
    pdf14_clist_device dev_proto;
10639
9.40k
    pdf14_clist_device * pdev;
10640
9.40k
    int code;
10641
9.40k
    bool has_tags = device_encodes_tags(target);
10642
9.40k
    cmm_profile_t *target_profile;
10643
9.40k
    gsicc_rendering_param_t render_cond;
10644
9.40k
    cmm_dev_profile_t *dev_profile;
10645
9.40k
    uchar k;
10646
9.40k
    bool deep = device_is_deep(target);
10647
9.40k
    cmm_profile_t *icc_profile;
10648
9.40k
    int nc;
10649
10650
9.40k
    code = dev_proc(target, get_profile)(target,  &dev_profile);
10651
9.40k
    if (code < 0)
10652
0
        return code;
10653
9.40k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &target_profile,
10654
9.40k
                          &render_cond);
10655
9.40k
    if_debug0m('v', pgs->memory, "[v]pdf14_create_clist_device\n");
10656
    /* Prototypes never include tags. We add those in later. */
10657
9.40k
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10658
9.40k
                                        pgs, pdf14pct, false);
10659
9.40k
    if (code < 0)
10660
0
        return code;
10661
9.40k
    code = gs_copydevice((gx_device **) &pdev,
10662
9.40k
                         (const gx_device *) &dev_proto, mem);
10663
9.40k
    if (code < 0)
10664
0
        return code;
10665
10666
9.40k
    nc = pdev->color_info.num_components;
10667
    /* If we are not using a blending color space, the number of color planes
10668
       should not exceed that of the target */
10669
9.40k
    if (!(pdev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || pdev->overprint_sim)) {
10670
9.40k
        if (nc > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev))
10671
0
            nc = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev);
10672
9.40k
        if (pdev->color_info.max_components > target->color_info.max_components)
10673
1.28k
            pdev->color_info.max_components = target->color_info.max_components;
10674
9.40k
    }
10675
9.40k
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10676
0
        nc = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10677
10678
9.40k
    pdev->color_info.num_components = nc;
10679
9.40k
    pdev->color_info.depth = pdev->color_info.num_components * (8<<deep);
10680
9.40k
    pdev->pad = target->pad;
10681
9.40k
    pdev->log2_align_mod = target->log2_align_mod;
10682
10683
9.40k
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10684
10685
9.40k
    pdev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
10686
10687
9.40k
    if (deep) {
10688
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
10689
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
10690
0
    }
10691
    /* If we have a tag device then go ahead and do a special encoder decoder
10692
       for the pdf14 device to make sure we maintain this information in the
10693
       encoded color information.  We could use the target device's methods but
10694
       the PDF14 device has to maintain 8 bit color always and we could run
10695
       into other issues if the number of colorants became large.  If we need to
10696
       do compressed color with tags that will be a special project at that time */
10697
9.40k
    if (has_tags) {
10698
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag: pdf14_encode_color_tag);
10699
0
    }
10700
9.40k
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;  /* this is the standard */
10701
9.40k
    gx_device_fill_in_procs((gx_device *)pdev);
10702
    /* Copying the params adds the tags to the color_info if required. */
10703
9.40k
    gs_pdf14_device_copy_params((gx_device *)pdev, target);
10704
9.40k
    if (target->num_planar_planes > 0)
10705
1.33k
        pdev->num_planar_planes = pdev->color_info.num_components;
10706
9.40k
    gx_device_set_target((gx_device_forward *)pdev, target);
10707
10708
    /* Components shift, etc have to be based upon 8 bit */
10709
33.3k
    for (k = 0; k < pdev->color_info.num_components; k++) {
10710
23.9k
        pdev->color_info.comp_bits[k] = 8<<deep;
10711
23.9k
        pdev->color_info.comp_shift[k] = (pdev->color_info.num_components - 1 - k) * (8<<deep);
10712
23.9k
    }
10713
9.40k
    code = dev_proc((gx_device *) pdev, open_device) ((gx_device *) pdev);
10714
9.40k
    if (code < 0)
10715
0
        return code;
10716
9.40k
    pdev->pclist_device = target;
10717
10718
9.40k
    code = dev_proc(target, get_profile)(target, &dev_profile);
10719
9.40k
    if (code < 0)
10720
0
        return code;
10721
9.40k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
10722
9.40k
        &render_cond);
10723
9.40k
    if_debug0m('v', mem, "[v]pdf14_create_clist_device\n");
10724
10725
    /* Simulated overprint case.  We have to use CMYK-based profile
10726
       Also if the target profile is NCLR, we are going to use a pdf14
10727
       device that is CMYK based and do the mapping to the NCLR profile
10728
       when the put_image occurs */
10729
9.40k
    if ((pdev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
10730
9.40k
         icc_profile->data_cs == gsNCHANNEL) {
10731
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_create_clist_device");
10732
0
        gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10733
0
            -1, "pdf14_create_clist_device");
10734
0
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
10735
9.40k
    } else {
10736
        /* If the target profile was CIELAB, then overide with default RGB for
10737
           proper blending.  During put_image we will convert from RGB to
10738
           CIELAB */
10739
9.40k
        if ((target_profile->data_cs == gsCIELAB || target_profile->islab) &&
10740
0
            pdev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10741
0
            pdev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
10742
0
            rc_assign(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10743
0
                pgs->icc_manager->default_rgb, "pdf14_create_clist_device");
10744
0
        }
10745
9.40k
    }
10746
10747
9.40k
    if (pdf14pct->params.overprint_sim_push &&
10748
0
        pdf14pct->params.num_spot_colors_int > 0) {
10749
0
        pdev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
10750
0
        pdev->procs.ret_devn_params = pdf14_ret_devn_params;
10751
0
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
10752
0
        pdev->target_support_devn = pdev->icc_struct->supports_devn;
10753
0
        pdev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
10754
0
    }
10755
    /* if the device has separations already defined (by SeparationOrderNames) */
10756
    /* we need to copy them (allocating new names) so the colorants are in the */
10757
    /* same order as the target device.                                        */
10758
9.40k
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
10759
1.33k
        code = devn_copy_params(target, (gx_device *)pdev);
10760
1.33k
        if (code < 0)
10761
0
            return code;
10762
1.33k
    }
10763
9.40k
    pdev->my_encode_color = dev_proc(pdev, encode_color);
10764
9.40k
    pdev->my_decode_color = dev_proc(pdev, decode_color);
10765
9.40k
    pdev->my_get_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
10766
9.40k
    pdev->my_get_color_comp_index = dev_proc(pdev, get_color_comp_index);
10767
9.40k
    pdev->color_info.separable_and_linear =
10768
9.40k
        target->color_info.separable_and_linear;
10769
9.40k
    *ppdev = (gx_device *) pdev;
10770
9.40k
    return code;
10771
9.40k
}
10772
10773
/*
10774
 * Disable the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10775
 * compositor device is never removed.  (We do not have a remove compositor
10776
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10777
 * routine implements that action.
10778
 */
10779
static  int
10780
pdf14_disable_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10781
                                gx_device * dev)
10782
8.91k
{
10783
8.91k
    gx_device_forward * pdev = (gx_device_forward *)dev;
10784
8.91k
    gx_device * target = pdev->target;
10785
10786
8.91k
    if_debug0m('v', pgs->memory, "[v]pdf14_disable_clist_device\n");
10787
10788
    /*
10789
     * To disable the action of this device, we forward all device
10790
     * procedures to the target except the composite and copy
10791
     * the target's color_info.
10792
     */
10793
8.91k
    dev->color_info = target->color_info;
10794
8.91k
    pdf14_forward_device_procs(dev);
10795
8.91k
    set_dev_proc(dev, composite, pdf14_clist_forward_composite);
10796
8.91k
    return 0;
10797
8.91k
}
10798
10799
/*
10800
 * Recreate the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10801
 * compositor device is never removed.  (We do not have a remove compositor
10802
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10803
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
10804
 * again.
10805
 */
10806
static  int
10807
pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10808
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
10809
0
{
10810
0
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
10811
0
    gx_device * target = pdev->target;
10812
0
    pdf14_clist_device dev_proto;
10813
0
    int code;
10814
10815
0
    if_debug0m('v', pgs->memory, "[v]pdf14_recreate_clist_device\n");
10816
    /*
10817
     * We will not use the entire prototype device but we will set the
10818
     * color related info to match the prototype.
10819
     */
10820
0
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10821
0
                                        pgs, pdf14pct, false);
10822
0
    if (code < 0)
10823
0
        return code;
10824
0
    pdev->color_info = dev_proto.color_info;
10825
10826
0
    if (dev_proto.initialize_device_procs != NULL)
10827
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
10828
10829
0
    pdev->procs = dev_proto.procs;
10830
0
    pdev->pad = target->pad;
10831
0
    pdev->log2_align_mod = target->log2_align_mod;
10832
10833
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10834
0
        pdev->num_planar_planes = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10835
0
    else
10836
0
        pdev->num_planar_planes = target->num_planar_planes;
10837
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10838
10839
0
    copy_tag_setup(dev, target);
10840
10841
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
10842
0
    gx_device_fill_in_procs((gx_device *)pdev);
10843
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
10844
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
10845
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
10846
0
    check_device_separable((gx_device *)pdev);
10847
0
    return code;
10848
0
}
10849
10850
/*
10851
 * devicen params
10852
 */
10853
gs_devn_params *
10854
pdf14_ret_devn_params(gx_device *pdev)
10855
1.98M
{
10856
1.98M
    pdf14_device *p14dev = (pdf14_device *)pdev;
10857
10858
1.98M
    return &(p14dev->devn_params);
10859
1.98M
}
10860
10861
/*
10862
 * devicen params
10863
 */
10864
gs_devn_params *
10865
pdf14_accum_ret_devn_params(gx_device *pdev)
10866
0
{
10867
0
    gx_device_pdf14_accum *p14dev = (gx_device_pdf14_accum *)pdev;
10868
10869
0
    return &(p14dev->devn_params);
10870
0
}
10871
10872
static int
10873
pdf14_accum_get_color_comp_index(gx_device * dev,
10874
    const char * pname, int name_size, int component_type)
10875
0
{
10876
0
    pdf14_device *p14dev = (pdf14_device *)(((gx_device_pdf14_accum *)dev)->save_p14dev);
10877
0
    gx_device *target = p14dev->target;
10878
0
    int colorant_number = devn_get_color_comp_index(dev,
10879
0
                &(((gx_device_pdf14_accum *)dev)->devn_params),
10880
0
                &(((gx_device_pdf14_accum *)dev)->equiv_cmyk_colors),
10881
0
                pname, name_size, component_type, ENABLE_AUTO_SPOT_COLORS);
10882
10883
0
    if (target != NULL)
10884
        /* colorant_number returned here _should_ be the same as from above */
10885
0
        colorant_number = (*dev_proc(target, get_color_comp_index))
10886
0
                              (target, (const char *)pname, name_size, component_type);
10887
0
    return colorant_number;
10888
0
}
10889
10890
/*
10891
 * The following procedures are used to map the standard color spaces into
10892
 * the separation color components for the pdf14_accum device.
10893
 */
10894
static void
10895
pdf14_accum_gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[])
10896
0
{
10897
0
    int * map =
10898
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10899
10900
0
    gray_cs_to_devn_cm(dev, map, gray, out);
10901
0
}
10902
10903
static void
10904
pdf14_accum_rgb_cs_to_cmyk_cm(const gx_device * dev,
10905
    const gs_gstate *pgs, frac r, frac g, frac b, frac out[])
10906
0
{
10907
0
    int * map =
10908
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10909
10910
0
    rgb_cs_to_devn_cm(dev, map, pgs, r, g, b, out);
10911
0
}
10912
10913
static void
10914
pdf14_accum_cmyk_cs_to_cmyk_cm(const gx_device * dev,
10915
    frac c, frac m, frac y, frac k, frac out[])
10916
0
{
10917
0
    const int * map =
10918
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10919
10920
0
    cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out);
10921
0
}
10922
10923
static const gx_cm_color_map_procs pdf14_accum_cm_procs = {
10924
    pdf14_accum_gray_cs_to_cmyk_cm,
10925
    pdf14_accum_rgb_cs_to_cmyk_cm,
10926
    pdf14_accum_cmyk_cs_to_cmyk_cm
10927
};
10928
10929
static const gx_cm_color_map_procs *
10930
pdf14_accum_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev)
10931
0
{
10932
0
    *map_dev = dev;
10933
0
    return &pdf14_accum_cm_procs;
10934
0
}
10935
10936
/*
10937
 *  Device proc for updating the equivalent CMYK color for spot colors.
10938
 */
10939
static int
10940
pdf14_accum_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs, const gs_color_space *pcs)
10941
0
{
10942
0
    gx_device_pdf14_accum *pdev = (gx_device_pdf14_accum *)dev;
10943
0
    gx_device *tdev = ((pdf14_device *)(pdev->save_p14dev))->target;
10944
0
    int code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10945
0
                                              &pdev->equiv_cmyk_colors);
10946
10947
0
    if (code >= 0 && tdev != NULL)
10948
0
        code = dev_proc(tdev, update_spot_equivalent_colors)(tdev, pgs, pcs);
10949
0
    return code;
10950
0
}
10951
10952
/* Used when doing overprint simulation and have spot colors */
10953
static int
10954
pdf14_update_spot_equivalent_colors(gx_device *dev, const gs_gstate *pgs, const gs_color_space *pcs)
10955
0
{
10956
0
    pdf14_device *pdev = (pdf14_device *)dev;
10957
0
    int code;
10958
10959
    /* Make sure we are not All or None */
10960
0
    if (pcs != NULL && pcs->type->index == gs_color_space_index_Separation &&
10961
0
        pcs->params.separation.sep_type != SEP_OTHER)
10962
0
            return 0;
10963
10964
0
    code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10965
0
        &pdev->op_pequiv_cmyk_colors);
10966
0
    return code;
10967
0
}
10968
10969
/*
10970
 * Retrieve a list of spot color names for the PDF14 device.
10971
 */
10972
int
10973
put_param_pdf14_spot_names(gx_device * pdev,
10974
                gs_separations * pseparations, gs_param_list * plist)
10975
95.2k
{
10976
95.2k
    int code, num_spot_colors, i;
10977
95.2k
    gs_param_string str;
10978
10979
    /* Check if the given keyname is present. */
10980
95.2k
    code = param_read_int(plist, PDF14NumSpotColorsParamName,
10981
95.2k
                                                &num_spot_colors);
10982
95.2k
    switch (code) {
10983
0
        default:
10984
0
            param_signal_error(plist, PDF14NumSpotColorsParamName, code);
10985
0
            break;
10986
95.2k
        case 1:
10987
95.2k
            return 0;
10988
0
        case 0:
10989
0
            if (num_spot_colors < 1 ||
10990
0
                num_spot_colors > GX_DEVICE_COLOR_MAX_COMPONENTS)
10991
0
                return_error(gs_error_rangecheck);
10992
0
            for (i = 0; i < num_spot_colors; i++) {
10993
0
                char buff[20];
10994
0
                byte * sep_name;
10995
10996
0
                gs_snprintf(buff, sizeof(buff), "PDF14SpotName_%d", i);
10997
0
                code = param_read_string(plist, buff, &str);
10998
0
                switch (code) {
10999
0
                    default:
11000
0
                        param_signal_error(plist, buff, code);
11001
0
                        break;
11002
0
                    case 0:
11003
0
                        sep_name = gs_alloc_bytes(pdev->memory,
11004
0
                                str.size, "put_param_pdf14_spot_names");
11005
0
                        if (sep_name == NULL)
11006
0
                            return_error(gs_error_VMerror);
11007
11008
0
                        memcpy(sep_name, str.data, str.size);
11009
0
                        pseparations->names[i].size = str.size;
11010
0
                        pseparations->names[i].data = sep_name;
11011
0
                }
11012
0
            }
11013
0
            pseparations->num_separations = num_spot_colors;
11014
0
            break;
11015
95.2k
    }
11016
0
    return 0;;
11017
0
}
11018
11019
/*
11020
 * This procedure will have information from the PDF 1.4 clist writing
11021
 * clist compositior device.  This is information output the compressed
11022
 * color list info which is needed for the support of spot colors in
11023
 * PDF 1.4 compositing.  This info needs to be passed to the PDF 1.4
11024
 * clist reading compositor.  However this device is not created until
11025
 * the clist is read.  To get this info to that device, we have to
11026
 * temporarily store that info in the output device.  This routine saves
11027
 * that info in the output device.
11028
 */
11029
int
11030
pdf14_put_devn_params(gx_device * pdev, gs_devn_params * pdevn_params,
11031
                                        gs_param_list * plist)
11032
95.2k
{
11033
95.2k
    int code;
11034
95.2k
    code = put_param_pdf14_spot_names(pdev,
11035
95.2k
                       &pdevn_params->pdf14_separations, plist);
11036
95.2k
    return code;
11037
95.2k
}
11038
11039
/*
11040
 * When we are banding, we have two PDF 1.4 compositor devices.  One for
11041
 * when we are creating the clist.  The second is for imaging the data from
11042
 * the clist.  This routine is part of the clist writing PDF 1.4 device.
11043
 * This routine is only called once the PDF 1.4 clist write compositor already
11044
 * exists.
11045
 */
11046
static  int
11047
pdf14_clist_composite(gx_device * dev, gx_device ** pcdev,
11048
    const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem,
11049
    gx_device *cdev)
11050
1.54M
{
11051
1.54M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11052
1.54M
    int code, is_pdf14_compositor;
11053
1.54M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11054
1.54M
    bool deep = device_is_deep(dev);
11055
11056
    /* We only handle a few PDF 1.4 transparency operations */
11057
1.54M
    if ((is_pdf14_compositor = gs_is_pdf14trans_compositor(pct)) != 0) {
11058
888k
        switch (pdf14pct->params.pdf14_op) {
11059
0
            case PDF14_PUSH_DEVICE:
11060
                /* Re-activate the PDF 1.4 compositor */
11061
/*
11062
                We previously did:
11063
11064
                pdev->saved_target_color_info = pdev->target->color_info;
11065
11066
                Here, but since we already saved and modified the the color_info
11067
                of the target clist device in gs_pdf14_clist_device_push() this is
11068
                overwriting saved_target_color_info that we already saved with the
11069
                group color_info, meaning when we set it back again, it's incorrect.
11070
*/
11071
0
                pdev->target->color_info = pdev->color_info;
11072
0
                pdev->saved_target_encode_color = dev_proc(pdev->target, encode_color);
11073
0
                pdev->saved_target_decode_color = dev_proc(pdev->target, decode_color);
11074
0
                set_dev_proc(pdev->target, encode_color, pdev->my_encode_color);
11075
0
                set_dev_proc(pdev, encode_color, pdev->my_encode_color);
11076
0
                set_dev_proc(pdev->target, decode_color, pdev->my_decode_color);
11077
0
                set_dev_proc(pdev, decode_color, pdev->my_decode_color);
11078
0
                pdev->saved_target_get_color_mapping_procs =
11079
0
                                        dev_proc(pdev->target, get_color_mapping_procs);
11080
0
                pdev->saved_target_get_color_comp_index =
11081
0
                                        dev_proc(pdev->target, get_color_comp_index);
11082
0
                set_dev_proc(pdev->target, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11083
0
                set_dev_proc(pdev, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11084
0
                set_dev_proc(pdev->target, get_color_comp_index, pdev->my_get_color_comp_index);
11085
0
                set_dev_proc(pdev, get_color_comp_index, pdev->my_get_color_comp_index);
11086
0
                pdev->save_get_cmap_procs = pgs->get_cmap_procs;
11087
0
                pgs->get_cmap_procs = pdf14_get_cmap_procs;
11088
0
                gx_set_cmap_procs(pgs, dev);
11089
0
                code = pdf14_recreate_clist_device(mem, pgs, dev, pdf14pct);
11090
0
                pdev->blend_mode = pdev->text_knockout = 0;
11091
0
                pdev->opacity = pdev->shape = 0.0;
11092
0
                if (code < 0)
11093
0
                    return code;
11094
                /*
11095
                 * This routine is part of the PDF 1.4 clist write device.
11096
                 * Change the compositor procs to not create another since we
11097
                 * do not need to create a chain of identical devices.
11098
                 */
11099
0
                {
11100
0
                    gs_pdf14trans_t pctemp = *pdf14pct;
11101
11102
0
                    pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type;
11103
0
                    code = dev_proc(pdev->target, composite)
11104
0
                                (pdev->target, pcdev, (gs_composite_t *)&pctemp, pgs, mem, cdev);
11105
                    /* We should never have created a new device here. */
11106
0
                    assert(code != 1);
11107
0
                    return code;
11108
0
                }
11109
8.91k
            case PDF14_POP_DEVICE:
11110
8.91k
            {
11111
8.91k
                gx_device *clistdev = pdev->target;
11112
11113
                /* Find the clist device */
11114
8.91k
                while (1) {
11115
8.91k
                    gxdso_device_child_request req;
11116
                    /* Ignore any errors here, that's expected as non-clist
11117
                     * devices don't implement it. */
11118
8.91k
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_is_clist_device, NULL, 0);
11119
8.91k
                    if (code == 1)
11120
8.91k
                        break;
11121
0
                    req.n = 0;
11122
0
                    req.target = clistdev;
11123
0
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_device_child, &req, sizeof(req));
11124
0
                    if (code < 0)
11125
0
                        return code;
11126
0
                    clistdev = req.target;
11127
0
                }
11128
11129
                /* If we have overprint simulation spot color information, store
11130
                   it in a pseudo-band of the clist */
11131
8.91k
                if (pdev->overprint_sim &&
11132
0
                    pdev->devn_params.page_spot_colors > 0) {
11133
0
                    code = clist_write_op_equiv_cmyk_colors((gx_device_clist_writer *)clistdev,
11134
0
                        &pdev->op_pequiv_cmyk_colors);
11135
0
                    if (code < 0)
11136
0
                        return code;
11137
0
                }
11138
11139
                /* If we hit an error during an SMask, we need to undo the color
11140
                 * swapping before continuing. pdf14_decrement_smask_color() checks
11141
                 * for itself if it needs to take action.
11142
                 */
11143
8.91k
                pdf14_decrement_smask_color(pgs, dev);
11144
                /* Restore the color_info for the clist device */
11145
8.91k
                clistdev->color_info = pdev->saved_target_color_info;
11146
8.91k
                ((gx_device_clist_writer*)clistdev)->clist_color_info = clistdev->color_info; /* also reset for writer */
11147
8.91k
                set_dev_proc(clistdev, encode_color, pdev->saved_target_encode_color);
11148
8.91k
                set_dev_proc(clistdev, decode_color, pdev->saved_target_decode_color);
11149
8.91k
                set_dev_proc(clistdev, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs);
11150
8.91k
                set_dev_proc(clistdev, get_color_comp_index, pdev->saved_target_get_color_comp_index);
11151
8.91k
                pgs->get_cmap_procs = pdev->save_get_cmap_procs;
11152
8.91k
                gx_set_cmap_procs(pgs, clistdev);
11153
8.91k
                gx_device_decache_colors(clistdev);
11154
                /* Disable the PDF 1.4 compositor */
11155
8.91k
                pdf14_disable_clist_device(mem, pgs, dev);
11156
                /*
11157
                 * Make sure that the transfer funtions, etc. are current.
11158
                 */
11159
8.91k
                code = cmd_put_color_mapping((gx_device_clist_writer *)clistdev, pgs);
11160
8.91k
                if (code < 0)
11161
0
                    return code;
11162
8.91k
                break;
11163
8.91k
            }
11164
8.91k
            case PDF14_BEGIN_TRANS_PAGE_GROUP:
11165
35.5k
            case PDF14_BEGIN_TRANS_GROUP:
11166
35.5k
                if (pdev->smask_constructed || pdev->depth_within_smask)
11167
16.2k
                    pdev->depth_within_smask++;
11168
35.5k
                pdev->smask_constructed = 0;
11169
                /*
11170
                 * Keep track of any changes made in the blending parameters.
11171
                   These need to be written out in the same bands as the group
11172
                   information is written.  Hence the passing of the dimensions
11173
                   for the group. */
11174
35.5k
                code = pdf14_clist_update_params(pdev, pgs, true,
11175
35.5k
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11176
35.5k
                if (code < 0)
11177
0
                    return code;
11178
35.5k
                if (pdf14pct->params.Background_components != 0 &&
11179
0
                    pdf14pct->params.Background_components !=
11180
0
                    pdev->color_info.num_components)
11181
0
                    return_error(gs_error_rangecheck);
11182
11183
                /* We need to update the clist writer device procs based upon the
11184
                   the group color space. This ensures the proper color data is
11185
                   written out to the device. For simplicity, the list item is
11186
                   created even if the color space did not change */
11187
35.5k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, false);
11188
35.5k
                if (code < 0)
11189
0
                    return code;
11190
11191
35.5k
                break;
11192
36.6k
            case PDF14_BEGIN_TRANS_MASK:
11193
                /* We need to update the clist writer device procs based upon the
11194
                   the group color space.  For simplicity, the list item is created
11195
                   even if the color space did not change */
11196
                /* First store the current ones */
11197
36.6k
                if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
11198
20.3k
                    break;
11199
11200
                /* Update the color settings of the clist writer.  Store information in stack */
11201
16.3k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, true);
11202
16.3k
                if (code < 0)
11203
0
                    return code;
11204
11205
                /* Also, if the BC is a value that may end up as something other
11206
                  than transparent. We must use the parent colors bounding box in
11207
                  determining the range of bands in which this mask can affect.
11208
                  So, if needed change the masks bounding box at this time */
11209
16.3k
                pdev->in_smask_construction++;
11210
16.3k
                break;
11211
353k
            case PDF14_BEGIN_TRANS_TEXT_GROUP:
11212
353k
                if (pdev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
11213
15
                    emprintf(pdev->memory, "Warning: Text group pushed but no ET found\n");
11214
15
                    pdev->text_group = PDF14_TEXTGROUP_MISSING_ET;
11215
15
                } else
11216
353k
                    pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
11217
353k
                *pcdev = dev;
11218
353k
                return 0; /* Never put into clist. Only used during writing */
11219
356k
            case PDF14_END_TRANS_TEXT_GROUP:
11220
356k
                if (pdev->text_group != PDF14_TEXTGROUP_BT_PUSHED) {
11221
353k
                    *pcdev = dev;
11222
353k
                    return 0; /* Avoids spurious ET calls in interpreter */
11223
353k
                }
11224
2.25k
                pdev->text_group = PDF14_TEXTGROUP_NO_BT; /* These can't be nested */
11225
2.25k
                code = pdf14_clist_pop_color_model(dev, pgs);
11226
2.25k
                if (code < 0)
11227
0
                    return code;
11228
2.25k
                break;
11229
16.3k
            case PDF14_END_TRANS_MASK:
11230
16.3k
                pdev->in_smask_construction--;
11231
16.3k
                if (pdev->in_smask_construction < 0)
11232
0
                    pdev->in_smask_construction = 0;
11233
16.3k
                if (pdev->in_smask_construction == 0)
11234
16.3k
                    pdev->smask_constructed = 1;
11235
                /* fallthrough */
11236
49.5k
            case PDF14_END_TRANS_GROUP:
11237
                /* We need to update the clist writer device procs based upon the
11238
                   the group color space. */
11239
49.5k
                code = pdf14_clist_pop_color_model(dev, pgs);
11240
49.5k
                if (pdev->depth_within_smask)
11241
16.2k
                    pdev->depth_within_smask--;
11242
49.5k
                if (code < 0)
11243
0
                    return code;
11244
49.5k
                break;
11245
49.5k
            case PDF14_PUSH_TRANS_STATE:
11246
0
                break;
11247
15.9k
            case PDF14_POP_TRANS_STATE:
11248
15.9k
                break;
11249
16.3k
            case PDF14_PUSH_SMASK_COLOR:
11250
16.3k
                code = pdf14_increment_smask_color(pgs,dev);
11251
16.3k
                *pcdev = dev;
11252
16.3k
                return code;  /* Note, this are NOT put in the clist */
11253
0
                break;
11254
16.3k
            case PDF14_POP_SMASK_COLOR:
11255
16.3k
                code = pdf14_decrement_smask_color(pgs,dev);
11256
16.3k
                *pcdev = dev;
11257
16.3k
                return code;  /* Note, this are NOT put in the clist */
11258
0
                break;
11259
0
            case PDF14_SET_BLEND_PARAMS:
11260
                /* If there is a change we go ahead and apply it to the target */
11261
0
                code = pdf14_clist_update_params(pdev, pgs, false,
11262
0
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11263
0
                *pcdev = dev;
11264
0
                return code;
11265
0
                break;
11266
0
            case PDF14_ABORT_DEVICE:
11267
0
                code = gx_abort_trans_device(pgs, dev);
11268
0
                if (pdev->free_devicen) {
11269
0
                    devn_free_params(dev);
11270
0
                }
11271
0
                pdf14_disable_device(dev);
11272
0
                pdf14_close(dev);
11273
0
                *pcdev = dev;
11274
0
                return code;
11275
0
                break;
11276
0
            default:
11277
0
                break;   /* Pass remaining ops to target */
11278
888k
        }
11279
888k
    }
11280
809k
    code = dev_proc(pdev->target, composite)
11281
809k
                        (pdev->target, pcdev, pct, pgs, mem, cdev);
11282
    /* If we were accumulating into a pdf14-clist-accum device, */
11283
    /* we now have to render the page into it's target device */
11284
809k
    if (is_pdf14_compositor && pdf14pct->params.pdf14_op == PDF14_POP_DEVICE &&
11285
8.91k
        pdev->target->stype == &st_gx_devn_accum_device) {
11286
11287
3.23k
        int i, y, rows_used;
11288
3.23k
        byte *linebuf;
11289
3.23k
        byte *actual_data;
11290
3.23k
        gx_device_pdf14_accum *tdev = (gx_device_pdf14_accum *)(pdev->target);     /* the printer class clist device used to accumulate */
11291
        /* get the target device we want to send the image to */
11292
3.23k
        gx_device *target = ((pdf14_device *)(tdev->save_p14dev))->target;
11293
3.23k
        gs_image1_t image;
11294
3.23k
        gs_color_space *pcs;
11295
3.23k
        gx_image_enum_common_t *info = NULL;
11296
3.23k
        gx_image_plane_t planes;
11297
3.23k
        gsicc_rendering_param_t render_cond;
11298
3.23k
        cmm_dev_profile_t *dev_profile;
11299
3.23k
        bool save_planar = pdev->num_planar_planes;
11300
3.23k
        gs_devn_params *target_devn_params = dev_proc(target, ret_devn_params)(target);
11301
3.23k
        int save_num_separations;
11302
3.23k
        gs_int_rect rect;
11303
11304
3.23k
        pdev->num_planar_planes = 0;    /* so gx_device_raster is for entire chunky pixel line */
11305
3.23k
        linebuf = gs_alloc_bytes(mem, gx_device_raster((gx_device *)pdev, true), "pdf14-clist_accum pop dev");
11306
3.23k
        pdev->num_planar_planes = save_planar;
11307
11308
        /* As long as we don't have spot colors, we can use ICC colorspace, but spot
11309
         * colors do require devn support
11310
         */
11311
3.23k
        if (tdev->color_info.num_components <= 4 ||
11312
3.23k
             dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) <= 0) {
11313
            /*
11314
             * Set color space in preparation for sending an image.
11315
             */
11316
3.23k
            code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
11317
3.23k
            if (code < 0)
11318
0
                goto put_accum_error;
11319
11320
            /* Need to set this to avoid color management during the
11321
               image color render operation.  Exception is for the special case
11322
               when the destination was CIELAB.  Then we need to convert from
11323
               default RGB to CIELAB in the put image operation.  That will happen
11324
               here as we should have set the profile for the pdf14 device to RGB
11325
               and the target will be CIELAB */
11326
3.23k
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11327
3.23k
            if (code < 0)
11328
0
                goto put_accum_error;
11329
3.23k
            gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile,
11330
3.23k
                                  &(pcs->cmm_icc_profile_data), &render_cond);
11331
            /* pcs takes a reference to the profile data it just retrieved. */
11332
3.23k
            gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_clist_composite");
11333
3.23k
            if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS) {
11334
0
                code = gs_note_error(gs_error_rangecheck);
11335
0
                goto put_accum_error;
11336
0
            }
11337
3.23k
            gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
11338
3.23k
        } else {
11339
             /* DeviceN case -- need to handle spot colors */
11340
0
            code = gs_cspace_new_DeviceN(&pcs, tdev->color_info.num_components,
11341
0
                                         gs_currentcolorspace(pgs), pgs->memory);
11342
0
            if (code < 0)
11343
0
                goto put_accum_error;
11344
            /* set up a usable DeviceN space with info from the tdev->devn_params */
11345
0
            pcs->params.device_n.use_alt_cspace = false;
11346
11347
0
            if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
11348
0
                goto put_accum_error;
11349
0
            }
11350
            /* One last thing -- we need to fudge the pgs->color_component_map */
11351
0
            for (i=0; i < tdev->color_info.num_components; i++)
11352
0
                pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
11353
            /* copy devn_params that were accumulated into the target device's devn_params */
11354
0
            target_devn_params->bitspercomponent = tdev->devn_params.bitspercomponent;
11355
0
            target_devn_params->std_colorant_names = tdev->devn_params.std_colorant_names;
11356
0
            target_devn_params->num_std_colorant_names = tdev->devn_params.num_std_colorant_names;
11357
0
            target_devn_params->max_separations = tdev->devn_params.max_separations;
11358
0
            target_devn_params->page_spot_colors = tdev->devn_params.page_spot_colors;
11359
0
            target_devn_params->num_separation_order_names = tdev->devn_params.num_separation_order_names;
11360
0
            target_devn_params->separations = tdev->devn_params.separations;
11361
0
            memcpy(target_devn_params->separation_order_map, tdev->devn_params.separation_order_map,
11362
0
                   sizeof(gs_separation_map));
11363
0
            target_devn_params->pdf14_separations = tdev->devn_params.pdf14_separations;
11364
0
        }
11365
3.23k
        if (linebuf == NULL) {
11366
0
            code = gs_error_VMerror;
11367
0
            goto put_accum_error;
11368
0
        }
11369
3.23k
        gs_image_t_init_adjust(&image, pcs, false);
11370
3.23k
        image.ImageMatrix.xx = (float)pdev->width;
11371
3.23k
        image.ImageMatrix.yy = (float)pdev->height;
11372
3.23k
        image.Width = pdev->width;
11373
3.23k
        image.Height = pdev->height;
11374
3.23k
        image.BitsPerComponent = 8<<deep;
11375
3.23k
        ctm_only_writable(pgs).xx = (float)pdev->width;
11376
3.23k
        ctm_only_writable(pgs).xy = 0;
11377
3.23k
        ctm_only_writable(pgs).yx = 0;
11378
3.23k
        ctm_only_writable(pgs).yy = (float)pdev->height;
11379
3.23k
        ctm_only_writable(pgs).tx = 0.0;
11380
3.23k
        ctm_only_writable(pgs).ty = 0.0;
11381
3.23k
        code = dev_proc(target, begin_typed_image) (target,
11382
3.23k
                                                    pgs, NULL,
11383
3.23k
                                                    (gs_image_common_t *)&image,
11384
3.23k
                                                    NULL, NULL, NULL,
11385
3.23k
                                                    pgs->memory, &info);
11386
3.23k
        if (code < 0)
11387
0
            goto put_accum_error;
11388
3.23k
        rect.p.x = 0;
11389
3.23k
        rect.q.x = tdev->width;
11390
6.92M
        for (y=0; y < tdev->height; y++) {
11391
6.91M
            gs_get_bits_params_t params;
11392
11393
6.91M
            params.options = (GB_ALIGN_ANY |
11394
6.91M
                              (GB_RETURN_COPY | GB_RETURN_POINTER) |
11395
6.91M
                              GB_OFFSET_0 |
11396
6.91M
                              GB_RASTER_STANDARD | GB_PACKING_CHUNKY |
11397
6.91M
                              GB_COLORS_NATIVE | GB_ALPHA_NONE);
11398
6.91M
            params.x_offset = 0;
11399
6.91M
            params.raster = bitmap_raster(dev->width * dev->color_info.depth);
11400
6.91M
            params.data[0] = linebuf;
11401
6.91M
            rect.p.y = y;
11402
6.91M
            rect.q.y = y+1;
11403
6.91M
            code = dev_proc(tdev, get_bits_rectangle)((gx_device *)tdev,
11404
6.91M
                                                      &rect, &params);
11405
6.91M
            if (code < 0)
11406
6
                goto put_accum_error;
11407
6.91M
            actual_data = params.data[0];
11408
6.91M
            planes.data = actual_data;
11409
6.91M
            planes.data_x = 0;
11410
6.91M
            planes.raster = tdev->width * tdev->color_info.num_components;
11411
6.91M
            if ((code = info->procs->plane_data(info, &planes, 1, &rows_used)) < 0)
11412
0
                goto put_accum_error;
11413
6.91M
        }
11414
11415
3.23k
put_accum_error:
11416
3.23k
        if (info != NULL) {
11417
3.23k
            if (code < 0)
11418
6
                (void)info->procs->end_image(info, true);
11419
3.23k
            else
11420
3.23k
                code = info->procs->end_image(info, true);
11421
3.23k
        }
11422
11423
3.23k
        gs_free_object(pdev->memory, linebuf, "pdf14_put_image");
11424
        /* This will also decrement the device profile */
11425
3.23k
        rc_decrement_only_cs(pcs, "pdf14_put_image");
11426
3.23k
        dev_proc(tdev, close_device)((gx_device *)tdev);  /* frees the prn_device memory */
11427
        /* Now unhook the clist device and hook to the original so we can clean up */
11428
3.23k
        gx_device_set_target((gx_device_forward *)pdev,
11429
3.23k
                             ((gx_device_pdf14_accum *)(pdev->target))->save_p14dev);
11430
3.23k
        pdev->pclist_device = pdev->target;
11431
3.23k
        *pcdev = pdev->target;          /* pass upwards to switch devices */
11432
3.23k
        pdev->color_info = target->color_info;      /* same as in pdf14_disable_clist */
11433
3.23k
        if (target_devn_params != NULL) {
11434
            /* prevent devn_free_params from freeing names still in use by target device */
11435
0
            save_num_separations = tdev->devn_params.separations.num_separations;
11436
0
            tdev->devn_params.separations.num_separations = 0;
11437
0
        }
11438
3.23k
        gs_free_object(tdev->memory, tdev, "popdevice pdf14-accum");
11439
3.23k
        if (target_devn_params != NULL) {
11440
0
            target_devn_params->separations.num_separations = save_num_separations;
11441
0
        }
11442
3.23k
        return code;    /* DON'T perform set_target */
11443
3.23k
    }
11444
806k
    if (code == 1) {
11445
        /* We just wrapped pdev->target, so we need to update that.*/
11446
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
11447
0
        code = 0; /* We did not wrap dev. */
11448
0
    }
11449
806k
    *pcdev = dev;
11450
806k
    return code;
11451
809k
}
11452
11453
/*
11454
 * The PDF 1.4 clist compositor is never removed.  (We do not have a 'remove
11455
 * compositor' method.  However the compositor is disabled when we are not
11456
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
11457
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
11458
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
11459
 * to the targer.
11460
 */
11461
static  int
11462
pdf14_clist_forward_composite(gx_device * dev, gx_device * * pcdev,
11463
        const gs_composite_t * pct, gs_gstate * pgs,
11464
        gs_memory_t * mem, gx_device *cdev)
11465
0
{
11466
0
    pdf14_device *pdev = (pdf14_device *)dev;
11467
0
    gx_device * tdev = pdev->target;
11468
0
    gx_device * ndev;
11469
0
    int code;
11470
11471
0
    *pcdev = dev;
11472
0
    if (gs_is_pdf14trans_compositor(pct)) {
11473
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11474
11475
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
11476
0
            return pdf14_clist_composite(dev, &ndev, pct, pgs, mem, cdev);
11477
0
        return 0;
11478
0
    }
11479
0
    code = dev_proc(tdev, composite)(tdev, &ndev, pct, pgs, mem, cdev);
11480
0
    if (code == 1) {
11481
        /* We just wrapped tdev, so update our target. */
11482
0
        gx_device_set_target((gx_device_forward *)pdev, ndev);
11483
0
        code = 0; /* We did not wrap dev. */
11484
0
    }
11485
0
    return code;
11486
0
}
11487
11488
/*
11489
 * If any of the PDF 1.4 transparency blending parameters have changed, we
11490
 * need to send them to the PDF 1.4 compositor on the output side of the clist.
11491
 */
11492
static  int
11493
pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs,
11494
                          bool crop_blend_params,
11495
                          gs_pdf14trans_params_t *group_params)
11496
3.55M
{
11497
3.55M
    gs_pdf14trans_params_t params = { 0 };
11498
3.55M
    gx_device * pcdev;
11499
3.55M
    int changed = 0;
11500
3.55M
    int code = 0;
11501
3.55M
    gs_composite_t *pct_new = NULL;
11502
11503
3.55M
    params.crop_blend_params = crop_blend_params;
11504
11505
3.55M
    params.pdf14_op = PDF14_SET_BLEND_PARAMS;
11506
3.55M
    if (pgs->blend_mode != pdev->blend_mode) {
11507
17.5k
        changed |= PDF14_SET_BLEND_MODE;
11508
17.5k
        params.blend_mode = pdev->blend_mode = pgs->blend_mode;
11509
17.5k
    }
11510
3.55M
    if (pgs->text_knockout != pdev->text_knockout) {
11511
8.59k
        changed |= PDF14_SET_TEXT_KNOCKOUT;
11512
8.59k
        params.text_knockout = pdev->text_knockout = pgs->text_knockout;
11513
8.59k
    }
11514
3.55M
    if (pgs->alphaisshape != pdev->ais) {
11515
1.46k
        changed |= PDF14_SET_AIS;
11516
1.46k
        params.ais = pdev->ais = pgs->alphaisshape;
11517
1.46k
    }
11518
3.55M
    if (pgs->overprint != pdev->overprint) {
11519
13.6k
        changed |= PDF14_SET_OVERPRINT;
11520
13.6k
        params.overprint = pdev->overprint = pgs->overprint;
11521
13.6k
    }
11522
3.55M
    if (pgs->stroke_overprint != pdev->stroke_overprint) {
11523
13.6k
        changed |= PDF14_SET_STROKEOVERPRINT;
11524
13.6k
        params.stroke_overprint = pdev->stroke_overprint = pgs->stroke_overprint;
11525
13.6k
    }
11526
3.55M
    if (pgs->fillconstantalpha != pdev->fillconstantalpha) {
11527
21.6k
        changed |= PDF14_SET_FILLCONSTANTALPHA;
11528
21.6k
        params.fillconstantalpha = pdev->fillconstantalpha = pgs->fillconstantalpha;
11529
21.6k
    }
11530
3.55M
    if (pgs->strokeconstantalpha != pdev->strokeconstantalpha) {
11531
15.4k
        changed |= PDF14_SET_STROKECONSTANTALPHA;
11532
15.4k
        params.strokeconstantalpha = pdev->strokeconstantalpha = pgs->strokeconstantalpha;
11533
15.4k
    }
11534
3.55M
    if ((pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_FILL)) {
11535
23.8k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11536
23.8k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_FILL;
11537
23.8k
        if_debug0m('v', pgs->memory,
11538
23.8k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as PDF14_OP_STATE_FILL \n");
11539
23.8k
    }
11540
3.55M
    if ((!pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_STROKE)) {
11541
24.8k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11542
24.8k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_STROKE;
11543
24.8k
        if_debug0m('v', pgs->memory,
11544
24.8k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as PDF14_OP_STATE_STROKE \n");
11545
24.8k
    }
11546
3.55M
    if (crop_blend_params) {
11547
35.5k
        params.ctm = group_params->ctm;
11548
35.5k
        params.bbox = group_params->bbox;
11549
35.5k
    }
11550
3.55M
    params.changed = changed;
11551
    /* Avoid recursion when we have a PDF14_SET_BLEND_PARAMS forced and apply
11552
       now to the target.  Otherwise we send the compositor action
11553
       to the pdf14 device at this time.  This is due to the fact that we
11554
       need to often perform this operation when we are already starting to
11555
       do a compositor action */
11556
3.55M
    if (changed != 0) {
11557
97.4k
        code = gs_create_pdf14trans(&pct_new, &params, pgs->memory);
11558
97.4k
        if (code < 0)
11559
0
            return code;
11560
97.4k
        code = dev_proc(pdev->target, composite)
11561
97.4k
                    (pdev->target, &pcdev, pct_new, (gs_gstate *)pgs, pgs->memory, NULL);
11562
97.4k
        gs_free_object(pgs->memory, pct_new, "pdf14_clist_update_params");
11563
97.4k
    }
11564
3.55M
    return code;
11565
3.55M
}
11566
11567
/*
11568
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11569
 * writing the clist.
11570
 */
11571
static  int
11572
pdf14_clist_fill_path(gx_device *dev, const gs_gstate *pgs,
11573
                           gx_path *ppath, const gx_fill_params *params,
11574
                           const gx_drawing_color *pdcolor,
11575
                           const gx_clip_path *pcpath)
11576
1.07M
{
11577
1.07M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11578
1.07M
    gs_gstate new_pgs = *pgs;
11579
1.07M
    int code;
11580
1.07M
    gs_pattern2_instance_t *pinst = NULL;
11581
1.07M
    gx_device_forward * fdev = (gx_device_forward *)dev;
11582
1.07M
    cmm_dev_profile_t *dev_profile, *fwd_profile;
11583
1.07M
    gsicc_rendering_param_t render_cond;
11584
1.07M
    cmm_profile_t *icc_profile_fwd, *icc_profile_dev;
11585
1.07M
    int push_group = 0;
11586
11587
1.07M
    code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11588
1.07M
    if (code < 0)
11589
0
        return code;
11590
1.07M
    code = dev_proc(fdev->target, get_profile)(fdev->target,  &fwd_profile);
11591
1.07M
    if (code < 0)
11592
0
        return code;
11593
11594
1.07M
    if (dev->color_info.separable_and_linear == GX_CINFO_UNKNOWN_SEP_LIN)
11595
933
        check_device_separable(dev);
11596
11597
1.07M
    gsicc_extract_profile(GS_UNKNOWN_TAG, fwd_profile, &icc_profile_fwd,
11598
1.07M
                          &render_cond);
11599
1.07M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile_dev,
11600
1.07M
                          &render_cond);
11601
11602
    /*
11603
     * Ensure that that the PDF 1.4 reading compositor will have the current
11604
     * blending parameters.  This is needed since the fill_rectangle routines
11605
     * do not have access to the gs_gstate.  Thus we have to pass any
11606
     * changes explictly.
11607
     */
11608
1.07M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11609
1.07M
    if (code < 0)
11610
0
        return code;
11611
    /* If we are doing a shading fill and we are in a transparency group of a
11612
       different color space, then we do not want to do the shading in the
11613
       device color space. It must occur in the source space.  To handle it in
11614
       the device space would require knowing all the nested transparency group
11615
       color space as well as the transparency.  Some of the shading code ignores
11616
       this, so we have to pass on the clist_writer device to enable proper
11617
       mapping to the transparency group color space. */
11618
11619
1.07M
    if (gx_dc_is_pattern2_color(pdcolor)) {
11620
        /* Non-idempotent blends require a transparency
11621
         * group to be pushed because shadings might
11622
         * paint several pixels twice. */
11623
9.44k
        push_group = pgs->fillconstantalpha != 1.0 ||
11624
8.89k
               !blend_is_idempotent(gs_currentblendmode(pgs));
11625
9.44k
        pinst =
11626
9.44k
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11627
9.44k
           pinst->saved->has_transparency = true;
11628
           /* The transparency color space operations are driven by the pdf14
11629
              clist writer device.  */
11630
9.44k
           pinst->saved->trans_device = dev;
11631
9.44k
    }
11632
1.07M
    if (push_group) {
11633
545
        gs_fixed_rect box;
11634
545
        gs_fixed_rect dev_bbox;
11635
11636
545
        if (pcpath) {
11637
545
            gx_cpath_outer_box(pcpath, &box);
11638
545
            (*dev_proc(dev, get_clipping_box)) (dev, &dev_bbox);
11639
545
            rect_intersect(box, dev_bbox);
11640
545
        } else
11641
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11642
11643
545
        if (ppath) {
11644
16
            gs_fixed_rect path_box;
11645
11646
16
            gx_path_bbox(ppath, &path_box);
11647
16
            if (box.p.x < path_box.p.x)
11648
16
                box.p.x = path_box.p.x;
11649
16
            if (box.p.y < path_box.p.y)
11650
16
                box.p.y = path_box.p.y;
11651
16
            if (box.q.x > path_box.q.x)
11652
16
                box.q.x = path_box.q.x;
11653
16
            if (box.q.y > path_box.q.y)
11654
16
                box.q.y = path_box.q.y;
11655
16
        }
11656
11657
545
        if (box.p.y >= box.q.y || box.p.x >= box.q.x) {
11658
            /* No need to do anything */
11659
218
            if (pinst != NULL) {
11660
218
                pinst->saved->trans_device = NULL;
11661
218
            }
11662
218
            return 0;
11663
218
        }
11664
11665
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11666
327
        code = push_shfill_group(pdev, &new_pgs, &box);
11667
327
    } else
11668
1.07M
        update_lop_for_pdf14(&new_pgs, pdcolor);
11669
1.07M
    if (code >= 0) {
11670
1.07M
        new_pgs.trans_device = dev;
11671
1.07M
        new_pgs.has_transparency = true;
11672
1.07M
        if (gx_dc_is_pattern2_color(pdcolor))
11673
9.22k
            code = gx_default_fill_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11674
1.06M
        else
11675
1.06M
            code = gx_forward_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11676
1.07M
        new_pgs.trans_device = NULL;
11677
1.07M
        new_pgs.has_transparency = false;
11678
1.07M
    }
11679
1.07M
    if (code >= 0 && push_group) {
11680
325
        code = pop_shfill_group(&new_pgs);
11681
325
        if (code >= 0)
11682
325
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11683
325
    }
11684
1.07M
    if (pinst != NULL){
11685
9.22k
        pinst->saved->trans_device = NULL;
11686
9.22k
    }
11687
1.07M
    return code;
11688
1.07M
}
11689
11690
/*
11691
 * stroke_path routine for the PDF 1.4 transparency compositor device for
11692
 * writing the clist.
11693
 */
11694
static  int
11695
pdf14_clist_stroke_path(gx_device *dev, const gs_gstate *pgs,
11696
                             gx_path *ppath, const gx_stroke_params *params,
11697
                             const gx_drawing_color *pdcolor,
11698
                             const gx_clip_path *pcpath)
11699
338k
{
11700
338k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11701
338k
    gs_gstate new_pgs = *pgs;
11702
338k
    int code = 0;
11703
338k
    gs_pattern2_instance_t *pinst = NULL;
11704
338k
    int push_group = 0;
11705
11706
    /*
11707
     * Ensure that that the PDF 1.4 reading compositor will have the current
11708
     * blending parameters.  This is needed since the fill_rectangle routines
11709
     * do not have access to the gs_gstate.  Thus we have to pass any
11710
     * changes explictly.
11711
     */
11712
338k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11713
338k
    if (code < 0)
11714
0
        return code;
11715
    /* If we are doing a shading stroke and we are in a transparency group of a
11716
       different color space, then we need to get the proper device information
11717
       passed along so that we use the correct color procs and colorinfo about
11718
       the transparency device and not the final target device */
11719
338k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11720
        /* Non-idempotent blends require a transparency
11721
         * group to be pushed because shadings might
11722
         * paint several pixels twice. */
11723
33
        push_group = pgs->strokeconstantalpha != 1.0 ||
11724
33
               !blend_is_idempotent(gs_currentblendmode(pgs));
11725
33
        if (pdev->color_model_stack != NULL) {
11726
33
            pinst =
11727
33
                (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11728
33
            pinst->saved->has_transparency = true;
11729
            /* The transparency color space operations are driven
11730
              by the pdf14 clist writer device.  */
11731
33
            pinst->saved->trans_device = dev;
11732
33
        }
11733
33
    }
11734
338k
    if (push_group) {
11735
0
        gs_fixed_rect box;
11736
0
        if (pcpath)
11737
0
            gx_cpath_outer_box(pcpath, &box);
11738
0
        else
11739
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11740
0
        if (ppath) {
11741
0
            gs_fixed_rect path_box;
11742
0
            gs_fixed_point expansion;
11743
11744
0
            gx_path_bbox(ppath, &path_box);
11745
            /* Expand the path bounding box by the scaled line width. */
11746
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
11747
                /* The expansion is so large it caused a limitcheck. */
11748
0
                path_box.p.x = path_box.p.y = min_fixed;
11749
0
                path_box.q.x = path_box.q.y = max_fixed;
11750
0
            } else {
11751
0
                expansion.x += pgs->fill_adjust.x;
11752
0
                expansion.y += pgs->fill_adjust.y;
11753
                /*
11754
                 * It's theoretically possible for the following computations to
11755
                 * overflow, so we need to check for this.
11756
                 */
11757
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
11758
0
                                path_box.p.x - expansion.x);
11759
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
11760
0
                                path_box.p.y - expansion.y);
11761
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
11762
0
                                path_box.q.x + expansion.x);
11763
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
11764
0
                                path_box.q.y + expansion.y);
11765
0
            }
11766
0
            if (box.p.x < path_box.p.x)
11767
0
                box.p.x = path_box.p.x;
11768
0
            if (box.p.y < path_box.p.y)
11769
0
                box.p.y = path_box.p.y;
11770
0
            if (box.q.x > path_box.q.x)
11771
0
                box.q.x = path_box.q.x;
11772
0
            if (box.q.y > path_box.q.y)
11773
0
                box.q.y = path_box.q.y;
11774
0
        }
11775
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11776
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
11777
0
        code = push_shfill_group(pdev, &new_pgs, &box);
11778
0
    } else
11779
338k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11780
11781
338k
    if (code >= 0) {
11782
338k
        new_pgs.trans_device = dev;
11783
338k
        new_pgs.has_transparency = true;
11784
338k
        if (gx_dc_is_pattern2_color(pdcolor))
11785
33
            code = gx_default_stroke_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11786
338k
        else
11787
338k
            code = gx_forward_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11788
338k
        new_pgs.trans_device = NULL;
11789
338k
        new_pgs.has_transparency = false;
11790
338k
    }
11791
338k
    if (code >= 0 && push_group) {
11792
0
        code = pop_shfill_group(&new_pgs);
11793
0
        if (code >= 0)
11794
0
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11795
0
    }
11796
338k
    if (pinst != NULL)
11797
33
        pinst->saved->trans_device = NULL;
11798
338k
    return code;
11799
338k
}
11800
11801
/* Set up work for doing shading patterns in fill stroke through
11802
   the clist.  We have to do all the dirty work now since we are
11803
   going through the default fill and stroke operations individually */
11804
static int
11805
pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs, gx_path* ppath,
11806
    const gx_fill_params* params_fill, const gx_drawing_color* pdevc_fill,
11807
    const gx_stroke_params* params_stroke, const gx_drawing_color* pdevc_stroke,
11808
    const gx_clip_path* pcpath)
11809
0
{
11810
0
    union {
11811
0
        const gs_gstate *cpgs;
11812
0
        gs_gstate *pgs;
11813
0
    } const_breaker;
11814
0
    gs_gstate *pgs;
11815
0
    int code, code2;
11816
0
    gs_transparency_group_params_t params = { 0 };
11817
0
    gs_fixed_rect clip_bbox;
11818
0
    gs_rect bbox, group_stroke_box;
11819
0
    float fill_alpha;
11820
0
    float stroke_alpha;
11821
0
    gs_blend_mode_t blend_mode;
11822
0
    gs_fixed_rect path_bbox;
11823
0
    int expansion_code;
11824
0
    gs_fixed_point expansion;
11825
11826
    /* Break const just once, neatly */
11827
0
    const_breaker.cpgs = cpgs;
11828
0
    pgs = const_breaker.pgs;
11829
11830
0
    fill_alpha = pgs->fillconstantalpha;
11831
0
    stroke_alpha = pgs->strokeconstantalpha;
11832
0
    blend_mode = pgs->blend_mode;
11833
11834
0
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
11835
0
    if (code < 0 && code != gs_error_unknownerror)
11836
0
        return code;
11837
0
    if (code == gs_error_unknownerror) {
11838
        /* didn't get clip box from gx_curr_fixed_bbox */
11839
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
11840
0
        clip_bbox.q.x = int2fixed(dev->width);
11841
0
        clip_bbox.q.y = int2fixed(dev->height);
11842
0
    }
11843
0
    if (pcpath)
11844
0
        rect_intersect(clip_bbox, pcpath->outer_box);
11845
11846
    /* expand the ppath using stroke expansion rule, then intersect it */
11847
0
    code = gx_path_bbox(ppath, &path_bbox);
11848
0
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0)
11849
0
        return 0;   /* ignore empty path */
11850
0
    if (code < 0)
11851
0
        return code;
11852
0
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
11853
0
    if (expansion_code >= 0) {
11854
0
        path_bbox.p.x -= expansion.x;
11855
0
        path_bbox.p.y -= expansion.y;
11856
0
        path_bbox.q.x += expansion.x;
11857
0
        path_bbox.q.y += expansion.y;
11858
0
    }
11859
0
    rect_intersect(path_bbox, clip_bbox);
11860
0
    bbox.p.x = fixed2float(path_bbox.p.x);
11861
0
    bbox.p.y = fixed2float(path_bbox.p.y);
11862
0
    bbox.q.x = fixed2float(path_bbox.q.x);
11863
0
    bbox.q.y = fixed2float(path_bbox.q.y);
11864
11865
0
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
11866
0
    if (code < 0)
11867
0
        return code;
11868
11869
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
11870
0
    if (pgs->fillconstantalpha == pgs->strokeconstantalpha &&
11871
0
        pgs->overprint && pgs->stroke_overprint &&
11872
0
        (dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11873
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
11874
11875
0
        params.Isolated = false;
11876
0
        params.group_color_type = UNKNOWN;
11877
0
        params.Knockout = false;
11878
0
        params.page_group = false;
11879
0
        params.group_opacity = fill_alpha;
11880
0
        params.group_shape = 1.0;
11881
11882
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
11883
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11884
0
        if (code < 0)
11885
0
            return code;
11886
11887
        /* Set alpha to 1.0 and compatible overprint mode for actual drawings */
11888
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11889
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
11890
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11891
11892
0
        code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11893
0
        if (code < 0)
11894
0
            goto cleanup;
11895
11896
0
        code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11897
0
        if (code < 0)
11898
0
            goto cleanup;
11899
11900
0
    } else {
11901
        /* Push a non-isolated knockout group. Do not change the alpha or
11902
           blend modes */
11903
0
        params.Isolated = false;
11904
0
        params.group_color_type = UNKNOWN;
11905
0
        params.Knockout = true;
11906
0
        params.page_group = false;
11907
0
        params.group_opacity = 1.0;
11908
0
        params.group_shape = 1.0;
11909
11910
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
11911
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11912
0
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11913
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11914
11915
        /* restore blend mode for actual drawing in the group */
11916
0
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11917
11918
0
        if (fill_alpha > 0.0) {
11919
0
            (void)gs_setfillconstantalpha(pgs, fill_alpha);
11920
11921
            /* If we are in an overprint situation, set the blend mode to compatible
11922
               overprint */
11923
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11924
0
                pgs->overprint &&
11925
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11926
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11927
11928
0
            code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11929
0
            if (code < 0)
11930
0
                goto cleanup;
11931
11932
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11933
0
                pgs->overprint &&
11934
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11935
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11936
0
        }
11937
11938
0
        if (stroke_alpha > 0.0) {
11939
            /* Note that the stroke can end up looking like a fill here */
11940
0
            (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11941
0
            (void)gs_setfillconstantalpha(pgs, stroke_alpha);
11942
11943
0
            if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11944
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11945
11946
0
            code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11947
0
            if (code < 0)
11948
0
                goto cleanup;
11949
11950
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11951
0
                pgs->overprint &&
11952
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11953
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11954
0
        }
11955
0
    }
11956
11957
0
cleanup:
11958
    /* Now during the pop do the compositing with alpha of 1.0 and normal blend */
11959
0
    (void)gs_setfillconstantalpha(pgs, 1.0);
11960
0
    (void)gs_setstrokeconstantalpha(pgs, 1.0);
11961
0
    (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11962
11963
    /* Restore where we were. If an error occured while in the group push
11964
       return that error code but try to do the cleanup */
11965
0
    code2 = gs_end_transparency_group(pgs);
11966
0
    if (code2 < 0) {
11967
        /* At this point things have gone very wrong. We should just shut down */
11968
0
        code = gs_abort_pdf14trans_device(pgs);
11969
0
        return code2;
11970
0
    }
11971
11972
    /* Restore if there were any changes */
11973
0
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
11974
0
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11975
0
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11976
11977
0
    return code;
11978
0
}
11979
11980
/*
11981
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11982
 * writing the clist.
11983
 */
11984
static  int
11985
pdf14_clist_fill_stroke_path(gx_device  *dev, const gs_gstate *pgs, gx_path *ppath,
11986
                             const gx_fill_params *params_fill, const gx_drawing_color *pdevc_fill,
11987
                             const gx_stroke_params *params_stroke, const gx_drawing_color *pdevc_stroke,
11988
                             const gx_clip_path *pcpath)
11989
7.13k
{
11990
7.13k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11991
7.13k
    gs_gstate new_pgs = *pgs;
11992
7.13k
    int code;
11993
11994
7.13k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
11995
7.06k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
11996
81
        return 0;
11997
11998
    /*
11999
     * Ensure that that the PDF 1.4 reading compositor will have the current
12000
     * blending parameters.  This is needed since the fill_rectangle routines
12001
     * do not have access to the gs_gstate.  Thus we have to pass any
12002
     * changes explictly.
12003
     */
12004
7.05k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12005
7.05k
    if (code < 0)
12006
0
        return code;
12007
    /* If we are doing a shading fill or stroke, the clist can't
12008
       deal with this and end up in the pdf_fill_stroke operation.
12009
       We will need to break up the fill stroke now and do
12010
       the appropriate group pushes and set up. */
12011
12012
7.05k
    if (gx_dc_is_pattern2_color(pdevc_fill) ||
12013
7.05k
        gx_dc_is_pattern2_color(pdevc_stroke)) {
12014
0
        return pdf14_clist_fill_stroke_path_pattern_setup(dev, pgs, ppath,
12015
0
            params_fill, pdevc_fill, params_stroke, pdevc_stroke, pcpath);
12016
0
    }
12017
7.05k
    update_lop_for_pdf14(&new_pgs, pdevc_fill);
12018
7.05k
    new_pgs.trans_device = dev;
12019
7.05k
    new_pgs.has_transparency = true;
12020
7.05k
    code = gx_forward_fill_stroke_path(dev, &new_pgs, ppath, params_fill, pdevc_fill,
12021
7.05k
                                       params_stroke, pdevc_stroke, pcpath);
12022
7.05k
    new_pgs.trans_device = NULL;
12023
7.05k
    new_pgs.has_transparency = false;
12024
7.05k
    return code;
12025
7.05k
}
12026
12027
/*
12028
 * text_begin routine for the PDF 1.4 transaprency compositor device for
12029
 * writing the clist.
12030
 */
12031
static  int
12032
pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs,
12033
                 const gs_text_params_t * text, gs_font * font,
12034
                 const gx_clip_path * pcpath,
12035
                 gs_text_enum_t ** ppenum)
12036
2.05M
{
12037
2.05M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12038
2.05M
    gs_text_enum_t *penum;
12039
2.05M
    int code;
12040
2.05M
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
12041
2.05M
    float opacity = pgs->fillconstantalpha;
12042
2.05M
    float shape = 1.0;
12043
2.05M
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
12044
2.05M
    bool draw = !(text->operation & TEXT_DO_NONE);
12045
2.05M
    uint text_mode = gs_currenttextrenderingmode(pgs);
12046
2.05M
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
12047
2.05M
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
12048
12049
2.05M
    if_debug0m('v', pgs->memory, "[v]pdf14_clist_text_begin\n");
12050
    /*
12051
     * Ensure that that the PDF 1.4 reading compositor will have the current
12052
     * blending parameters.  This is needed since the fill_rectangle routines
12053
     * do not have access to the gs_gstate.  Thus we have to pass any
12054
     * changes explictly.
12055
     */
12056
2.05M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12057
2.05M
    if (code < 0)
12058
0
        return code;
12059
    /* Pass text_begin to the target */
12060
2.05M
    code = gx_forward_text_begin(dev, pgs, text, font,
12061
2.05M
                                 pcpath, &penum);
12062
2.05M
    if (code < 0)
12063
713
        return code;
12064
12065
   /* Catch case where we already pushed a group and are trying to push another one.
12066
   In that case, we will pop the current one first, as we don't want to be left
12067
   with it. Note that if we have a BT and no other BTs or ETs then this issue
12068
   will not be caught until we do the put_image and notice that the stack is not
12069
   empty. */
12070
2.05M
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
12071
1
        code = gs_end_transparency_group(pgs);
12072
1
        if (code < 0)
12073
0
            return code;
12074
1
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
12075
1
    }
12076
12077
    /* We may need to push a non-isolated transparency group if the following
12078
    is true.
12079
    1) We are not currently in one that we pushed for text.  This is
12080
    is determined by looking at the pdf14 device.
12081
    2) The blend mode is not Normal or the opacity is not 1.0
12082
    3) Text knockout is set to true
12083
    4) And we are actually drawing text
12084
    */
12085
12086
2.05M
    if (gs_currenttextknockout(pgs) && (blend_issue ||
12087
2.04M
        (pgs->fillconstantalpha != 1.0 && text_fill) ||
12088
2.04M
        (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
12089
10.0k
        text_mode != 3 && /* don't bother with invisible text */
12090
9.99k
        pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED) {
12091
2.27k
        if (draw) {
12092
2.27k
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape, true);
12093
2.27k
            if (code == 0)
12094
2.27k
                pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* Needed during clist writing */
12095
2.27k
        }
12096
2.27k
    }
12097
2.05M
    *ppenum = (gs_text_enum_t *)penum;
12098
2.05M
    return code;
12099
2.05M
}
12100
12101
static  int
12102
pdf14_clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
12103
                           const gs_matrix *pmat, const gs_image_common_t *pic,
12104
                           const gs_int_rect * prect,
12105
                           const gx_drawing_color * pdcolor,
12106
                           const gx_clip_path * pcpath, gs_memory_t * mem,
12107
                           gx_image_enum_common_t ** pinfo)
12108
37.0k
{
12109
37.0k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12110
37.0k
    int code;
12111
37.0k
    gs_gstate * pgs_noconst = (gs_gstate *)pgs; /* Break 'const'. */
12112
37.0k
    const gs_image_t *pim = (const gs_image_t *)pic;
12113
37.0k
    gx_image_enum *penum;
12114
37.0k
    gx_color_tile *ptile;
12115
37.0k
    gs_rect bbox_in, bbox_out;
12116
37.0k
    gs_transparency_group_params_t tgp;
12117
    /*
12118
     * Ensure that that the PDF 1.4 reading compositor will have the current
12119
     * blending parameters.  This is needed since the fill_rectangle routines
12120
     * do not have access to the gs_gstate.  Thus we have to pass any
12121
     * changes explictly.
12122
     */
12123
37.0k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12124
37.0k
    if (code < 0)
12125
0
        return code;
12126
    /* Pass image to the target */
12127
    /* Do a quick change to the gs_gstate so that if we can return with -1 in
12128
       case the clist writer cannot handle this image itself.  In such a case,
12129
       we want to make sure we dont use the target device.  I don't necc. like
12130
       doing it this way.  Probably need to go back and do something a bit
12131
       more elegant. */
12132
37.0k
    pgs_noconst->has_transparency = true;
12133
37.0k
    pgs_noconst->trans_device = dev;
12134
12135
    /* If we are filling an image mask with a pattern that has a transparency
12136
       then we need to do some special handling */
12137
37.0k
    if (pim->ImageMask) {
12138
84
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
12139
21
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
12140
0
                if (dev_proc(dev, begin_typed_image) != pdf14_clist_begin_typed_image) {
12141
0
                    ptile = pdcolor->colors.pattern.p_tile;
12142
                    /* Set up things in the ptile so that we get the proper
12143
                       blending etc */
12144
                    /* Set the blending procs and the is_additive setting based
12145
                       upon the number of channels */
12146
0
                    if (ptile->ttrans->n_chan-1 < 4) {
12147
0
                        ptile->ttrans->blending_procs = &rgb_blending_procs;
12148
0
                        ptile->ttrans->is_additive = true;
12149
0
                    } else {
12150
0
                        ptile->ttrans->blending_procs = &cmyk_blending_procs;
12151
0
                        ptile->ttrans->is_additive = false;
12152
0
                    }
12153
                    /* Set the blending mode in the ptile based upon the current
12154
                       setting in the gs_gstate */
12155
0
                    ptile->blending_mode = pgs->blend_mode;
12156
                    /* Set the procs so that we use the proper filling method. */
12157
                    /* Let the imaging stuff get set up */
12158
0
                    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
12159
0
                                                        prect, pdcolor,
12160
0
                                                        pcpath, mem, pinfo);
12161
0
                    if (code < 0)
12162
0
                        return code;
12163
12164
0
                    penum = (gx_image_enum *) *pinfo;
12165
                    /* Apply inverse of the image matrix to our
12166
                       image size to get our bounding box. */
12167
0
                    bbox_in.p.x = 0;
12168
0
                    bbox_in.p.y = 0;
12169
0
                    bbox_in.q.x = pim->Width;
12170
0
                    bbox_in.q.y = pim->Height;
12171
0
                    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
12172
0
                                                     &bbox_out);
12173
0
                    if (code < 0)
12174
0
                        return code;
12175
                    /* Set up a compositor action for pushing the group */
12176
0
                    if_debug0m('v', pgs->memory, "[v]Pushing special trans group for image\n");
12177
0
                    tgp.Isolated = true;
12178
0
                    tgp.Knockout = false;
12179
0
                    tgp.page_group = false;
12180
0
                    tgp.mask_id = 0;
12181
0
                    tgp.image_with_SMask = false;
12182
0
                    tgp.idle = false;
12183
0
                    tgp.iccprofile = NULL;
12184
0
                    tgp.icc_hashcode = 0;
12185
0
                    tgp.group_color_numcomps = ptile->ttrans->n_chan-1;
12186
0
                    tgp.ColorSpace = NULL;
12187
0
                    tgp.text_group = 0;
12188
0
                    tgp.group_opacity = pgs->fillconstantalpha;
12189
0
                    tgp.group_shape = 1.0;
12190
                    /* This will handle the compositor command */
12191
0
                    gs_begin_transparency_group((gs_gstate *) pgs_noconst, &tgp,
12192
0
                                                &bbox_out, PDF14_BEGIN_TRANS_GROUP);
12193
0
                    ptile->ttrans->image_render = penum->render;
12194
0
                    penum->render = &pdf14_pattern_trans_render;
12195
0
                    ptile->trans_group_popped = false;
12196
0
                    pgs_noconst->has_transparency = false;
12197
0
                    pgs_noconst->trans_device = NULL;
12198
0
                    return code;
12199
0
                }
12200
0
            }
12201
21
        }
12202
84
    }
12203
    /* This basically tries high level images for clist. If that fails
12204
       then we do the default */
12205
37.0k
    code = gx_forward_begin_typed_image(dev, pgs, pmat,
12206
37.0k
                            pic, prect, pdcolor, pcpath, mem, pinfo);
12207
37.0k
    if (code < 0){
12208
9.52k
        code = gx_default_begin_typed_image(dev, pgs, pmat, pic, prect,
12209
9.52k
                                        pdcolor, pcpath, mem, pinfo);
12210
9.52k
        pgs_noconst->has_transparency = false;
12211
9.52k
        pgs_noconst->trans_device = NULL;
12212
9.52k
        return code;
12213
27.5k
    } else {
12214
27.5k
        pgs_noconst->has_transparency = false;
12215
27.5k
        pgs_noconst->trans_device = NULL;
12216
27.5k
        return code;
12217
27.5k
    }
12218
37.0k
}
12219
12220
static int
12221
pdf14_clist_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
12222
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
12223
2.45k
{
12224
2.45k
    int code;
12225
12226
2.45k
    code = gx_forward_copy_planes(dev, data, data_x, raster, id,
12227
2.45k
                                  x, y, w, h, plane_height);
12228
2.45k
    return code;
12229
2.45k
}
12230
12231
static int
12232
gs_pdf14_clist_device_push(gs_memory_t *mem, gs_gstate *pgs, gx_device **pcdev,
12233
                           gx_device *dev, const gs_pdf14trans_t *pdf14pct)
12234
9.40k
{
12235
9.40k
    int code;
12236
9.40k
    pdf14_clist_device *p14dev;
12237
9.40k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12238
12239
9.40k
    code = pdf14_create_clist_device(mem, pgs, pcdev, dev, pdf14pct);
12240
9.40k
    if (code < 0)
12241
0
        return code;
12242
    /*
12243
     * Set the color_info of the clist device to match the compositing
12244
     * device.  We will restore it when the compositor is popped.
12245
     * See pdf14_clist_composite for the restore.  Do the
12246
     * same with the gs_gstate's get_cmap_procs.  We do not want
12247
     * the gs_gstate to use transfer functions on our color values.
12248
     * The transfer functions will be applied at the end after we
12249
     * have done our PDF 1.4 blend operations.
12250
     */
12251
9.40k
    p14dev = (pdf14_clist_device *)(*pcdev);
12252
9.40k
    p14dev->saved_target_color_info = dev->color_info;
12253
9.40k
    dev->color_info = (*pcdev)->color_info;
12254
    /* Make sure that we keep the anti-alias information though */
12255
9.40k
    dev->color_info.anti_alias = p14dev->saved_target_color_info.anti_alias;
12256
9.40k
    p14dev->color_info.anti_alias = dev->color_info.anti_alias;
12257
12258
    /* adjust the clist_color_info now */
12259
9.40k
    cdev->clist_color_info.depth = p14dev->color_info.depth;
12260
9.40k
    cdev->clist_color_info.polarity = p14dev->color_info.polarity;
12261
9.40k
    cdev->clist_color_info.num_components = p14dev->color_info.num_components;
12262
9.40k
    cdev->clist_color_info.max_color = p14dev->color_info.max_color;
12263
9.40k
    cdev->clist_color_info.max_gray = p14dev->color_info.max_gray;
12264
12265
9.40k
    p14dev->saved_target_encode_color = dev_proc(dev, encode_color);
12266
9.40k
    p14dev->saved_target_decode_color = dev_proc(dev, decode_color);
12267
9.40k
    set_dev_proc(dev, encode_color, p14dev->my_encode_color);
12268
9.40k
    set_dev_proc(p14dev, encode_color, p14dev->my_encode_color);
12269
9.40k
    set_dev_proc(dev, decode_color, p14dev->my_decode_color);
12270
9.40k
    set_dev_proc(p14dev, decode_color, p14dev->my_decode_color);
12271
9.40k
    p14dev->saved_target_get_color_mapping_procs =
12272
9.40k
                              dev_proc(dev, get_color_mapping_procs);
12273
9.40k
    p14dev->saved_target_get_color_comp_index =
12274
9.40k
                              dev_proc(dev, get_color_comp_index);
12275
9.40k
    set_dev_proc(dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12276
9.40k
    set_dev_proc(p14dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12277
9.40k
    set_dev_proc(dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12278
9.40k
    set_dev_proc(p14dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12279
9.40k
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
12280
9.40k
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
12281
9.40k
    gx_set_cmap_procs(pgs, dev);
12282
9.40k
    return code;
12283
9.40k
}
12284
/*
12285
 * When we push a PDF 1.4 transparency compositor onto the clist, we also need
12286
 * to create a compositing device for clist writing.  The primary purpose of
12287
 * this device is to provide support for the process color model in which
12288
 * the PDF 1.4 transparency is done.  (This may differ from the process color
12289
 * model of the output device.)  The actual work of compositing the image is
12290
 * done on the output (reader) side of the clist.
12291
 */
12292
static  int
12293
c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev,
12294
                gx_device ** pcdev, gs_gstate * pgs, gs_memory_t * mem)
12295
255k
{
12296
255k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12297
255k
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte;
12298
255k
    int code = 0;
12299
12300
    /* We only handle the push/pop operations */
12301
255k
    switch (pdf14pct->params.pdf14_op) {
12302
9.40k
        case PDF14_PUSH_DEVICE:
12303
9.40k
            code = gs_pdf14_clist_device_push(mem, pgs, pcdev, dev, pdf14pct);
12304
            /* Change (non-error) code to 1 to indicate that we created
12305
             * a device. */
12306
9.40k
            if (code >= 0)
12307
9.40k
                code = 1;
12308
9.40k
            return code;
12309
12310
8.91k
        case PDF14_POP_DEVICE:
12311
8.91k
            code = clist_writer_check_empty_cropping_stack(cdev);
12312
8.91k
            break;
12313
12314
3.31k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12315
35.5k
        case PDF14_BEGIN_TRANS_GROUP:
12316
35.5k
            { /* HACK: store mask_id into our params for subsequent
12317
                   calls of c_pdf14trans_write. To do this we must
12318
                   break const. */
12319
35.5k
                gs_pdf14trans_t * pdf14pct_noconst;
12320
12321
35.5k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12322
                /* What ever the current mask ID is, that is the
12323
                   softmask group through which this transparency
12324
                   group must be rendered. Store it now. */
12325
35.5k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12326
35.5k
                if_debug1m('v', pgs->memory,
12327
35.5k
                           "[v]c_pdf14trans_clist_write_update group mask_id=%d \n",
12328
35.5k
                           cdev->mask_id);
12329
35.5k
            }
12330
35.5k
            break;
12331
33.2k
        case PDF14_END_TRANS_GROUP:
12332
35.5k
        case PDF14_END_TRANS_TEXT_GROUP:
12333
35.5k
            code = 0; /* A place for breakpoint. */
12334
35.5k
            break;
12335
36.6k
        case PDF14_BEGIN_TRANS_MASK:
12336
            /* A new mask has been started */
12337
36.6k
            cdev->mask_id = ++cdev->mask_id_count;
12338
            /* replacing is set everytime that we
12339
               have a zpushtransparencymaskgroup */
12340
36.6k
            { /* HACK: store mask_id into our params for subsequent
12341
                   calls of c_pdf14trans_write. To do this we must
12342
                   break const. */
12343
36.6k
                gs_pdf14trans_t * pdf14pct_noconst;
12344
12345
36.6k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12346
36.6k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12347
36.6k
                if_debug1m('v', pgs->memory,
12348
36.6k
                           "[v]c_pdf14trans_clist_write_update mask mask_id=%d \n",
12349
36.6k
                           cdev->mask_id);
12350
36.6k
            }
12351
36.6k
            break;
12352
16.3k
        case PDF14_END_TRANS_MASK:
12353
16.3k
            code = 0; /* A place for breakpoint. */
12354
16.3k
            break;
12355
0
        case PDF14_PUSH_TRANS_STATE:
12356
0
            code = 0; /* A place for breakpoint. */
12357
0
            break;
12358
15.9k
        case PDF14_POP_TRANS_STATE:
12359
15.9k
            code = 0; /* A place for breakpoint. */
12360
15.9k
            break;
12361
0
        case PDF14_ABORT_DEVICE:
12362
0
            code = 0;
12363
0
            break;
12364
0
        case PDF14_PUSH_SMASK_COLOR:
12365
0
            *pcdev = dev;
12366
0
            return 0;
12367
0
            break;
12368
0
        case PDF14_POP_SMASK_COLOR:
12369
0
            *pcdev = dev;
12370
0
            return 0;
12371
0
            break;
12372
97.4k
        default:
12373
97.4k
            break;   /* do nothing for remaining ops */
12374
255k
    }
12375
246k
    *pcdev = dev;
12376
246k
    if (code < 0)
12377
0
        return code;
12378
    /* See c_pdf14trans_write, c_pdf14trans_adjust_ctm, and
12379
       apply_composite. */
12380
246k
    code = gs_gstate_setmatrix(&cdev->gs_gstate, &pdf14pct->params.ctm);
12381
    /* Wrote an extra ctm. */
12382
246k
    cmd_clear_known(cdev, ctm_known);
12383
12384
246k
    return code;
12385
246k
}
12386
12387
/*
12388
 * When we push a PDF 1.4 transparency compositor, we need to make the clist
12389
 * device color_info data match the compositing device.  We need to do this
12390
 * since the PDF 1.4 transparency compositing device may use a different
12391
 * process color model than the output device.  We do not need to modify the
12392
 * color related device procs since the compositing device has its own.  We
12393
 * restore the color_info data when the transparency device is popped.
12394
 */
12395
static  int
12396
c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
12397
                gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem)
12398
19.6M
{
12399
19.6M
    pdf14_device * p14dev = (pdf14_device *)tdev;
12400
19.6M
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12401
19.6M
    gs_devn_params * pclist_devn_params;
12402
19.6M
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)cdev;
12403
19.6M
    cmm_profile_t *cl_icc_profile, *p14_icc_profile;
12404
19.6M
    gsicc_rendering_param_t render_cond;
12405
19.6M
    cmm_dev_profile_t *dev_profile;
12406
12407
19.6M
    dev_proc(cdev, get_profile)(cdev,  &dev_profile);
12408
19.6M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &cl_icc_profile,
12409
19.6M
                          &render_cond);
12410
12411
    /* If we are using the blending color space, then be sure to use that. */
12412
19.6M
    if (p14dev->blend_cs_state == PDF14_BLEND_CS_SPECIFIED &&
12413
0
        dev_profile->blend_profile != NULL)
12414
0
        cl_icc_profile = dev_profile->blend_profile;
12415
19.6M
    else if (p14dev->blend_cs_state == PDF14_BLEND_CS_OUTPUTINTENT &&
12416
0
        dev_profile->oi_profile != NULL)
12417
0
        cl_icc_profile = dev_profile->oi_profile;
12418
12419
19.6M
    dev_proc(p14dev, get_profile)((gx_device *)p14dev,  &dev_profile);
12420
19.6M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &p14_icc_profile,
12421
19.6M
                          &render_cond);
12422
    /*
12423
     * We only handle the push/pop operations. Save and restore the color_info
12424
     * field for the clist device.  This is needed since the process color
12425
     * model of the clist device needs to match the PDF 1.4 compositing
12426
     * device.
12427
     */
12428
19.6M
    switch (pdf14pct->params.pdf14_op) {
12429
958k
    case PDF14_PUSH_DEVICE:
12430
        /* Overprint simulation sets the profile at prototype creation, as does
12431
           when the target profile is NCLR. Match the logic in gs_pdf14_device_push */
12432
958k
        if (!((p14dev->overprint_sim && cl_icc_profile->data_cs != gsCMYK) ||
12433
958k
            cl_icc_profile->data_cs == gsNCHANNEL)) {
12434
958k
            gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update");
12435
958k
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12436
958k
                -1, "c_pdf14trans_clist_read_update");
12437
958k
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile;
12438
958k
        }
12439
            /*
12440
             * If we are blending using spot colors (i.e. the output device
12441
             * supports spot colors) then we need to transfer
12442
             * color info from the clist PDF 1.4 compositing reader device
12443
             * to the clist writer PDF 1.4 compositing device.
12444
             * This info was transfered from that device to the output
12445
             * device as a set of device parameters.  However the clist
12446
             * reader PDF 1.4 compositing device did not exist when the
12447
             * device parameters were read from the clist.  So that info
12448
             * was buffered into the output device.
12449
             */
12450
958k
            pclist_devn_params = dev_proc(cdev, ret_devn_params)(cdev);
12451
958k
            if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors > 0) {
12452
555
                int num_comp = p14dev->color_info.num_components;
12453
555
                int has_tags = device_encodes_tags((gx_device *)p14dev);
12454
                /*
12455
                 * The number of components for the PDF14 device is the sum
12456
                 * of the process components and the number of spot colors
12457
                 * for the page.  If the color capabilities of the parent
12458
                 * device (which coming into this are the same as the p14dev)
12459
                 * are smaller than the number of page spot colors then
12460
                 * use that for the number of components. Otherwise use
12461
                 * the page_spot_colors.  The exception is, if we had used
12462
                 * the sICCOutputColors setting, then just use that, which
12463
                 * should be already baked into num_comp. With clist patterns,
12464
                 * cdev->icc_struct may be null.
12465
                 */
12466
12467
555
                if (cdev->icc_struct == NULL || cdev->icc_struct->spotnames == NULL) {
12468
555
                    p14dev->devn_params.page_spot_colors =
12469
555
                        pclist_devn_params->page_spot_colors;
12470
555
                    if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
12471
0
                        if (p14dev->num_planar_planes > 0)
12472
0
                            p14dev->num_planar_planes += num_comp - p14dev->color_info.num_components;
12473
0
                        p14dev->color_info.num_components = num_comp;
12474
0
                        assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12475
555
                    } else {
12476
                        /* if page_spot_colors < 0, this will be wrong, so don't update num_components */
12477
555
                        if (p14dev->devn_params.page_spot_colors >= 0) {
12478
555
                            int n = p14dev->num_std_colorants +
12479
555
                                    p14dev->devn_params.page_spot_colors + has_tags;
12480
555
                            if (p14dev->num_planar_planes > 0)
12481
555
                                p14dev->num_planar_planes += n - p14dev->color_info.num_components;
12482
555
                            p14dev->color_info.num_components = n;
12483
555
                            assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12484
555
                        }
12485
555
                    }
12486
555
                }
12487
                /* limit the num_components to the max. */
12488
555
                if (p14dev->color_info.num_components > p14dev->color_info.max_components + has_tags)
12489
0
                    p14dev->color_info.num_components = p14dev->color_info.max_components + has_tags;
12490
                /* Transfer the data for the spot color names
12491
                   But we have to free what may be there before we do this */
12492
555
                devn_free_params((gx_device*) p14dev);
12493
555
                p14dev->devn_params.separations =
12494
555
                    pclist_devn_params->pdf14_separations;
12495
555
                p14dev->free_devicen = false;  /* to avoid freeing the clist ones */
12496
555
                if (num_comp != p14dev->color_info.num_components) {
12497
                    /* Historically, there has been a comment here:
12498
                       "When the pdf14 device is opened it creates a context and some
12499
                       soft mask related objects.  The push device compositor action
12500
                       will have already created these but they are the wrong size.
12501
                       We must destroy them though before reopening the device."
12502
                       I can't see why this is the case, and testing in the cluster
12503
                       doesn't show ill effects from not doing it. Indeed, Bug 707790
12504
                       shows that this freeing/NULLing the ctx here causes problems
12505
                       when the freed ctx is reinserted at the end of clist pattern
12506
                       files. Accordingly, I'm removing the freeing/NULLing for now
12507
                       at least. */
12508
0
                    int code = dev_proc(tdev, open_device) (tdev);
12509
0
                    if (code < 0)
12510
0
                        return code;
12511
0
                }
12512
555
            }
12513
            /* Check if we need to swap out the ICC profile for the pdf14
12514
               device.  This will occur if our source profile for our device
12515
               happens to be something like CIELAB.  Then we will blend in
12516
               RGB (unless a trans group is specified) */
12517
958k
            if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) {
12518
0
                gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12519
0
                                        -1, "c_pdf14trans_clist_read_update");
12520
                /* Initial ref count from gsicc_read_serial_icc() is 1, which is what we want */
12521
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
12522
0
                                        gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash);
12523
                /* Keep a pointer to the clist device */
12524
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->dev = (gx_device *) cdev;
12525
0
            }
12526
958k
            break;
12527
12528
958k
        case PDF14_POP_DEVICE:
12529
#     if 0 /* Disabled because *p14dev has no forwarding methods during
12530
                    the clist playback. This code is not executed while clist
12531
                    writing. */
12532
            cdev->color_info = p14dev->saved_target_color_info;
12533
#     endif
12534
958k
           break;
12535
12536
17.7M
        default:
12537
17.7M
            break;   /* do nothing for remaining ops */
12538
19.6M
    }
12539
12540
19.6M
    return 0;
12541
19.6M
}
12542
12543
/*
12544
 * Get cropping for the compositor command.
12545
 */
12546
static  int
12547
c_pdf14trans_get_cropping(const gs_composite_t *pcte, int *ry, int *rheight,
12548
                          int cropping_min, int cropping_max)
12549
255k
{
12550
255k
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12551
255k
    switch (pdf14pct->params.pdf14_op) {
12552
9.40k
        case PDF14_PUSH_DEVICE: return ALLBANDS; /* Applies to all bands. */
12553
8.91k
        case PDF14_POP_DEVICE:  return ALLBANDS; /* Applies to all bands. */
12554
0
        case PDF14_ABORT_DEVICE: return ALLBANDS; /* Applies to all bands */
12555
3.31k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12556
35.5k
        case PDF14_BEGIN_TRANS_GROUP:
12557
35.5k
            { gs_int_rect rect;
12558
12559
                /* Text group always uses parents size*/
12560
35.5k
                if (pdf14pct->params.text_group == PDF14_TEXTGROUP_BT_PUSHED) {
12561
2.27k
                    *ry = cropping_min;
12562
2.27k
                    *rheight = cropping_max - *ry;
12563
33.2k
                } else {
12564
33.2k
                    pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12565
33.2k
                        &pdf14pct->params.bbox, &rect);
12566
                    /* We have to crop this by the parent object.   */
12567
33.2k
                    *ry = max(rect.p.y, cropping_min);
12568
33.2k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12569
33.2k
                }
12570
35.5k
                return PUSHCROP; /* Push cropping. */
12571
3.31k
            }
12572
36.6k
        case PDF14_BEGIN_TRANS_MASK:
12573
36.6k
            { gs_int_rect rect;
12574
12575
36.6k
                pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12576
36.6k
                                                    &pdf14pct->params.bbox, &rect);
12577
                /* We have to crop this by the parent object and worry about the BC outside
12578
                   the range, except for image SMask which don't affect areas outside the image.
12579
                   The presence of a transfer function opens the possibility of issues with this */
12580
36.6k
                if (pdf14pct->params.mask_is_image || (pdf14pct->params.GrayBackground == 1.0 &&
12581
15.3k
                      pdf14pct->params.function_is_identity)) {
12582
                    /* In this case there will not be a background effect to
12583
                       worry about.  The mask will not have any effect outside
12584
                       the bounding box.  This is NOT the default or common case. */
12585
15.3k
                    *ry = max(rect.p.y, cropping_min);
12586
15.3k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12587
15.3k
                    return PUSHCROP; /* Push cropping. */
12588
21.3k
                }  else {
12589
                    /* We need to make the soft mask range as large as the parent
12590
                       due to the fact that the background color can have an impact
12591
                       OUTSIDE the bounding box of the soft mask */
12592
21.3k
                    *ry = cropping_min;
12593
21.3k
                    *rheight = cropping_max - cropping_min;
12594
21.3k
                    if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
12595
20.3k
                        return SAMEAS_PUSHCROP_BUTNOPUSH;
12596
1.03k
                    else
12597
1.03k
                        return PUSHCROP; /* Push cropping. */
12598
21.3k
                }
12599
36.6k
            }
12600
33.2k
        case PDF14_END_TRANS_GROUP: return POPCROP; /* Pop cropping. */
12601
2.25k
        case PDF14_END_TRANS_TEXT_GROUP: return POPCROP; /* Pop cropping. */
12602
16.3k
        case PDF14_END_TRANS_MASK: return POPCROP;   /* Pop the cropping */
12603
0
        case PDF14_PUSH_TRANS_STATE: return CURRBANDS;
12604
15.9k
        case PDF14_POP_TRANS_STATE: return CURRBANDS;
12605
97.4k
        case PDF14_SET_BLEND_PARAMS: return ALLBANDS;
12606
0
        case PDF14_PUSH_SMASK_COLOR: return POPCROP; /* Pop cropping. */
12607
0
        case PDF14_POP_SMASK_COLOR: return POPCROP;   /* Pop the cropping */
12608
0
        case PDF14_BEGIN_TRANS_TEXT_GROUP: return ALLBANDS; /* should never occur */
12609
255k
    }
12610
0
    return ALLBANDS;
12611
255k
}
12612
12613
/*
12614
 * This routine will check to see if the color component name matches those
12615
 * that are available amoung the current device's color components.  If the
12616
 * color name is known to the output device then we add it to the list of
12617
 * colorants for the PDF 1.4 transparency compositor.
12618
 *
12619
 * Notes:  There are currently three different versions of The PDF 1.4
12620
 * transparency compositor device.  The choice of which one is being used
12621
 * depends upon the process color model of the output device.  This procedure
12622
 * is only used if the output (target) device uses a CMYK, or RGB or Gray
12623
 * plus spot color process color model.
12624
 *
12625
 * Parameters:
12626
 *   dev - pointer to device data structure.
12627
 *   pname - pointer to name (zero termination not required)
12628
 *   nlength - length of the name
12629
 *   number of process colorants (either 1, 3, or 4)
12630
 *
12631
 * This routine returns a positive value (0 to n) which is the device colorant
12632
 * number if the name is found.  It returns GX_DEVICE_COLOR_MAX_COMPONENTS if
12633
 * the colorant is not being used due to a SeparationOrder device parameter.
12634
 * It returns a negative value if not found.
12635
 */
12636
static int
12637
pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname,
12638
    int name_size, int component_type, int num_process_colors, int cmyk)
12639
7.71k
{
12640
7.71k
    pdf14_device *pdev = (pdf14_device *)dev;
12641
7.71k
    gx_device *tdev = pdev->target;
12642
7.71k
    gs_devn_params *pdevn_params = &pdev->devn_params;
12643
7.71k
    gs_separations *pseparations;
12644
7.71k
    int comp_index;
12645
7.71k
    dev_proc_get_color_comp_index(*target_get_color_comp_index);
12646
7.71k
    int offset;
12647
12648
7.71k
    while (tdev->child) {
12649
0
        tdev = tdev->child;
12650
0
    }
12651
    /* If something has gone wrong and this is no longer the pdf14 compositor, */
12652
    /* get the devn_params from the target to avoid accessing using the wrong  */
12653
    /* pointer. Bug 696372.                                                    */
12654
7.71k
    if (tdev == (gx_device *)pdev)
12655
0
        pdevn_params = dev_proc(pdev, ret_devn_params)(dev);
12656
7.71k
    offset = pdevn_params->num_std_colorant_names - num_process_colors;
12657
7.71k
    pseparations = &pdevn_params->separations;
12658
    /* If num_process_colors is 3 or 1 (RGB or Gray) then we are in a situation
12659
     * where we are in a blend color space that is RGB or Gray based and we
12660
     * have a spot colorant.  If the spot colorant name is Cyan, Magenta
12661
     * Yellow or Black, then we should use the alternate tint transform */
12662
7.71k
    if (num_process_colors < 4) {
12663
667
        int k;
12664
3.33k
        for (k = 0; k < pdevn_params->num_std_colorant_names; k++) {
12665
2.66k
            if (strncmp(pname, pdevn_params->std_colorant_names[k], name_size) == 0)
12666
0
                return -1;
12667
2.66k
        }
12668
667
    }
12669
12670
7.71k
    target_get_color_comp_index = dev_proc(tdev, get_color_comp_index);
12671
12672
    /* The pdf14_clist_composite may have set the color procs.
12673
       We need the real target procs. */
12674
7.71k
    if ((target_get_color_comp_index == pdf14_cmykspot_get_color_comp_index ||
12675
0
         target_get_color_comp_index == pdf14_rgbspot_get_color_comp_index))
12676
7.71k
        target_get_color_comp_index =
12677
7.71k
            ((pdf14_clist_device *)pdev)->saved_target_get_color_comp_index;
12678
    /*
12679
    * If this is not a separation name then simply forward it to the target
12680
    * device or return -1 if we are doing overprint simulation.
12681
    * The halftone setup expects this.
12682
    */
12683
7.71k
    if (!pdev->overprint_sim && (component_type == NO_COMP_NAME_TYPE_HT ||
12684
7.71k
        component_type == NO_COMP_NAME_TYPE_OP)) {
12685
6.65k
            if (target_get_color_comp_index != NULL)
12686
6.65k
                return  (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12687
0
            else
12688
0
                return -1;
12689
6.65k
    }
12690
1.06k
    if (pdev->overprint_sim && component_type == NO_COMP_NAME_TYPE_HT) {
12691
0
        return -1;
12692
0
    }
12693
12694
    /*
12695
    * Check if the component is in either the process color model list
12696
    * or in the SeparationNames list.
12697
    */
12698
1.06k
    comp_index = check_pcm_and_separation_names(dev, pdevn_params, pname,
12699
1.06k
        name_size, component_type);
12700
12701
    /* Additive devices should NOT have C/M/Y/K Colorants added to them.
12702
     * This is a decision we take here to avoid problems with PDFI not
12703
     * counting such colorants as spots. */
12704
1.06k
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
12705
38
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12706
0
            return -1;
12707
38
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12708
0
            return -1;
12709
38
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12710
0
            return -1;
12711
38
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12712
0
            return -1;
12713
38
    }
12714
    /* A psdrgb device, with simulate overprint will have become a cmyk
12715
     * device. As such, we don't want to add Black/Cyan/Magenta/Yellow to that
12716
     * either, but we need to return real numbers for them as the underlying
12717
     * routine won't know about these. */
12718
1.06k
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && cmyk) {
12719
2
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12720
0
            return 3;
12721
2
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12722
0
            return 0;
12723
2
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12724
0
            return 1;
12725
2
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12726
0
            return 2;
12727
2
    }
12728
12729
    /*
12730
    * Return the colorant number if we know this name.  Note adjustment for
12731
    * compensating of blend color space.
12732
    */
12733
1.06k
    if (comp_index >= 0)
12734
1.02k
        return comp_index - offset;
12735
12736
    /* Only worry about the target if we are not doing an overprint simulation */
12737
40
    if (!pdev->overprint_sim) {
12738
        /*
12739
        * If we do not know this color, check if the output (target) device does.
12740
        * Note that if the target device has ENABLE_AUTO_SPOT_COLORS this will add
12741
        * the colorant so we will only get < 0 returned when we hit the max. for
12742
        * the target device.
12743
        */
12744
40
        if (target_get_color_comp_index != NULL)
12745
40
            comp_index = (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12746
0
        else
12747
0
            return -1;
12748
        /*
12749
        * Ignore color if unknown to the output device or if color is not being
12750
        * imaged due to the SeparationOrder device parameter.
12751
        */
12752
40
        if (comp_index < 0 || comp_index == GX_DEVICE_COLOR_MAX_COMPONENTS)
12753
0
            return comp_index - offset;
12754
40
    }
12755
12756
    /*
12757
    * This is a new colorant.  Add it to our list of colorants.
12758
    * The limit accounts for the number of process colors (at least 4).
12759
    */
12760
40
    if ((pseparations->num_separations + 1) <
12761
40
            (GX_DEVICE_COLOR_MAX_COMPONENTS - max(num_process_colors, 4))) {
12762
40
        int sep_num = pseparations->num_separations++;
12763
40
        int color_component_number;
12764
40
        byte * sep_name;
12765
12766
40
        sep_name = gs_alloc_bytes(dev->memory->stable_memory,
12767
40
            name_size, "pdf14_spot_get_color_comp_index");
12768
40
        if (sep_name == NULL) {
12769
0
            pseparations->num_separations--;  /* we didn't add it */
12770
0
            return -1;
12771
0
        }
12772
40
        memcpy(sep_name, pname, name_size);
12773
40
        pseparations->names[sep_num].size = name_size;
12774
40
        pseparations->names[sep_num].data = sep_name;
12775
40
        color_component_number = sep_num + num_process_colors;
12776
40
        if (color_component_number >= dev->color_info.max_components)
12777
0
            color_component_number = GX_DEVICE_COLOR_MAX_COMPONENTS;
12778
40
        else
12779
40
            pdevn_params->separation_order_map[color_component_number] =
12780
40
            color_component_number;
12781
12782
        /* Indicate that we need to find equivalent CMYK color. */
12783
40
        pdev->op_pequiv_cmyk_colors.color[sep_num].color_info_valid = false;
12784
40
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
12785
12786
        /* If we're doing an overprint simulation, then the target device
12787
         * (for instance) might not know about this colorant. This is annoying
12788
         * as the target can't then output the correct names. Call the target
12789
         * get_color_comp_index routine and ignore the result to give it a
12790
         * chance to stash it. */
12791
40
        if (pdev->overprint_sim && target_get_color_comp_index != NULL)
12792
0
            (void)(*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12793
12794
40
        return color_component_number;
12795
40
    }
12796
12797
0
    return GX_DEVICE_COLOR_MAX_COMPONENTS;
12798
40
}
12799
12800
12801
/* CMYK process + spots */
12802
static int
12803
pdf14_cmykspot_get_color_comp_index(gx_device * dev, const char * pname,
12804
    int name_size, int component_type)
12805
7.04k
{
12806
7.04k
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 4, 1);
12807
7.04k
}
12808
12809
/* RGB process + spots */
12810
static int
12811
pdf14_rgbspot_get_color_comp_index(gx_device * dev, const char * pname,
12812
    int name_size, int component_type)
12813
667
{
12814
667
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 3, 0);
12815
667
}
12816
12817
/* Gray process + spots */
12818
static int
12819
pdf14_grayspot_get_color_comp_index(gx_device * dev, const char * pname,
12820
    int name_size, int component_type)
12821
0
{
12822
0
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 1, 0);
12823
0
}
12824
12825
/* These functions keep track of when we are dealing with soft masks.
12826
   In such a case, we set the default color profiles to ones that ensure
12827
   proper soft mask rendering. */
12828
static int
12829
pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev)
12830
20.1k
{
12831
20.1k
    pdf14_device * pdev = (pdf14_device *) dev;
12832
20.1k
    pdf14_smaskcolor_t *result;
12833
20.1k
    gsicc_smask_t *smask_profiles = pgs->icc_manager->smask_profiles;
12834
20.1k
    int k;
12835
12836
    /* See if we have profiles already in place.   Note we also have to
12837
       worry about a corner case where this device does not have a
12838
       smaskcolor stucture to store the profiles AND the profiles were
12839
       already swapped out in the icc_manager.  This can occur when we
12840
       pushed a transparency mask and then inside the mask we have a pattern
12841
       which also has a transparency mask.   The state of the icc_manager
12842
       is that it already has done the swap and there is no need to fool
12843
       with any of this while dealing with the soft mask within the pattern */
12844
20.1k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12845
20.1k
        pgs->icc_manager->smask_profiles->swapped) {
12846
0
            return 0;
12847
0
    }
12848
20.1k
    if (pdev->smaskcolor != NULL) {
12849
15
        pdev->smaskcolor->ref_count++;
12850
15
        if_debug1m(gs_debug_flag_icc, dev->memory,
12851
15
                   "[icc] Increment smask color now %d\n",
12852
15
                   pdev->smaskcolor->ref_count);
12853
20.1k
    } else {
12854
        /* Allocate and swap out the current profiles.  The softmask
12855
           profiles should already be in place */
12856
20.1k
        result = gs_alloc_struct(pdev->memory->stable_memory, pdf14_smaskcolor_t,
12857
20.1k
                                &st_pdf14_smaskcolor,
12858
20.1k
                                "pdf14_increment_smask_color");
12859
20.1k
        if (result == NULL)
12860
0
            return gs_error_VMerror;
12861
12862
20.1k
        result->profiles = gsicc_new_iccsmask(pdev->memory->stable_memory);
12863
20.1k
        if (result->profiles == NULL)
12864
0
            return gs_error_VMerror;
12865
12866
20.1k
        pdev->smaskcolor = result;
12867
12868
20.1k
        result->profiles->smask_gray = pgs->icc_manager->default_gray;
12869
20.1k
        result->profiles->smask_rgb = pgs->icc_manager->default_rgb;
12870
20.1k
        result->profiles->smask_cmyk = pgs->icc_manager->default_cmyk;
12871
20.1k
        pgs->icc_manager->default_gray = smask_profiles->smask_gray;
12872
20.1k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "pdf14_increment_smask_color");
12873
20.1k
        pgs->icc_manager->default_rgb = smask_profiles->smask_rgb;
12874
20.1k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "pdf14_increment_smask_color");
12875
20.1k
        pgs->icc_manager->default_cmyk = smask_profiles->smask_cmyk;
12876
20.1k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_increment_smask_color");
12877
20.1k
        pgs->icc_manager->smask_profiles->swapped = true;
12878
20.1k
        if_debug0m(gs_debug_flag_icc, pgs->memory,
12879
20.1k
                   "[icc] Initial creation of smask color. Ref count 1\n");
12880
20.1k
        pdev->smaskcolor->ref_count = 1;
12881
        /* We also need to update the profile that is currently in the
12882
           color spaces of the graphic state.  Otherwise this can be
12883
           referenced, which will result in a mismatch.  What we want to do
12884
           is see if it was the original default and only swap in that case. */
12885
60.3k
        for (k = 0; k < 2; k++) {
12886
40.2k
            gs_color_space *pcs     = pgs->color[k].color_space;
12887
40.2k
            cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12888
40.2k
            if (profile != NULL) {
12889
38.8k
                switch(profile->data_cs) {
12890
22.2k
                    case gsGRAY:
12891
22.2k
                        if (profile->hashcode ==
12892
22.2k
                            result->profiles->smask_gray->hashcode) {
12893
20.6k
                                profile = pgs->icc_manager->default_gray;
12894
20.6k
                        }
12895
22.2k
                        break;
12896
16.3k
                    case gsRGB:
12897
16.3k
                        if (profile->hashcode ==
12898
16.3k
                            result->profiles->smask_rgb->hashcode) {
12899
9.77k
                                profile = pgs->icc_manager->default_rgb;
12900
9.77k
                        }
12901
16.3k
                        break;
12902
218
                    case gsCMYK:
12903
218
                        if (profile->hashcode ==
12904
218
                            result->profiles->smask_cmyk->hashcode) {
12905
218
                                profile = pgs->icc_manager->default_cmyk;
12906
218
                        }
12907
218
                        break;
12908
0
                    default:
12909
12910
0
                        break;
12911
38.8k
                }
12912
38.8k
                if (pcs->cmm_icc_profile_data != profile) {
12913
30.6k
                    gsicc_adjust_profile_rc(profile, 1, "pdf14_increment_smask_color");
12914
30.6k
                    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_increment_smask_color");
12915
30.6k
                    pcs->cmm_icc_profile_data = profile;
12916
30.6k
                }
12917
38.8k
            }
12918
40.2k
        }
12919
20.1k
    }
12920
20.1k
    return 0;
12921
20.1k
}
12922
12923
static int
12924
pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev)
12925
29.0k
{
12926
29.0k
    pdf14_device * pdev = (pdf14_device *) dev;
12927
29.0k
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
12928
29.0k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
12929
29.0k
    int k;
12930
12931
    /* See comment in pdf14_increment_smask_color to understand this one */
12932
29.0k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12933
3.78k
        pgs->icc_manager->smask_profiles->swapped) {
12934
0
            return 0;
12935
0
    }
12936
29.0k
    if (smaskcolor != NULL) {
12937
20.1k
        smaskcolor->ref_count--;
12938
20.1k
        if_debug1m(gs_debug_flag_icc, pgs->memory,
12939
20.1k
                   "[icc] Decrement smask color.  Now %d\n",
12940
20.1k
                   smaskcolor->ref_count);
12941
20.1k
        if (smaskcolor->ref_count == 0) {
12942
20.1k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reset smask color.\n");
12943
            /* Lets return the profiles and clean up */
12944
            /* First see if we need to "reset" the profiles that are in
12945
               the graphic state */
12946
20.1k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reseting graphic state color spaces\n");
12947
60.3k
            for (k = 0; k < 2; k++) {
12948
40.2k
                gs_color_space *pcs = pgs->color[k].color_space;
12949
40.2k
                cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12950
40.2k
                if (profile != NULL) {
12951
38.8k
                    switch(profile->data_cs) {
12952
22.2k
                        case gsGRAY:
12953
22.2k
                            if (profile->hashcode ==
12954
22.2k
                                pgs->icc_manager->default_gray->hashcode) {
12955
20.6k
                                    profile =
12956
20.6k
                                        smaskcolor->profiles->smask_gray;
12957
20.6k
                            }
12958
22.2k
                            break;
12959
16.3k
                        case gsRGB:
12960
16.3k
                            if (profile->hashcode ==
12961
16.3k
                                pgs->icc_manager->default_rgb->hashcode) {
12962
9.77k
                                    profile =
12963
9.77k
                                        smaskcolor->profiles->smask_rgb;
12964
9.77k
                            }
12965
16.3k
                            break;
12966
218
                        case gsCMYK:
12967
218
                            if (profile->hashcode ==
12968
218
                                pgs->icc_manager->default_cmyk->hashcode) {
12969
218
                                    profile =
12970
218
                                        smaskcolor->profiles->smask_cmyk;
12971
218
                            }
12972
218
                            break;
12973
0
                        default:
12974
12975
0
                            break;
12976
38.8k
                    }
12977
38.8k
                    if (pcs->cmm_icc_profile_data != profile) {
12978
30.6k
                        gsicc_adjust_profile_rc(profile, 1, "pdf14_decrement_smask_color");
12979
30.6k
                        gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_decrement_smask_color");
12980
30.6k
                        pcs->cmm_icc_profile_data = profile;
12981
30.6k
                    }
12982
38.8k
                }
12983
40.2k
            }
12984
12985
20.1k
            gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "pdf14_decrement_smask_color");
12986
20.1k
            icc_manager->default_gray = smaskcolor->profiles->smask_gray;
12987
20.1k
            gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "pdf14_decrement_smask_color");
12988
20.1k
            icc_manager->default_rgb = smaskcolor->profiles->smask_rgb;
12989
20.1k
            gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "pdf14_decrement_smask_color");
12990
20.1k
            icc_manager->default_cmyk = smaskcolor->profiles->smask_cmyk;
12991
20.1k
            icc_manager->smask_profiles->swapped = false;
12992
            /* We didn't increment the reference count when we assigned these
12993
             * so NULL them to avoid decrementing when smaskcolor is freed
12994
             */
12995
20.1k
            smaskcolor->profiles->smask_gray =
12996
20.1k
              smaskcolor->profiles->smask_rgb =
12997
20.1k
              smaskcolor->profiles->smask_cmyk = NULL;
12998
12999
20.1k
            pdf14_free_smask_color(pdev);
13000
20.1k
        }
13001
20.1k
    }
13002
29.0k
    return 0;
13003
29.0k
}
13004
13005
static void
13006
pdf14_free_smask_color(pdf14_device * pdev)
13007
20.1k
{
13008
20.1k
    if (pdev->smaskcolor != NULL) {
13009
20.1k
        if ( pdev->smaskcolor->profiles != NULL) {
13010
            /* Do not decrement the profiles - the references were moved
13011
               here and moved back again, so the ref counts don't change
13012
             */
13013
20.1k
            gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor->profiles,
13014
20.1k
                        "pdf14_free_smask_color");
13015
20.1k
        }
13016
20.1k
        gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor, "pdf14_free_smask_color");
13017
20.1k
        pdev->smaskcolor = NULL;
13018
20.1k
    }
13019
20.1k
}
13020
13021
static void
13022
pdf14_device_finalize(const gs_memory_t *cmem, void *vptr)
13023
967k
{
13024
967k
    gx_device * const dev = (gx_device *)vptr;
13025
967k
    pdf14_device * pdev = (pdf14_device *)dev;
13026
967k
    int k;
13027
13028
967k
    pdf14_cleanup_group_color_profiles (pdev);
13029
13030
967k
    if (pdev->ctx) {
13031
31
        pdf14_ctx_free(pdev->ctx);
13032
31
        pdev->ctx = NULL;
13033
31
    }
13034
13035
967k
    while (pdev->color_model_stack) {
13036
28
        pdf14_pop_group_color(dev, NULL);
13037
28
    }
13038
13039
967k
    for (k = 0; k < pdev->devn_params.separations.num_separations; k++) {
13040
40
        if (pdev->devn_params.separations.names[k].data) {
13041
40
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.separations.names[k].data, "pdf14_device_finalize");
13042
40
            pdev->devn_params.separations.names[k].data = NULL;
13043
40
        }
13044
40
    }
13045
13046
967k
    for (k = 0; k < pdev->devn_params.pdf14_separations.num_separations; k++) {
13047
0
        if (pdev->devn_params.pdf14_separations.names[k].data) {
13048
0
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.pdf14_separations.names[k].data, "pdf14_device_finalize");
13049
0
            pdev->devn_params.pdf14_separations.names[k].data = NULL;
13050
0
        }
13051
0
    }
13052
13053
967k
    gx_device_finalize(cmem, vptr);
13054
967k
}
13055
13056
#if DUMP_MASK_STACK
13057
13058
static void
13059
dump_mask_stack(pdf14_mask_t *mask_stack)
13060
{
13061
    pdf14_mask_t *curr_mask = mask_stack;
13062
    int level = 0;
13063
13064
    while (curr_mask != NULL) {
13065
        if_debug1m('v', curr_mask->memory, "[v]mask_level, %d\n", level);
13066
        if_debug1m('v', curr_mask->memory, "[v]mask_buf, %p\n", curr_mask->rc_mask->mask_buf);
13067
        if_debug1m('v', curr_mask->memory, "[v]rc_count, %ld\n", curr_mask->rc_mask->rc.ref_count);
13068
        level++;
13069
        curr_mask = curr_mask->previous;
13070
    }
13071
}
13072
13073
/* A function to display the current state of the mask stack */
13074
static void
13075
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13076
{
13077
    if_debug1m('v', ctx->memory, "[v]ctx_maskstack, %p\n", ctx->mask_stack);
13078
    if (ctx->mask_stack != NULL) {
13079
        dump_mask_stack(ctx->mask_stack);
13080
    }
13081
    if_debug1m('v', ctx->memory, "[v]ctx_stack, %p\n", ctx->stack);
13082
    if (ctx->stack != NULL) {
13083
        if_debug1m('v', ctx->memory, "[v]ctx_stack_maskstack, %p\n", ctx->stack->mask_stack);
13084
        if (ctx->stack->mask_stack != NULL) {
13085
            dump_mask_stack(ctx->stack->mask_stack);
13086
        }
13087
    }
13088
}
13089
13090
#else
13091
13092
#ifdef DEBUG
13093
static void
13094
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13095
{
13096
    return;
13097
}
13098
#endif
13099
13100
#endif /* DUMP_MASK_STACK */