Coverage Report

Created: 2022-04-16 11:23

/src/ghostpdl/base/gdevp14.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2022 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.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14
*/
15
16
/* Compositing devices for implementing PDF 1.4 imaging model */
17
18
#include "assert_.h"
19
#include "math_.h"
20
#include "memory_.h"
21
#include "gx.h"
22
#include "gserrors.h"
23
#include "gscdefs.h"
24
#include "gxdevice.h"
25
#include "gsdevice.h"
26
#include "gsstruct.h"
27
#include "gxgstate.h"
28
#include "gxdcolor.h"
29
#include "gxiparam.h"
30
#include "gstparam.h"
31
#include "gxblend.h"
32
#include "gxtext.h"
33
#include "gsimage.h"
34
#include "gsrect.h"
35
#include "gscoord.h"
36
#include "gzstate.h"
37
#include "gdevdevn.h"
38
#include "gdevmem.h"
39
#include "gdevp14.h"
40
#include "gdevprn.h"    /* for prn_device structures */
41
#include "gdevppla.h"   /* for gdev_prn_open_planar */
42
#include "gdevdevnprn.h"
43
#include "gscdevn.h"
44
#include "gsovrc.h"
45
#include "gxcmap.h"
46
#include "gscolor1.h"
47
#include "gstrans.h"
48
#include "gsutil.h"
49
#include "gxcldev.h"
50
#include "gxclpath.h"
51
#include "gxdcconv.h"
52
#include "gsptype2.h"
53
#include "gxpcolor.h"
54
#include "gsptype1.h"
55
#include "gzcpath.h"
56
#include "gxpaint.h"
57
#include "gsicc_manage.h"
58
#include "gsicc_cache.h"
59
#include "gxclist.h"
60
#include "gxiclass.h"
61
#include "gximage.h"
62
#include "gsmatrix.h"
63
#include "gxdevsop.h"
64
#include "gsicc.h"
65
#ifdef WITH_CAL
66
#include "cal.h"
67
#define CAL_SLOP 16
68
#else
69
#define CAL_SLOP 0
70
#endif
71
#include "assert_.h"
72
#include "gxgetbit.h"
73
74
#if RAW_DUMP
75
unsigned int global_index = 0;
76
unsigned int clist_band_count = 0;
77
#endif
78
79
#define DUMP_MASK_STACK 0
80
81
/* Static prototypes */
82
/* Used for filling rects when we are doing a fill with a pattern that
83
   has transparency */
84
static int pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
85
                                   gx_path * ppath, const gx_fill_params * params,
86
                                   const gx_device_color * pdevc, const gx_clip_path * pcpath);
87
static pdf14_mask_t *pdf14_mask_element_new(gs_memory_t *memory);
88
static void pdf14_free_smask_color(pdf14_device * pdev);
89
static int compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
90
                                         const gs_rect *pbbox, gs_gstate *pgs);
91
static int pdf14_clist_update_params(pdf14_clist_device * pdev,
92
                                     const gs_gstate * pgs,
93
                                     bool crop_blend_params,
94
                                     gs_pdf14trans_params_t *group_params);
95
static int pdf14_mark_fill_rectangle_ko_simple(gx_device *  dev, int x, int y,
96
                                               int w, int h, gx_color_index color,
97
                                               const gx_device_color *pdc,
98
                                               bool devn);
99
static int pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
100
                                  int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
101
                                  gx_color_index color, const gx_device_color *pdc,
102
                                  int depth, bool devn);
103
104
/* Functions for dealing with soft mask color */
105
static int pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev);
106
static int pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev);
107
108
/*
109
 * We chose the blending color space based upon the process color model of the
110
 * output device.  For gray, RGB, CMYK, or CMYK+spot devices, the choice is
111
 * usually simple.  For other devices or if the user is doing custom color
112
 * processing then the user may want to control this choice.
113
 */
114
#define AUTO_USE_CUSTOM_BLENDING 0
115
#define ALWAYS_USE_CUSTOM_BLENDING 1
116
#define DO_NOT_USE_CUSTOM_BLENDING 2
117
118
#define CUSTOM_BLENDING_MODE AUTO_USE_CUSTOM_BLENDING
119
120
# define INCR(v) DO_NOTHING
121
122
/* Forward prototypes */
123
void pdf14_cmyk_cs_to_cmyk_cm(const gx_device *, frac, frac, frac, frac, frac *);
124
static int gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
125
                                gx_device ** pdev, gx_device * target,
126
                                const gs_pdf14trans_t * pdf14pct);
127
static int gs_pdf14_clist_device_push(gs_memory_t * mem, gs_gstate * pgs,
128
                                      gx_device ** pdev, gx_device * target,
129
                                      const gs_pdf14trans_t * pdf14pct);
130
static int pdf14_tile_pattern_fill(gx_device * pdev,
131
                const gs_gstate * pgs, gx_path * ppath,
132
                const gx_fill_params * params,
133
                const gx_device_color * pdevc, const gx_clip_path * pcpath);
134
static pdf14_mask_t * pdf14_mask_element_new(gs_memory_t * memory);
135
#ifdef DEBUG
136
static void pdf14_debug_mask_stack_state(pdf14_ctx *ctx);
137
#endif
138
139
/* Buffer stack data structure */
140
gs_private_st_ptrs7(st_pdf14_buf, pdf14_buf, "pdf14_buf",
141
                    pdf14_buf_enum_ptrs, pdf14_buf_reloc_ptrs,
142
                    saved, data, backdrop, transfer_fn, mask_stack,
143
                    matte, group_color_info);
144
145
gs_private_st_ptrs3(st_pdf14_ctx, pdf14_ctx, "pdf14_ctx",
146
                    pdf14_ctx_enum_ptrs, pdf14_ctx_reloc_ptrs,
147
                    stack, mask_stack, base_color);
148
149
gs_private_st_ptrs1(st_pdf14_clr, pdf14_group_color_t, "pdf14_clr",
150
                    pdf14_clr_enum_ptrs, pdf14_clr_reloc_ptrs, previous);
151
152
gs_private_st_ptrs2(st_pdf14_mask, pdf14_mask_t, "pdf_mask",
153
                    pdf14_mask_enum_ptrs, pdf14_mask_reloc_ptrs,
154
                    rc_mask, previous);
155
156
gs_private_st_ptrs1(st_pdf14_rcmask, pdf14_rcmask_t, "pdf_rcmask",
157
                    pdf14_rcmask_enum_ptrs, pdf14_rcmask_reloc_ptrs,
158
                    mask_buf);
159
160
gs_private_st_ptrs1(st_pdf14_smaskcolor, pdf14_smaskcolor_t, "pdf14_smaskcolor",
161
                    pdf14_smaskcolor_enum_ptrs, pdf14_smaskcolor_reloc_ptrs,
162
                    profiles);
163
164
/* ------ The device descriptors ------ */
165
166
/*
167
 * Default X and Y resolution.
168
 */
169
#define X_DPI 72
170
#define Y_DPI 72
171
172
static int pdf14_initialize_device(gx_device *dev);
173
174
static  int pdf14_open(gx_device * pdev);
175
static  dev_proc_close_device(pdf14_close);
176
static  int pdf14_output_page(gx_device * pdev, int num_copies, int flush);
177
static  dev_proc_put_params(pdf14_put_params);
178
static  dev_proc_get_color_comp_index(pdf14_cmykspot_get_color_comp_index);
179
static  dev_proc_get_color_comp_index(pdf14_rgbspot_get_color_comp_index);
180
static  dev_proc_get_color_comp_index(pdf14_grayspot_get_color_comp_index);
181
static  dev_proc_get_color_mapping_procs(pdf14_cmykspot_get_color_mapping_procs);
182
static  dev_proc_get_color_mapping_procs(pdf14_rgbspot_get_color_mapping_procs);
183
static  dev_proc_get_color_mapping_procs(pdf14_grayspot_get_color_mapping_procs);
184
dev_proc_encode_color(pdf14_encode_color);
185
dev_proc_encode_color(pdf14_encode_color_tag);
186
dev_proc_decode_color(pdf14_decode_color);
187
dev_proc_encode_color(pdf14_encode_color16);
188
dev_proc_encode_color(pdf14_encode_color16_tag);
189
dev_proc_decode_color(pdf14_decode_color16);
190
static  dev_proc_fill_rectangle(pdf14_fill_rectangle);
191
static  dev_proc_fill_rectangle_hl_color(pdf14_fill_rectangle_hl_color);
192
static  dev_proc_fill_path(pdf14_fill_path);
193
static  dev_proc_fill_stroke_path(pdf14_fill_stroke_path);
194
static  dev_proc_copy_mono(pdf14_copy_mono);
195
static  dev_proc_fill_mask(pdf14_fill_mask);
196
static  dev_proc_stroke_path(pdf14_stroke_path);
197
static  dev_proc_begin_typed_image(pdf14_begin_typed_image);
198
static  dev_proc_text_begin(pdf14_text_begin);
199
static  dev_proc_composite(pdf14_composite);
200
static  dev_proc_composite(pdf14_forward_composite);
201
static  dev_proc_begin_transparency_group(pdf14_begin_transparency_group);
202
static  dev_proc_end_transparency_group(pdf14_end_transparency_group);
203
static  dev_proc_begin_transparency_mask(pdf14_begin_transparency_mask);
204
static  dev_proc_end_transparency_mask(pdf14_end_transparency_mask);
205
static  dev_proc_dev_spec_op(pdf14_dev_spec_op);
206
static  dev_proc_push_transparency_state(pdf14_push_transparency_state);
207
static  dev_proc_pop_transparency_state(pdf14_pop_transparency_state);
208
static  dev_proc_ret_devn_params(pdf14_ret_devn_params);
209
static  dev_proc_update_spot_equivalent_colors(pdf14_update_spot_equivalent_colors);
210
static  dev_proc_copy_alpha(pdf14_copy_alpha);
211
static  dev_proc_copy_planes(pdf14_copy_planes);
212
static  dev_proc_copy_alpha_hl_color(pdf14_copy_alpha_hl_color);
213
static  dev_proc_discard_transparency_layer(pdf14_discard_trans_layer);
214
static  dev_proc_strip_tile_rect_devn(pdf14_strip_tile_rect_devn);
215
static  const gx_color_map_procs *
216
    pdf14_get_cmap_procs(const gs_gstate *, const gx_device *);
217
218
#define XSIZE (int)(8.5 * X_DPI)  /* 8.5 x 11 inch page, by default */
219
#define YSIZE (int)(11 * Y_DPI)
220
221
/* 24-bit color. */
222
223
static void
224
pdf14_procs_initialize(gx_device *dev,
225
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
226
                       dev_proc_get_color_comp_index(get_color_comp_index),
227
                       dev_proc_encode_color(encode_color),
228
                       dev_proc_decode_color(decode_color))
229
278k
{
230
278k
    set_dev_proc(dev, initialize_device, pdf14_initialize_device);
231
278k
    set_dev_proc(dev, open_device, pdf14_open);
232
278k
    set_dev_proc(dev, output_page, pdf14_output_page);
233
278k
    set_dev_proc(dev, close_device, pdf14_close);
234
278k
    set_dev_proc(dev, map_rgb_color, encode_color);
235
278k
    set_dev_proc(dev, map_color_rgb, decode_color);
236
278k
    set_dev_proc(dev, fill_rectangle, pdf14_fill_rectangle);
237
278k
    set_dev_proc(dev, copy_mono, pdf14_copy_mono);
238
278k
    set_dev_proc(dev, get_params, gx_forward_get_params);
239
278k
    set_dev_proc(dev, put_params, pdf14_put_params);
240
278k
    set_dev_proc(dev, copy_alpha, pdf14_copy_alpha);
241
278k
    set_dev_proc(dev, fill_path, pdf14_fill_path);
242
278k
    set_dev_proc(dev, stroke_path, pdf14_stroke_path);
243
278k
    set_dev_proc(dev, fill_mask, pdf14_fill_mask);
244
278k
    set_dev_proc(dev, begin_typed_image, pdf14_begin_typed_image);
245
278k
    set_dev_proc(dev, composite, pdf14_composite);
246
278k
    set_dev_proc(dev, text_begin, pdf14_text_begin);
247
278k
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
248
278k
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
249
278k
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
250
278k
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
251
278k
    set_dev_proc(dev, discard_transparency_layer, pdf14_discard_trans_layer);
252
278k
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
253
278k
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
254
278k
    set_dev_proc(dev, encode_color, encode_color);
255
278k
    set_dev_proc(dev, decode_color, decode_color);
256
278k
    set_dev_proc(dev, fill_rectangle_hl_color, pdf14_fill_rectangle_hl_color);
257
278k
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
258
278k
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
259
278k
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
260
278k
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
261
278k
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
262
278k
    set_dev_proc(dev, copy_planes, pdf14_copy_planes);
263
278k
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
264
278k
    set_dev_proc(dev, strip_tile_rect_devn, pdf14_strip_tile_rect_devn);
265
278k
    set_dev_proc(dev, copy_alpha_hl_color, pdf14_copy_alpha_hl_color);
266
278k
    set_dev_proc(dev, fill_stroke_path, pdf14_fill_stroke_path);
267
278k
}
268
269
static void
270
pdf14_Gray_initialize_device_procs(gx_device *dev)
271
24.2k
{
272
24.2k
    pdf14_procs_initialize(dev,
273
24.2k
                           gx_default_DevGray_get_color_mapping_procs,
274
24.2k
                           gx_default_DevGray_get_color_comp_index,
275
24.2k
                           pdf14_encode_color,
276
24.2k
                           pdf14_decode_color);
277
24.2k
}
278
279
static void
280
pdf14_RGB_initialize_device_procs(gx_device *dev)
281
135k
{
282
135k
    pdf14_procs_initialize(dev,
283
135k
                           gx_default_DevRGB_get_color_mapping_procs,
284
135k
                           gx_default_DevRGB_get_color_comp_index,
285
135k
                           pdf14_encode_color,
286
135k
                           pdf14_decode_color);
287
135k
}
288
289
static void
290
pdf14_CMYK_initialize_device_procs(gx_device *dev)
291
118k
{
292
118k
    pdf14_procs_initialize(dev,
293
118k
                           gx_default_DevCMYK_get_color_mapping_procs,
294
118k
                           gx_default_DevCMYK_get_color_comp_index,
295
118k
                           pdf14_encode_color,
296
118k
                           pdf14_decode_color);
297
118k
}
298
299
static void
300
pdf14_CMYKspot_initialize_device_procs(gx_device *dev)
301
0
{
302
0
    pdf14_procs_initialize(dev,
303
0
                           pdf14_cmykspot_get_color_mapping_procs,
304
0
                           pdf14_cmykspot_get_color_comp_index,
305
0
                           pdf14_encode_color,
306
0
                           pdf14_decode_color);
307
0
}
308
309
static void
310
pdf14_RGBspot_initialize_device_procs(gx_device *dev)
311
0
{
312
0
    pdf14_procs_initialize(dev,
313
0
                           pdf14_rgbspot_get_color_mapping_procs,
314
0
                           pdf14_rgbspot_get_color_comp_index,
315
0
                           pdf14_encode_color,
316
0
                           pdf14_decode_color);
317
0
}
318
319
static void
320
pdf14_Grayspot_initialize_device_procs(gx_device *dev)
321
0
{
322
0
    pdf14_procs_initialize(dev,
323
0
                           pdf14_grayspot_get_color_mapping_procs,
324
0
                           pdf14_grayspot_get_color_comp_index,
325
0
                           pdf14_encode_color,
326
0
                           pdf14_decode_color);
327
0
}
328
329
static void
330
pdf14_custom_initialize_device_procs(gx_device *dev)
331
0
{
332
0
    pdf14_procs_initialize(dev,
333
0
                           gx_forward_get_color_mapping_procs,
334
0
                           gx_forward_get_color_comp_index,
335
0
                           gx_forward_encode_color,
336
0
                           gx_forward_decode_color);
337
0
}
338
339
static struct_proc_finalize(pdf14_device_finalize);
340
341
gs_private_st_composite_use_final(st_pdf14_device, pdf14_device, "pdf14_device",
342
                                  pdf14_device_enum_ptrs, pdf14_device_reloc_ptrs,
343
                          pdf14_device_finalize);
344
345
static int pdf14_put_image(gx_device * dev, gs_gstate * pgs,
346
                                                        gx_device * target);
347
static int pdf14_cmykspot_put_image(gx_device * dev, gs_gstate * pgs,
348
                                                        gx_device * target);
349
static int pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs,
350
                                                        gx_device * target);
351
352
/* Alter pdf14 device color model based upon group or softmask. This occurs
353
   post clist or in immediate rendering case. Data stored with buffer */
354
static pdf14_group_color_t* pdf14_push_color_model(gx_device *dev,
355
                              gs_transparency_color_t group_color, int64_t icc_hashcode,
356
                              cmm_profile_t *iccprofile, bool is_mask);
357
static void pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color);
358
359
/* Alter clist writer device color model based upon group or softmask. Data
360
   stored in the device color model stack */
361
static int pdf14_clist_push_color_model(gx_device* dev, gx_device* cdev, gs_gstate* pgs,
362
    const gs_pdf14trans_t* pdf14pct, gs_memory_t* mem, bool is_mask);
363
static int pdf14_clist_pop_color_model(gx_device* dev, gs_gstate* pgs);
364
365
/* Used for cleaning up the stack if things go wrong */
366
static void pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs);
367
368
static const pdf14_procs_t gray_pdf14_procs = {
369
    pdf14_unpack_additive,
370
    pdf14_put_image,
371
    pdf14_unpack16_additive
372
};
373
374
static const pdf14_procs_t rgb_pdf14_procs = {
375
    pdf14_unpack_additive,
376
    pdf14_put_image,
377
    pdf14_unpack16_additive
378
};
379
380
static const pdf14_procs_t cmyk_pdf14_procs = {
381
    pdf14_unpack_subtractive,
382
    pdf14_put_image,
383
    pdf14_unpack16_subtractive
384
};
385
386
static const pdf14_procs_t cmykspot_pdf14_procs = {
387
    pdf14_unpack_custom,  /* should never be used since we will use devn values */
388
    pdf14_cmykspot_put_image,
389
    pdf14_unpack16_custom /* should never be used since we will use devn values */
390
};
391
392
static const pdf14_procs_t rgbspot_pdf14_procs = {
393
    pdf14_unpack_rgb_mix,
394
    pdf14_cmykspot_put_image,
395
    pdf14_unpack16_rgb_mix
396
};
397
398
static const pdf14_procs_t grayspot_pdf14_procs = {
399
    pdf14_unpack_gray_mix,
400
    pdf14_cmykspot_put_image,
401
    pdf14_unpack16_gray_mix
402
};
403
404
static const pdf14_procs_t custom_pdf14_procs = {
405
    pdf14_unpack_custom,
406
    pdf14_custom_put_image,
407
    pdf14_unpack16_custom
408
};
409
410
static const pdf14_nonseparable_blending_procs_t gray_blending_procs = {
411
    art_blend_luminosity_custom_8,
412
    art_blend_saturation_custom_8,
413
    art_blend_luminosity_custom_16,
414
    art_blend_saturation_custom_16
415
};
416
417
static const pdf14_nonseparable_blending_procs_t rgb_blending_procs = {
418
    art_blend_luminosity_rgb_8,
419
    art_blend_saturation_rgb_8,
420
    art_blend_luminosity_rgb_16,
421
    art_blend_saturation_rgb_16
422
};
423
424
static const pdf14_nonseparable_blending_procs_t cmyk_blending_procs = {
425
    art_blend_luminosity_cmyk_8,
426
    art_blend_saturation_cmyk_8,
427
    art_blend_luminosity_cmyk_16,
428
    art_blend_saturation_cmyk_16
429
};
430
431
static const pdf14_nonseparable_blending_procs_t rgbspot_blending_procs = {
432
    art_blend_luminosity_rgb_8,
433
    art_blend_saturation_rgb_8,
434
    art_blend_luminosity_rgb_16,
435
    art_blend_saturation_rgb_16
436
};
437
438
static const pdf14_nonseparable_blending_procs_t grayspot_blending_procs = {
439
    art_blend_luminosity_custom_8,
440
    art_blend_saturation_custom_8,
441
    art_blend_luminosity_custom_16,
442
    art_blend_saturation_custom_16
443
};
444
445
static const pdf14_nonseparable_blending_procs_t custom_blending_procs = {
446
    art_blend_luminosity_custom_8,
447
    art_blend_saturation_custom_8,
448
    art_blend_luminosity_custom_16,
449
    art_blend_saturation_custom_16
450
};
451
452
const pdf14_device gs_pdf14_Gray_device = {
453
    std_device_std_color_full_body_type(pdf14_device,
454
                                        pdf14_Gray_initialize_device_procs,
455
                                        "pdf14gray",
456
                                        &st_pdf14_device,
457
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 8,
458
                                        0, 0, 0, 0, 0, 0),
459
    { 0 },      /* Procs */
460
    NULL,     /* target */
461
    { 0 },      /* devn_params - not used */
462
    &gray_pdf14_procs,
463
    &gray_blending_procs,
464
    1
465
};
466
467
const pdf14_device gs_pdf14_RGB_device = {
468
    std_device_color_stype_body(pdf14_device,
469
                                pdf14_RGB_initialize_device_procs,
470
                                "pdf14RGB",
471
                                &st_pdf14_device,
472
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
473
    { 0 },      /* Procs */
474
    NULL,     /* target */
475
    { 0 },      /* devn_params - not used */
476
    &rgb_pdf14_procs,
477
    &rgb_blending_procs,
478
    3
479
};
480
481
const pdf14_device gs_pdf14_CMYK_device = {
482
    std_device_std_color_full_body_type(pdf14_device,
483
                                        pdf14_CMYK_initialize_device_procs,
484
                                        "pdf14cmyk",
485
                                        &st_pdf14_device,
486
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
487
                                        0, 0, 0, 0, 0, 0),
488
    { 0 },      /* Procs */
489
    NULL,     /* target */
490
    { 0 },      /* devn_params - not used */
491
    &cmyk_pdf14_procs,
492
    &cmyk_blending_procs,
493
    4
494
};
495
496
const pdf14_device gs_pdf14_CMYKspot_device = {
497
    std_device_part1_(pdf14_device,
498
                      pdf14_CMYKspot_initialize_device_procs,
499
                      "pdf14cmykspot",
500
                      &st_pdf14_device,
501
                      open_init_closed),
502
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
503
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
504
    offset_margin_values(0, 0, 0, 0, 0, 0),
505
    std_device_part3_(),
506
    { 0 },      /* Procs */
507
    NULL,     /* target */
508
    /* DeviceN parameters */
509
    { 8,      /* Not used - Bits per color */
510
      DeviceCMYKComponents, /* Names of color model colorants */
511
      4,      /* Number colorants for CMYK */
512
      0,      /* MaxSeparations has not been specified */
513
      -1,     /* PageSpotColors has not been specified */
514
      {0},      /* SeparationNames */
515
      0,      /* SeparationOrder names */
516
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
517
    },
518
    &cmykspot_pdf14_procs,
519
    &cmyk_blending_procs,
520
    4
521
};
522
523
const pdf14_device gs_pdf14_RGBspot_device = {
524
    std_device_part1_(pdf14_device,
525
                      pdf14_RGBspot_initialize_device_procs,
526
                      "pdf14rgbspot",
527
                      &st_pdf14_device,
528
                      open_init_closed),
529
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
530
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
531
    offset_margin_values(0, 0, 0, 0, 0, 0),
532
    std_device_part3_(),
533
    { 0 },      /* Procs */
534
    NULL,     /* target */
535
                    /* DeviceN parameters */
536
    { 8,      /* Not used - Bits per color */
537
    0,              /* Names of color model colorants */
538
    3,          /* Number colorants for RGB */
539
    0,          /* MaxSeparations has not been specified */
540
    -1,         /* PageSpotColors has not been specified */
541
    { 0 },      /* SeparationNames */
542
    0,          /* SeparationOrder names */
543
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
544
    },
545
    &rgbspot_pdf14_procs,
546
    &rgbspot_blending_procs,
547
    3
548
};
549
550
const pdf14_device gs_pdf14_Grayspot_device = {
551
    std_device_part1_(pdf14_device,
552
                      pdf14_Grayspot_initialize_device_procs,
553
                      "pdf14grayspot",
554
                      &st_pdf14_device,
555
                      open_init_closed),
556
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
557
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
558
    offset_margin_values(0, 0, 0, 0, 0, 0),
559
    std_device_part3_(),
560
    { 0 },      /* Procs */
561
    NULL,     /* target */
562
                    /* DeviceN parameters */
563
    { 8,      /* Not used - Bits per color */
564
    0,              /* Names of color model colorants */
565
    3,          /* Number colorants for RGB */
566
    0,          /* MaxSeparations has not been specified */
567
    -1,         /* PageSpotColors has not been specified */
568
    { 0 },      /* SeparationNames */
569
    0,          /* SeparationOrder names */
570
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
571
    },
572
    &grayspot_pdf14_procs,
573
    &grayspot_blending_procs,
574
    1
575
};
576
577
/*
578
 * The 'custom' PDF 1.4 compositor device is for working with those devices
579
 * which support spot colors but do not have a CMYK process color model.
580
 *
581
 * This causes some problems with the Hue, Saturation, Color, and Luminosity
582
 * blending modes.  These blending modes are 'non separable' and depend upon
583
 * knowing the details of the blending color space.  However we use the
584
 * process color model of the output device for our blending color space.
585
 * With an unknown process color model, we have to fall back to some 'guesses'
586
 * about how to treat these blending modes.
587
 */
588
const pdf14_device gs_pdf14_custom_device = {
589
    std_device_part1_(pdf14_device,
590
                      pdf14_custom_initialize_device_procs,
591
                      "pdf14custom",
592
                      &st_pdf14_device,
593
                      open_init_closed),
594
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
595
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
596
    offset_margin_values(0, 0, 0, 0, 0, 0),
597
    std_device_part3_(),
598
    { 0 },      /* Procs */
599
    NULL,     /* target */
600
    /* DeviceN parameters */
601
    { 8,      /* Not used - Bits per color */
602
      DeviceCMYKComponents, /* Names of color model colorants */
603
      4,      /* Number colorants for CMYK */
604
      0,      /* MaxSeparations has not been specified */
605
      -1,     /* PageSpotColors has not been specified */
606
      {0},      /* SeparationNames */
607
      0,      /* SeparationOrder names */
608
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
609
    },
610
    &custom_pdf14_procs,
611
    &custom_blending_procs,
612
    4
613
};
614
615
/* Devices used for pdf14-accum-* device, one for  each image colorspace, */
616
/* Gray, RGB, CMYK, DeviceN. Before calling gdev_prn_open, the following  */
617
/* are set from the target device: width, height, xdpi, ydpi, MaxBitmap.  */
618
619
static dev_proc_print_page(no_print_page);
620
static  dev_proc_ret_devn_params(pdf14_accum_ret_devn_params);
621
static  dev_proc_get_color_comp_index(pdf14_accum_get_color_comp_index);
622
static  dev_proc_get_color_mapping_procs(pdf14_accum_get_color_mapping_procs);
623
static  dev_proc_update_spot_equivalent_colors(pdf14_accum_update_spot_equivalent_colors);
624
625
static int
626
no_print_page(gx_device_printer *pdev, gp_file *prn_stream)
627
0
{
628
0
    return_error(gs_error_unknownerror);
629
0
}
630
631
struct gx_device_pdf14_accum_s {
632
    gx_devn_prn_device_common;
633
    gx_device *save_p14dev;   /* the non-clist pdf14 deivce saved for after accum */
634
};
635
typedef struct gx_device_pdf14_accum_s gx_device_pdf14_accum;
636
637
int
638
pdf14_accum_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size)
639
0
{
640
0
    gx_device_pdf14_accum *adev = (gx_device_pdf14_accum *)pdev;
641
642
0
    if (dev_spec_op == gxdso_device_child) {
643
0
        gxdso_device_child_request *req = (gxdso_device_child_request *)data;
644
0
        if (size < sizeof(*req))
645
0
            return gs_error_unknownerror;
646
0
        req->target = adev->save_p14dev;
647
0
        req->n = 0;
648
0
        return 0;
649
0
    }
650
651
0
    return gdev_prn_dev_spec_op(pdev, dev_spec_op, data, size);
652
0
}
653
654
gs_private_st_suffix_add1_final(st_gx_devn_accum_device, gx_device_pdf14_accum,
655
        "gx_device_pdf14_accum", pdf14_accum_device_enum_ptrs, pdf14_accum_device_reloc_ptrs,
656
                          gx_devn_prn_device_finalize, st_gx_devn_prn_device, save_p14dev);
657
658
static void
659
pdf14_accum_Gray_initialize_device_procs(gx_device *dev)
660
0
{
661
0
    gdev_prn_initialize_device_procs_gray8(dev);
662
663
0
    set_dev_proc(dev, encode_color, gx_default_8bit_map_gray_color);
664
0
    set_dev_proc(dev, decode_color, gx_default_8bit_map_color_gray);
665
0
}
666
667
const gx_device_pdf14_accum pdf14_accum_Gray = {
668
    prn_device_stype_body(gx_device_pdf14_accum,
669
                          pdf14_accum_Gray_initialize_device_procs,
670
                          "pdf14-accum-Gray",
671
                          &st_gx_devn_accum_device,
672
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
673
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
674
                          1/*ncomp*/, 8/*depth*/, 255/*max_gray*/, 0/*max_color*/,
675
                          256/*dither_grays*/, 0/*dither_colors*/,
676
                          no_print_page),
677
    { 0 },      /* devn_params - not used */
678
    { 0 },      /* equivalent_cmyk_color_params - not used */
679
    0/*save_p14dev*/
680
};
681
682
static void
683
pdf14_accum_RGB_initialize_device_procs(gx_device *dev)
684
0
{
685
0
    gdev_prn_initialize_device_procs_rgb(dev);
686
0
}
687
688
const gx_device_pdf14_accum pdf14_accum_RGB = {
689
    prn_device_stype_body(gx_device_pdf14_accum,
690
                          pdf14_accum_RGB_initialize_device_procs,
691
                          "pdf14-accum-RGB",
692
                          &st_gx_devn_accum_device,
693
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
694
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
695
                          3/*ncomp*/, 24/*depth*/, 0/*max_gray*/, 255/*max_color*/,
696
                          1/*dither_grays*/, 256/*dither_colors*/,
697
                          no_print_page),
698
    { 0 },      /* devn_params - not used */
699
    { 0 },      /* equivalent_cmyk_color_params - not used */
700
    0/*save_p14dev*/
701
};
702
703
static void
704
pdf14_accum_CMYK_initialize_device_procs(gx_device *dev)
705
0
{
706
0
    gdev_prn_initialize_device_procs_cmyk8(dev);
707
708
0
    set_dev_proc(dev, encode_color, cmyk_8bit_map_cmyk_color);
709
0
    set_dev_proc(dev, decode_color, cmyk_8bit_map_color_cmyk);
710
0
}
711
712
const gx_device_pdf14_accum pdf14_accum_CMYK = {
713
    prn_device_stype_body(gx_device_pdf14_accum,
714
                          pdf14_accum_CMYK_initialize_device_procs,
715
                          "pdf14-accum-CMYK",
716
                          &st_gx_devn_accum_device,
717
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
718
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
719
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
720
                          256/*dither_grays*/, 256/*dither_colors*/,
721
                          no_print_page),
722
    { 0 },      /* devn_params - not used */
723
    { 0 },      /* equivalent_cmyk_color_params - not used */
724
    0/*save_p14dev*/
725
};
726
727
static void
728
pdf14_accum_initialize_device_procs_cmykspot(gx_device *dev)
729
0
{
730
0
    pdf14_accum_CMYK_initialize_device_procs(dev);
731
732
0
    set_dev_proc(dev, get_color_mapping_procs, pdf14_accum_get_color_mapping_procs);
733
0
    set_dev_proc(dev, get_color_comp_index, pdf14_accum_get_color_comp_index);
734
0
    set_dev_proc(dev, update_spot_equivalent_colors, pdf14_accum_update_spot_equivalent_colors);
735
0
    set_dev_proc(dev, ret_devn_params, pdf14_accum_ret_devn_params);
736
0
}
737
738
const gx_device_pdf14_accum pdf14_accum_CMYKspot = {
739
    prn_device_stype_body(gx_device_pdf14_accum,
740
                          pdf14_accum_initialize_device_procs_cmykspot,
741
                          "pdf14-accum-CMYKspot",
742
                          &st_gx_devn_accum_device,
743
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
744
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
745
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
746
                          256/*dither_grays*/, 256/*dither_colors*/,
747
                          no_print_page),
748
    /* DeviceN parameters */
749
    { 8,      /* Not used - Bits per color */
750
      DeviceCMYKComponents, /* Names of color model colorants */
751
      4,      /* Number colorants for CMYK */
752
      0,      /* MaxSeparations has not been specified */
753
      -1,     /* PageSpotColors has not been specified */
754
      { 0 },      /* SeparationNames */
755
      0,      /* SeparationOrder names */
756
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
757
    },
758
    { true },     /* equivalent_cmyk_color_params */
759
    0/*save_p14dev*/
760
};
761
762
/* GC procedures */
763
static
764
0
ENUM_PTRS_WITH(pdf14_device_enum_ptrs, pdf14_device *pdev)
765
0
{
766
0
    index -= 5;
767
0
    if (index < pdev->devn_params.separations.num_separations)
768
0
        ENUM_RETURN(pdev->devn_params.separations.names[index].data);
769
0
    index -= pdev->devn_params.separations.num_separations;
770
0
    if (index < pdev->devn_params.pdf14_separations.num_separations)
771
0
        ENUM_RETURN(pdev->devn_params.pdf14_separations.names[index].data);
772
0
    return 0;
773
0
}
774
0
case 0: return ENUM_OBJ(pdev->ctx);
775
0
case 1: return ENUM_OBJ(pdev->color_model_stack);
776
0
case 2: return ENUM_OBJ(pdev->smaskcolor);
777
0
case 3: ENUM_RETURN(gx_device_enum_ptr(pdev->target));
778
0
case 4: ENUM_RETURN(gx_device_enum_ptr(pdev->pclist_device));
779
0
ENUM_PTRS_END
780
781
0
static  RELOC_PTRS_WITH(pdf14_device_reloc_ptrs, pdf14_device *pdev)
782
0
{
783
0
    {
784
0
        int i;
785
786
0
        for (i = 0; i < pdev->devn_params.separations.num_separations; ++i) {
787
0
            RELOC_PTR(pdf14_device, devn_params.separations.names[i].data);
788
0
        }
789
0
    }
790
0
    RELOC_VAR(pdev->ctx);
791
0
    RELOC_VAR(pdev->smaskcolor);
792
0
    RELOC_VAR(pdev->color_model_stack);
793
0
    pdev->target = gx_device_reloc_ptr(pdev->target, gcst);
794
0
    pdev->pclist_device = gx_device_reloc_ptr(pdev->pclist_device, gcst);
795
0
}
796
0
RELOC_PTRS_END
797
798
/* ------ Private definitions ------ */
799
800
static void
801
resolve_matte(pdf14_buf *maskbuf, byte *src_data, int src_planestride, int src_rowstride,
802
              int width, int height, cmm_profile_t *src_profile, int deep)
803
0
{
804
0
    if (deep) {
805
0
        int x, y, i;
806
0
        uint16_t *mask_row_ptr  = (uint16_t *)maskbuf->data;
807
0
        uint16_t *src_row_ptr   = (uint16_t *)src_data;
808
0
        uint16_t *mask_tr_fn    = (uint16_t *)maskbuf->transfer_fn;
809
810
0
        src_planestride >>= 1;
811
0
        src_rowstride >>= 1;
812
813
0
        for (y = 0; y < height; y++) {
814
0
            uint16_t *mask_curr_ptr = mask_row_ptr;
815
0
            uint16_t *src_curr_ptr = src_row_ptr;
816
0
            for (x = 0; x < width; x++) {
817
0
                uint16_t idx = *mask_curr_ptr;
818
0
                byte     top = idx>>8;
819
0
                uint16_t a   = mask_tr_fn[top];
820
0
                int      b   = mask_tr_fn[top+1]-a;
821
0
                uint16_t matte_alpha = a + ((0x80 + b*(idx & 0xff))>>8);
822
823
                /* matte's happen rarely enough that we allow ourselves to
824
                 * resort to 64bit here. */
825
0
                if (matte_alpha != 0 && matte_alpha != 0xffff) {
826
0
                    for (i = 0; i < src_profile->num_comps; i++) {
827
0
                        int val = src_curr_ptr[i * src_planestride] - maskbuf->matte[i];
828
0
                        int temp = (((int64_t)val) * 0xffff / matte_alpha) + maskbuf->matte[i];
829
830
                        /* clip */
831
0
                        if (temp > 0xffff)
832
0
                            src_curr_ptr[i * src_planestride] = 0xffff;
833
0
                        else if (temp < 0)
834
0
                            src_curr_ptr[i * src_planestride] = 0;
835
0
                        else
836
0
                            src_curr_ptr[i * src_planestride] = temp;
837
0
                    }
838
0
                }
839
0
                mask_curr_ptr++;
840
0
                src_curr_ptr++;
841
0
            }
842
0
            src_row_ptr += src_rowstride;
843
0
            mask_row_ptr += (maskbuf->rowstride>>1);
844
0
        }
845
0
    } else {
846
0
        int x, y, i;
847
0
        byte *mask_row_ptr  = maskbuf->data;
848
0
        byte *src_row_ptr   = src_data;
849
0
        byte *mask_tr_fn    = maskbuf->transfer_fn;
850
851
0
        for (y = 0; y < height; y++) {
852
0
            byte *mask_curr_ptr = mask_row_ptr;
853
0
            byte *src_curr_ptr = src_row_ptr;
854
0
            for (x = 0; x < width; x++) {
855
0
                byte matte_alpha = mask_tr_fn[*mask_curr_ptr];
856
0
                if (matte_alpha != 0 && matte_alpha != 0xff) {
857
0
                    for (i = 0; i < src_profile->num_comps; i++) {
858
0
                        byte matte = maskbuf->matte[i]>>8;
859
0
                        int val = src_curr_ptr[i * src_planestride] - matte;
860
0
                        int temp = ((((val * 0xff) << 8) / matte_alpha) >> 8) + matte;
861
862
                        /* clip */
863
0
                        if (temp > 0xff)
864
0
                            src_curr_ptr[i * src_planestride] = 0xff;
865
0
                        else if (temp < 0)
866
0
                            src_curr_ptr[i * src_planestride] = 0;
867
0
                        else
868
0
                            src_curr_ptr[i * src_planestride] = temp;
869
0
                    }
870
0
                }
871
0
                mask_curr_ptr++;
872
0
                src_curr_ptr++;
873
0
            }
874
0
            src_row_ptr += src_rowstride;
875
0
            mask_row_ptr += maskbuf->rowstride;
876
0
        }
877
0
    }
878
0
}
879
880
/* Transform of color data and copy noncolor data.  Used in
881
   group pop and during the pdf14 put image calls when the blend color space
882
   is different than the target device color space.  The function will try do
883
   in-place conversion if possible.  If not, it will do an allocation.  The
884
   put_image call needs to know if an allocation was made so that it can adjust
885
   for the fact that we likely don't have a full page any longer and we don't
886
   need to do the offset to our data in the buffer. Bug 700686: If we are in
887
   a softmask that includes a matte entry, then we need to undo the matte
888
   entry here at this time in the image's native color space not the parent
889
   color space.   The endian_swap term here is only set to true if the data
890
   has been baked as BE during the put_image blending operation and we are
891
   on a LE machine.  */
892
static forceinline pdf14_buf*
893
template_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
894
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
895
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
896
    bool has_matte, bool deep, bool endian_swap)
897
479
{
898
479
    gsicc_rendering_param_t rendering_params;
899
479
    gsicc_link_t *icc_link;
900
479
    gsicc_bufferdesc_t src_buff_desc;
901
479
    gsicc_bufferdesc_t des_buff_desc;
902
479
    int src_planestride = src_buf->planestride;
903
479
    int src_rowstride = src_buf->rowstride;
904
479
    int src_n_planes = src_buf->n_planes;
905
479
    int src_n_chan = src_buf->n_chan;
906
479
    int des_planestride = src_planestride;
907
479
    int des_rowstride = src_rowstride;
908
479
    int des_n_planes = src_n_planes;
909
479
    int des_n_chan = src_n_chan;
910
479
    int diff;
911
479
    int k, j;
912
479
    byte *des_data = NULL;
913
479
    pdf14_buf *output = src_buf;
914
479
    pdf14_mask_t *mask_stack;
915
479
    pdf14_buf *maskbuf;
916
479
    int code;
917
918
479
    *did_alloc = false;
919
920
    /* Same profile */
921
479
    if (gsicc_get_hash(src_profile) == gsicc_get_hash(des_profile))
922
0
        return src_buf;
923
924
    /* Define the rendering intent get the link */
925
479
    rendering_params.black_point_comp = gsBLACKPTCOMP_ON;
926
479
    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
927
479
    rendering_params.override_icc = false;
928
479
    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
929
479
    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;  /* Use relative intent */
930
479
    rendering_params.cmm = gsCMM_DEFAULT;
931
479
    icc_link = gsicc_get_link_profile(pgs, dev, src_profile, des_profile,
932
479
        &rendering_params, pgs->memory, false);
933
479
    if (icc_link == NULL)
934
0
        return NULL;
935
936
    /* If different data sizes, we have to do an allocation */
937
479
    diff = des_profile->num_comps - src_profile->num_comps;
938
479
    if (diff != 0) {
939
479
        byte *src_ptr;
940
479
        byte *des_ptr;
941
942
479
        *did_alloc = true;
943
479
        des_rowstride = ((width + 3) & -4)<<deep;
944
479
        des_planestride = height * des_rowstride;
945
479
        des_n_planes = src_n_planes + diff;
946
479
        des_n_chan = src_n_chan + diff;
947
479
        des_data = gs_alloc_bytes(ctx->memory,
948
479
                                  (size_t)des_planestride * des_n_planes + CAL_SLOP,
949
479
                                  "pdf14_transform_color_buffer");
950
479
        if (des_data == NULL)
951
0
            return NULL;
952
953
        /* Copy over the noncolor planes. May only be a dirty part, so have
954
           to copy row by row */
955
479
        src_ptr = src_data;
956
479
        des_ptr = des_data;
957
5.34k
        for (j = 0; j < height; j++) {
958
9.72k
            for (k = 0; k < (src_n_planes - src_profile->num_comps); k++) {
959
4.86k
                memcpy(des_ptr + des_planestride * (k + des_profile->num_comps),
960
4.86k
                       src_ptr + src_planestride * (k + src_profile->num_comps),
961
4.86k
                       width<<deep);
962
4.86k
            }
963
4.86k
            src_ptr += src_rowstride;
964
4.86k
            des_ptr += des_rowstride;
965
4.86k
        }
966
479
    } else
967
0
        des_data = src_data;
968
969
    /* Set up the buffer descriptors. */
970
479
    gsicc_init_buffer(&src_buff_desc, src_profile->num_comps, 1<<deep, false,
971
479
                      false, true, src_planestride, src_rowstride, height, width);
972
479
    gsicc_init_buffer(&des_buff_desc, des_profile->num_comps, 1<<deep, false,
973
479
                      false, true, des_planestride, des_rowstride, height, width);
974
975
479
    src_buff_desc.endian_swap = endian_swap;
976
479
    des_buff_desc.endian_swap = endian_swap;
977
978
    /* If we have a matte entry, undo the pre-blending now.  Also set pdf14
979
       context to ensure that this is not done again during the group
980
       composition */
981
479
    if (has_matte &&
982
        /* Should always happen, but check for safety */
983
479
        ((mask_stack = ctx->mask_stack) != NULL) &&
984
479
        ((maskbuf = mask_stack->rc_mask->mask_buf) != NULL))
985
0
    {
986
0
        resolve_matte(maskbuf, src_data, src_planestride, src_rowstride, width, height, src_profile, deep);
987
0
    }
988
989
    /* Transform the data. Since the pdf14 device should be using RGB, CMYK or
990
       Gray buffers, this transform does not need to worry about the cmap procs
991
       of the target device. */
992
479
    code = (icc_link->procs.map_buffer)(dev, icc_link, &src_buff_desc, &des_buff_desc,
993
479
        src_data, des_data);
994
479
    gsicc_release_link(icc_link);
995
479
    if (code < 0)
996
0
        return NULL;
997
998
479
    output->planestride = des_planestride;
999
479
    output->rowstride = des_rowstride;
1000
479
    output->n_planes = des_n_planes;
1001
479
    output->n_chan = des_n_chan;
1002
    /* If not in-place conversion, then release. */
1003
479
    if (des_data != src_data) {
1004
479
        gs_free_object(ctx->memory, output->data,
1005
479
            "pdf14_transform_color_buffer");
1006
479
        output->data = des_data;
1007
        /* Note, this is needed for case where we did a put image, as the
1008
           resulting transformed buffer may not be a full page. */
1009
479
        output->rect.p.x = x0;
1010
479
        output->rect.p.y = y0;
1011
479
        output->rect.q.x = x0 + width;
1012
479
        output->rect.q.y = y0 + height;
1013
479
    }
1014
479
    return output;
1015
479
}
1016
1017
/* This is a routine to do memset's but with 16 bit values.
1018
 * Note, that we still take bytes, NOT "num values to set".
1019
 * We assume dest is 16 bit aligned. We assume that bytes is
1020
 * a multiple of 2. */
1021
static void gs_memset16(byte *dest_, uint16_t value, int bytes)
1022
0
{
1023
0
    uint16_t *dest = (uint16_t *)(void *)dest_;
1024
0
    uint32_t v;
1025
0
    if (bytes < 0)
1026
0
        return;
1027
0
    if (((intptr_t)dest) & 2) {
1028
0
        *dest++ = value;
1029
0
        bytes--;
1030
0
        if (bytes == 0)
1031
0
            return;
1032
0
    }
1033
0
    v = value | (value<<16);
1034
0
    bytes -= 2;
1035
0
    while (bytes > 0) {
1036
0
        *(uint32_t *)dest = v;
1037
0
        dest += 2;
1038
0
        bytes -= 4;
1039
0
    }
1040
0
    bytes += 2;
1041
0
    if (bytes & 2) {
1042
0
        *dest = value;
1043
0
    }
1044
0
}
1045
1046
static pdf14_buf*
1047
pdf14_transform_color_buffer_no_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1048
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1049
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1050
    bool deep, bool endian_swap)
1051
479
{
1052
479
    if (deep)
1053
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1054
0
            des_profile, x0, y0, width, height, did_alloc, false, true, endian_swap);
1055
479
    else
1056
479
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1057
479
            des_profile, x0, y0, width, height, did_alloc, false, false, endian_swap);
1058
479
}
1059
1060
static pdf14_buf*
1061
pdf14_transform_color_buffer_with_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1062
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1063
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1064
    bool deep, bool endian_swap)
1065
0
{
1066
0
    if (deep)
1067
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1068
0
            des_profile, x0, y0, width, height, did_alloc, true, true, endian_swap);
1069
0
    else
1070
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1071
0
            des_profile, x0, y0, width, height, did_alloc, true, false, endian_swap);
1072
0
}
1073
1074
/**
1075
 * pdf14_buf_new: Allocate a new PDF 1.4 buffer.
1076
 * @n_chan: Number of pixel channels including alpha.
1077
 *
1078
 * Return value: Newly allocated buffer, or NULL on failure.
1079
 **/
1080
static  pdf14_buf *
1081
pdf14_buf_new(gs_int_rect *rect, bool has_tags, bool has_alpha_g,
1082
              bool has_shape, bool idle, int n_chan, int num_spots,
1083
              gs_memory_t *memory, bool deep)
1084
204k
{
1085
1086
    /* Note that alpha_g is the alpha for the GROUP */
1087
    /* This is distinct from the alpha that may also exist */
1088
    /* for the objects within the group.  Hence it can introduce */
1089
    /* yet another plane */
1090
1091
204k
    pdf14_buf *result;
1092
204k
    int rowstride = ((rect->q.x - rect->p.x + 3) & -4)<<deep;
1093
204k
    int height = (rect->q.y - rect->p.y);
1094
204k
    int n_planes = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0) +
1095
204k
                   (has_tags ? 1 : 0);
1096
204k
    int planestride;
1097
204k
    double dsize = (((double) rowstride) * height) * n_planes;
1098
1099
204k
    if (dsize > (double)max_uint)
1100
0
      return NULL;
1101
1102
204k
    result = gs_alloc_struct(memory, pdf14_buf, &st_pdf14_buf,
1103
204k
                             "pdf14_buf_new");
1104
204k
    if (result == NULL)
1105
0
        return result;
1106
1107
204k
    result->memory = memory;
1108
204k
    result->backdrop = NULL;
1109
204k
    result->saved = NULL;
1110
204k
    result->isolated = false;
1111
204k
    result->knockout = false;
1112
204k
    result->has_alpha_g = has_alpha_g;
1113
204k
    result->has_shape = has_shape;
1114
204k
    result->has_tags = has_tags;
1115
204k
    result->rect = *rect;
1116
204k
    result->n_chan = n_chan;
1117
204k
    result->n_planes = n_planes;
1118
204k
    result->rowstride = rowstride;
1119
204k
    result->transfer_fn = NULL;
1120
204k
    result->is_ident = true;
1121
204k
    result->matte_num_comps = 0;
1122
204k
    result->matte = NULL;
1123
204k
    result->mask_stack = NULL;
1124
204k
    result->idle = idle;
1125
204k
    result->mask_id = 0;
1126
204k
    result->num_spots = num_spots;
1127
204k
    result->deep = deep;
1128
204k
    result->page_group = false;
1129
204k
    result->group_color_info = NULL;
1130
204k
    result->group_popped = false;
1131
1132
204k
    if (idle || height <= 0) {
1133
        /* Empty clipping - will skip all drawings. */
1134
128k
        result->planestride = 0;
1135
128k
        result->data = 0;
1136
128k
    } else {
1137
75.3k
        planestride = rowstride * height;
1138
75.3k
        result->planestride = planestride;
1139
75.3k
        result->data = gs_alloc_bytes(memory,
1140
75.3k
                                      (size_t)planestride * n_planes + CAL_SLOP,
1141
75.3k
                                      "pdf14_buf_new");
1142
75.3k
        if (result->data == NULL) {
1143
0
            gs_free_object(memory, result, "pdf14_buf_new");
1144
0
            return NULL;
1145
0
        }
1146
75.3k
        if (has_alpha_g) {
1147
6.84k
            int alpha_g_plane = n_chan + (has_shape ? 1 : 0);
1148
            /* Memsetting by 0, so this copes with the deep case too */
1149
6.84k
            memset(result->data + alpha_g_plane * planestride, 0, planestride);
1150
6.84k
        }
1151
75.3k
        if (has_tags) {
1152
0
            int tags_plane = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0);
1153
            /* Memsetting by 0, so this copes with the deep case too */
1154
0
            memset (result->data + tags_plane * planestride,
1155
0
                    GS_UNTOUCHED_TAG, planestride);
1156
0
        }
1157
75.3k
    }
1158
    /* Initialize dirty box with an invalid rectangle (the reversed rectangle).
1159
     * Any future drawing will make it valid again, so we won't blend back
1160
     * more than we need. */
1161
204k
    result->dirty.p.x = rect->q.x;
1162
204k
    result->dirty.p.y = rect->q.y;
1163
204k
    result->dirty.q.x = rect->p.x;
1164
204k
    result->dirty.q.y = rect->p.y;
1165
204k
    return result;
1166
204k
}
1167
1168
static  void
1169
pdf14_buf_free(pdf14_buf *buf)
1170
204k
{
1171
204k
    pdf14_group_color_t *group_color_info = buf->group_color_info;
1172
204k
    gs_memory_t *memory = buf->memory;
1173
1174
204k
    if (buf->mask_stack && buf->mask_stack->rc_mask)
1175
204k
        rc_decrement(buf->mask_stack->rc_mask, "pdf14_buf_free");
1176
1177
204k
    gs_free_object(memory, buf->mask_stack, "pdf14_buf_free");
1178
204k
    gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free");
1179
204k
    gs_free_object(memory, buf->matte, "pdf14_buf_free");
1180
204k
    gs_free_object(memory, buf->data, "pdf14_buf_free");
1181
1182
408k
    while (group_color_info) {
1183
204k
       if (group_color_info->icc_profile != NULL) {
1184
204k
           gsicc_adjust_profile_rc(group_color_info->icc_profile, -1, "pdf14_buf_free");
1185
204k
       }
1186
204k
       buf->group_color_info = group_color_info->previous;
1187
204k
       gs_free_object(memory, group_color_info, "pdf14_buf_free");
1188
204k
       group_color_info = buf->group_color_info;
1189
204k
    }
1190
1191
204k
    gs_free_object(memory, buf->backdrop, "pdf14_buf_free");
1192
204k
    gs_free_object(memory, buf, "pdf14_buf_free");
1193
204k
}
1194
1195
static void
1196
rc_pdf14_maskbuf_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
1197
67.2k
{
1198
    /* Ending the mask buffer. */
1199
67.2k
    pdf14_rcmask_t *rcmask = (pdf14_rcmask_t * ) ptr_in;
1200
    /* free the pdf14 buffer. */
1201
67.2k
    if ( rcmask->mask_buf != NULL ){
1202
8.72k
        pdf14_buf_free(rcmask->mask_buf);
1203
8.72k
    }
1204
67.2k
    gs_free_object(mem, rcmask, "rc_pdf14_maskbuf_free");
1205
67.2k
}
1206
1207
static  pdf14_rcmask_t *
1208
pdf14_rcmask_new(gs_memory_t *memory)
1209
67.2k
{
1210
67.2k
    pdf14_rcmask_t *result;
1211
1212
67.2k
    result = gs_alloc_struct(memory, pdf14_rcmask_t, &st_pdf14_rcmask,
1213
67.2k
                             "pdf14_maskbuf_new");
1214
67.2k
    if (result == NULL)
1215
0
        return NULL;
1216
67.2k
    rc_init_free(result, memory, 1, rc_pdf14_maskbuf_free);
1217
67.2k
    result->mask_buf = NULL;
1218
67.2k
    result->memory = memory;
1219
67.2k
    return result;
1220
67.2k
}
1221
1222
static  pdf14_ctx *
1223
pdf14_ctx_new(gx_device *dev, bool deep)
1224
44.6k
{
1225
44.6k
    pdf14_ctx *result;
1226
44.6k
    gs_memory_t *memory = dev->memory->stable_memory;
1227
1228
44.6k
    result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx, "pdf14_ctx_new");
1229
44.6k
    if (result == NULL)
1230
0
        return result;
1231
44.6k
    result->stack = NULL;
1232
44.6k
    result->mask_stack = pdf14_mask_element_new(memory);
1233
44.6k
    result->mask_stack->rc_mask = pdf14_rcmask_new(memory);
1234
44.6k
    result->memory = memory;
1235
44.6k
    result->smask_depth = 0;
1236
44.6k
    result->smask_blend = false;
1237
44.6k
    result->deep = deep;
1238
44.6k
    result->base_color = NULL;
1239
44.6k
    return result;
1240
44.6k
}
1241
1242
static  void
1243
pdf14_ctx_free(pdf14_ctx *ctx)
1244
44.6k
{
1245
44.6k
    pdf14_buf *buf, *next;
1246
1247
44.6k
    if (ctx->base_color) {
1248
30.1k
       gsicc_adjust_profile_rc(ctx->base_color->icc_profile, -1, "pdf14_ctx_free");
1249
30.1k
        gs_free_object(ctx->memory, ctx->base_color, "pdf14_ctx_free");
1250
30.1k
    }
1251
44.6k
    if (ctx->mask_stack) {
1252
        /* A mask was created but was not used in this band. */
1253
5.72k
        rc_decrement(ctx->mask_stack->rc_mask, "pdf14_ctx_free");
1254
5.72k
        gs_free_object(ctx->memory, ctx->mask_stack, "pdf14_ctx_free");
1255
5.72k
    }
1256
87.2k
    for (buf = ctx->stack; buf != NULL; buf = next) {
1257
42.5k
        next = buf->saved;
1258
42.5k
        pdf14_buf_free(buf);
1259
42.5k
    }
1260
44.6k
    gs_free_object (ctx->memory, ctx, "pdf14_ctx_free");
1261
44.6k
}
1262
1263
/**
1264
 * pdf14_find_backdrop_buf: Find backdrop buffer.
1265
 *
1266
 * Return value: Backdrop buffer for current group operation, or NULL
1267
 * if backdrop is fully transparent.
1268
 **/
1269
static  pdf14_buf *
1270
pdf14_find_backdrop_buf(pdf14_ctx *ctx, bool *is_backdrop)
1271
47.1k
{
1272
    /* Our new buffer is buf */
1273
47.1k
    pdf14_buf *buf = ctx->stack;
1274
1275
47.1k
    *is_backdrop = false;
1276
1277
47.1k
    if (buf != NULL) {
1278
        /* If the new buffer is isolated there is no backdrop */
1279
47.1k
        if (buf->isolated) return NULL;
1280
1281
        /* If the previous buffer is a knockout group
1282
           then we need to use its backdrop as the backdrop. If
1283
           it was isolated then that back drop was NULL */
1284
6.84k
        if (buf->saved != NULL && buf->saved->knockout) {
1285
            /* Per the spec, if we have a non-isolated group
1286
               in a knockout group the non-isolated group
1287
               uses the backdrop of its parent group (the knockout group)
1288
               as its own backdrop.  The non-isolated group must
1289
               go through the standard re-composition operation
1290
               to avoid the double application of the backdrop */
1291
49
            *is_backdrop = true;
1292
49
            return buf->saved;
1293
49
        }
1294
        /* This should be the non-isolated case where its parent is
1295
           not a knockout */
1296
6.80k
        if (buf->saved != NULL) {
1297
6.80k
            return buf->saved;
1298
6.80k
        }
1299
6.80k
    }
1300
0
    return NULL;
1301
47.1k
}
1302
1303
static pdf14_group_color_t*
1304
pdf14_make_base_group_color(gx_device* dev)
1305
30.1k
{
1306
30.1k
    pdf14_device* pdev = (pdf14_device*)dev;
1307
30.1k
    pdf14_group_color_t* group_color;
1308
30.1k
    bool deep = pdev->ctx->deep;
1309
1310
30.1k
    if_debug0m('v', dev->memory, "[v]pdf14_make_base_group_color\n");
1311
1312
30.1k
    group_color = gs_alloc_struct(pdev->ctx->memory,
1313
30.1k
        pdf14_group_color_t, &st_pdf14_clr,
1314
30.1k
        "pdf14_make_base_group_color");
1315
1316
30.1k
    if (group_color == NULL)
1317
0
        return NULL;
1318
30.1k
    memset(group_color, 0, sizeof(pdf14_group_color_t));
1319
1320
30.1k
    group_color->blend_procs = pdev->blend_procs;
1321
30.1k
    group_color->polarity = pdev->color_info.polarity;
1322
30.1k
    group_color->num_components = pdev->color_info.num_components;
1323
30.1k
    group_color->isadditive = pdev->ctx->additive;
1324
30.1k
    group_color->unpack_procs = pdev->pdf14_procs;
1325
30.1k
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
1326
30.1k
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
1327
30.1k
    group_color->depth = pdev->color_info.depth;
1328
30.1k
    group_color->decode = dev_proc(pdev, decode_color);
1329
30.1k
    group_color->encode = dev_proc(pdev, encode_color);
1330
30.1k
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
1331
30.1k
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
1332
30.1k
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
1333
30.1k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1334
30.1k
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
1335
30.1k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1336
30.1k
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
1337
30.1k
    group_color->icc_profile =
1338
30.1k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1339
30.1k
    gsicc_adjust_profile_rc(group_color->icc_profile, 1, "pdf14_make_base_group_color");
1340
1341
30.1k
    return group_color;
1342
30.1k
}
1343
1344
/* This wil create the first buffer when we have
1345
   either the first drawing operation or transparency
1346
   group push.  At that time, the color space in which
1347
   we are going to be doing the alpha blend will be known. */
1348
static int
1349
pdf14_initialize_ctx(gx_device* dev, int n_chan, bool additive, const gs_gstate* pgs)
1350
23.4M
{
1351
23.4M
    pdf14_device* pdev = (pdf14_device*)dev;
1352
23.4M
    bool has_tags = device_encodes_tags(dev);
1353
23.4M
    int num_spots = pdev->ctx->num_spots;
1354
23.4M
    pdf14_buf* buf;
1355
23.4M
    gs_memory_t* memory = dev->memory->stable_memory;
1356
1357
    /* Check for a blank idle group as a base group */
1358
23.4M
    if (pdev->ctx->stack != NULL && pdev->ctx->stack->group_popped &&
1359
23.4M
        pdev->ctx->stack->idle) {
1360
0
        pdf14_buf_free(pdev->ctx->stack);
1361
0
        pdev->ctx->stack = NULL;
1362
0
    }
1363
1364
23.4M
    if (pdev->ctx->stack != NULL)
1365
23.4M
        return 0;
1366
1367
23.4M
    if_debug2m('v', dev->memory, "[v]pdf14_initialize_ctx: width = %d, height = %d\n",
1368
14.9k
        dev->width, dev->height);
1369
1370
14.9k
    buf = pdf14_buf_new(&(pdev->ctx->rect), has_tags, false, false, false, n_chan + 1,
1371
14.9k
        num_spots, memory, pdev->ctx->deep);
1372
14.9k
    if (buf == NULL) {
1373
0
        return gs_error_VMerror;
1374
0
    }
1375
14.9k
    if_debug5m('v', memory,
1376
14.9k
        "[v]base buf: %d x %d, %d color channels, %d planes, deep=%d\n",
1377
14.9k
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes, pdev->ctx->deep);
1378
1379
    /* This check is not really needed */
1380
14.9k
    if (buf->data != NULL) {
1381
        /* Memsetting by 0, so this copes with the deep case too */
1382
14.9k
        if (buf->has_tags) {
1383
0
            memset(buf->data, 0, (size_t)buf->planestride * (buf->n_planes - 1));
1384
0
        }
1385
14.9k
        else {
1386
14.9k
            memset(buf->data, 0, (size_t)buf->planestride * buf->n_planes);
1387
14.9k
        }
1388
14.9k
    }
1389
14.9k
    buf->saved = NULL;
1390
14.9k
    pdev->ctx->stack = buf;
1391
14.9k
    pdev->ctx->n_chan = n_chan;
1392
14.9k
    pdev->ctx->additive = additive;
1393
1394
    /* Every buffer needs group color information including the base
1395
       one that is created for when we have no group */
1396
14.9k
    buf->group_color_info = gs_alloc_struct(pdev->memory->stable_memory,
1397
14.9k
            pdf14_group_color_t, &st_pdf14_clr, "pdf14_initialize_ctx");
1398
14.9k
    if (buf->group_color_info == NULL)
1399
0
        return gs_error_VMerror;
1400
1401
14.9k
    if (pgs != NULL)
1402
10.0k
        buf->group_color_info->get_cmap_procs = pgs->get_cmap_procs;
1403
4.97k
    else
1404
4.97k
        buf->group_color_info->get_cmap_procs = pdf14_get_cmap_procs;
1405
1406
14.9k
    buf->group_color_info->group_color_mapping_procs =
1407
14.9k
        dev_proc(pdev, get_color_mapping_procs);
1408
14.9k
    buf->group_color_info->group_color_comp_index =
1409
14.9k
        dev_proc(pdev, get_color_comp_index);
1410
14.9k
    buf->group_color_info->blend_procs = pdev->blend_procs;
1411
14.9k
    buf->group_color_info->polarity = pdev->color_info.polarity;
1412
14.9k
    buf->group_color_info->num_components = pdev->color_info.num_components;
1413
14.9k
    buf->group_color_info->isadditive = pdev->ctx->additive;
1414
14.9k
    buf->group_color_info->unpack_procs = pdev->pdf14_procs;
1415
14.9k
    buf->group_color_info->depth = pdev->color_info.depth;
1416
14.9k
    buf->group_color_info->max_color = pdev->color_info.max_color;
1417
14.9k
    buf->group_color_info->max_gray = pdev->color_info.max_gray;
1418
14.9k
    buf->group_color_info->encode = dev_proc(pdev, encode_color);
1419
14.9k
    buf->group_color_info->decode = dev_proc(pdev, decode_color);
1420
14.9k
    memcpy(&(buf->group_color_info->comp_bits), &(pdev->color_info.comp_bits),
1421
14.9k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1422
14.9k
    memcpy(&(buf->group_color_info->comp_shift), &(pdev->color_info.comp_shift),
1423
14.9k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1424
14.9k
    buf->group_color_info->previous = NULL;  /* used during clist writing */
1425
14.9k
    buf->group_color_info->icc_profile =
1426
14.9k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1427
14.9k
    if (buf->group_color_info->icc_profile != NULL)
1428
14.9k
        gsicc_adjust_profile_rc(buf->group_color_info->icc_profile, 1, "pdf14_initialize_ctx");
1429
1430
14.9k
    return 0;
1431
14.9k
}
1432
1433
static pdf14_group_color_t*
1434
pdf14_clone_group_color_info(gx_device* pdev, pdf14_group_color_t* src)
1435
1.60k
{
1436
1.60k
    pdf14_group_color_t* des = gs_alloc_struct(pdev->memory->stable_memory,
1437
1.60k
        pdf14_group_color_t, &st_pdf14_clr, "pdf14_clone_group_color_info");
1438
1.60k
    if (des == NULL)
1439
0
        return NULL;
1440
1441
1.60k
    memcpy(des, src, sizeof(pdf14_group_color_t));
1442
1.60k
    if (des->icc_profile != NULL)
1443
1.60k
        gsicc_adjust_profile_rc(des->icc_profile, 1, "pdf14_clone_group_color_info");
1444
1.60k
    des->previous = NULL;  /* used during clist writing for state stack */
1445
1446
1.60k
    return des;
1447
1.60k
}
1448
1449
static  int
1450
pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect, bool isolated,
1451
                              bool knockout, uint16_t alpha, uint16_t shape, uint16_t opacity,
1452
                              gs_blend_mode_t blend_mode, bool idle, uint mask_id,
1453
                              int numcomps, bool cm_back_drop, bool shade_group,
1454
                              cmm_profile_t *group_profile, cmm_profile_t *tos_profile,
1455
                              pdf14_group_color_t* group_color, gs_gstate *pgs,
1456
                              gx_device *dev)
1457
166k
{
1458
166k
    pdf14_buf *tos = ctx->stack;
1459
166k
    pdf14_buf *buf, * pdf14_backdrop;
1460
166k
    bool has_shape = false;
1461
166k
    bool is_backdrop;
1462
166k
    int num_spots;
1463
1464
166k
    if_debug1m('v', ctx->memory,
1465
166k
               "[v]pdf14_push_transparency_group, idle = %d\n", idle);
1466
1467
166k
    if (tos != NULL)
1468
138k
        has_shape = tos->has_shape || tos->knockout;
1469
1470
166k
    if (ctx->smask_depth > 0)
1471
297
        num_spots = 0;
1472
165k
    else
1473
165k
        num_spots = ctx->num_spots;
1474
1475
1476
166k
    buf = pdf14_buf_new(rect, ctx->has_tags, !isolated, has_shape, idle, numcomps + 1,
1477
166k
                        num_spots, ctx->memory, ctx->deep);
1478
166k
    if (buf == NULL)
1479
0
        return_error(gs_error_VMerror);
1480
1481
166k
    if_debug4m('v', ctx->memory,
1482
166k
        "[v]base buf: %d x %d, %d color channels, %d planes\n",
1483
166k
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes);
1484
166k
    buf->isolated = isolated;
1485
166k
    buf->knockout = knockout;
1486
166k
    buf->alpha = alpha;
1487
166k
    buf->shape = shape;
1488
166k
    buf->opacity = opacity;
1489
166k
    buf->blend_mode = blend_mode;
1490
166k
    buf->mask_id = mask_id;
1491
166k
    buf->mask_stack = ctx->mask_stack; /* Save because the group rendering may
1492
                                          set up another (nested) mask. */
1493
166k
    ctx->mask_stack = NULL; /* Clean the mask field for rendering this group.
1494
                            See pdf14_pop_transparency_group how to handle it. */
1495
166k
    buf->saved = tos;
1496
166k
    buf->group_color_info = group_color;
1497
1498
166k
    if (tos == NULL)
1499
27.5k
        buf->page_group = true;
1500
1501
166k
    ctx->stack = buf;
1502
166k
    if (buf->data == NULL)
1503
119k
        return 0;
1504
47.1k
    if (idle)
1505
0
        return 0;
1506
47.1k
    pdf14_backdrop = pdf14_find_backdrop_buf(ctx, &is_backdrop);
1507
1508
    /* Initializes buf->data with the backdrop or as opaque */
1509
47.1k
    if (pdf14_backdrop == NULL || (is_backdrop && pdf14_backdrop->backdrop == NULL)) {
1510
        /* Note, don't clear out tags set by pdf14_buf_new == GS_UNKNOWN_TAG */
1511
        /* Memsetting by 0, so this copes with the deep case too */
1512
40.2k
        memset(buf->data, 0, (size_t)buf->planestride *
1513
40.2k
                                          (buf->n_chan +
1514
40.2k
                                           (buf->has_shape ? 1 : 0) +
1515
40.2k
                                           (buf->has_alpha_g ? 1 : 0)));
1516
40.2k
    } else {
1517
6.84k
        if (!cm_back_drop) {
1518
6.84k
            pdf14_preserve_backdrop(buf, pdf14_backdrop, is_backdrop
1519
#if RAW_DUMP
1520
                                    , ctx->memory
1521
#endif
1522
6.84k
                                    );
1523
6.84k
        } else {
1524
            /* We must have an non-isolated group with a mismatch in color spaces.
1525
                In this case, we can't just copy the buffer but must CM it */
1526
0
            pdf14_preserve_backdrop_cm(buf, group_profile, pdf14_backdrop, tos_profile,
1527
0
                                        ctx->memory, pgs, dev, is_backdrop);
1528
0
        }
1529
6.84k
    }
1530
1531
    /* If our new group is a non-isolated knockout group, we have to maintain
1532
       a copy of the backdrop in case we are drawing nonisolated groups on top of the
1533
       knockout group. They have to always blend with the groups backdrop
1534
       not what is currently drawn in the group. Selection of the backdrop
1535
       depends upon the properties of the parent group. For example, if
1536
       the parent itself is a knockout group we actually
1537
       need to blend with its backdrop. This could be NULL if the parent was
1538
       an isolated knockout group. */
1539
47.1k
    if (buf->knockout && pdf14_backdrop != NULL) {
1540
4.82k
        buf->backdrop = gs_alloc_bytes(ctx->memory,
1541
4.82k
                                       (size_t)buf->planestride * buf->n_planes + CAL_SLOP,
1542
4.82k
                                       "pdf14_push_transparency_group");
1543
4.82k
        if (buf->backdrop == NULL) {
1544
0
            return gs_throw(gs_error_VMerror, "Knockout backdrop allocation failed");
1545
0
        }
1546
1547
4.82k
        memcpy(buf->backdrop, buf->data,
1548
4.82k
               (size_t)buf->planestride * buf->n_planes);
1549
1550
#if RAW_DUMP
1551
        /* Dump the current buffer to see what we have. */
1552
        dump_raw_buffer(ctx->memory,
1553
            ctx->stack->rect.q.y - ctx->stack->rect.p.y,
1554
            ctx->stack->rowstride >> buf->deep, buf->n_planes,
1555
            ctx->stack->planestride, ctx->stack->rowstride,
1556
            "KnockoutBackDrop", buf->backdrop, buf->deep);
1557
        global_index++;
1558
#endif
1559
4.82k
    }
1560
#if RAW_DUMP
1561
    /* Dump the current buffer to see what we have. */
1562
    dump_raw_buffer(ctx->memory,
1563
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1564
                    ctx->stack->rowstride>>buf->deep, ctx->stack->n_planes,
1565
                    ctx->stack->planestride, ctx->stack->rowstride,
1566
                    "TransGroupPush", ctx->stack->data, buf->deep);
1567
    global_index++;
1568
#endif
1569
47.1k
    return 0;
1570
47.1k
}
1571
1572
static  int
1573
pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx,
1574
    const pdf14_nonseparable_blending_procs_t * pblend_procs,
1575
    int tos_num_color_comp, cmm_profile_t *curr_icc_profile, gx_device *dev)
1576
166k
{
1577
166k
    pdf14_buf *tos = ctx->stack;
1578
166k
    pdf14_buf *nos = tos->saved;
1579
166k
    pdf14_mask_t *mask_stack = tos->mask_stack;
1580
166k
    pdf14_buf *maskbuf;
1581
166k
    int x0, x1, y0, y1;
1582
166k
    int nos_num_color_comp;
1583
166k
    bool no_icc_match;
1584
166k
    pdf14_device *pdev = (pdf14_device *)dev;
1585
166k
    bool overprint = pdev->overprint;
1586
166k
    gx_color_index drawn_comps = pdev->drawn_comps_stroke | pdev->drawn_comps_fill;
1587
166k
    bool has_matte = false;
1588
166k
    int code = 0;
1589
1590
#ifdef DEBUG
1591
    pdf14_debug_mask_stack_state(ctx);
1592
#endif
1593
166k
    if (mask_stack == NULL) {
1594
118k
        maskbuf = NULL;
1595
118k
    }
1596
47.9k
    else {
1597
47.9k
        maskbuf = mask_stack->rc_mask->mask_buf;
1598
47.9k
    }
1599
1600
166k
    if (maskbuf != NULL && maskbuf->matte != NULL)
1601
0
        has_matte = true;
1602
1603
    /* Check if this is our last buffer, if yes, there is nothing to
1604
       compose to.  Keep this buffer until we have the put image.
1605
       If we have another group push, this group must be destroyed.
1606
       This only occurs sometimes when at clist creation time
1607
       push_shfill_group occured and nothing was drawn in this group.
1608
       There is also the complication if we have a softmask.  There
1609
       are two approaches to this problem.  Apply the softmask during
1610
       the put image or handle it now.  I choose the later as the
1611
       put_image code is already way to complicated. */
1612
166k
    if (nos == NULL && maskbuf == NULL) {
1613
27.5k
        tos->group_popped = true;
1614
27.5k
        return 0;
1615
27.5k
    }
1616
1617
    /* Here is the case with the soft mask.  Go ahead and create a new
1618
       target buffer (nos) with the same color information etc, but blank
1619
       and go ahead and do the blend with the softmask so that it gets applied. */
1620
138k
    if (nos == NULL && maskbuf != NULL) {
1621
0
        nos = pdf14_buf_new(&(tos->rect), ctx->has_tags, !tos->isolated, tos->has_shape,
1622
0
            tos->idle, tos->n_chan, tos->num_spots, ctx->memory, ctx->deep);
1623
0
        if (nos == NULL) {
1624
0
            code = gs_error_VMerror;
1625
0
            goto exit;
1626
0
        }
1627
1628
0
        if_debug4m('v', ctx->memory,
1629
0
            "[v] special buffer for softmask application: %d x %d, %d color channels, %d planes\n",
1630
0
            nos->rect.q.x, nos->rect.q.y, nos->n_chan, nos->n_planes);
1631
1632
0
        nos->dirty = tos->dirty;
1633
0
        nos->isolated = tos->isolated;
1634
0
        nos->knockout = tos->knockout;
1635
0
        nos->alpha = 65535;
1636
0
        nos->shape = 65535;
1637
0
        nos->opacity = 65535;
1638
0
        nos->blend_mode = tos->blend_mode;
1639
0
        nos->mask_id = tos->mask_id;
1640
0
        nos->group_color_info = pdf14_clone_group_color_info(dev, tos->group_color_info);
1641
1642
0
        if (nos->data != NULL)
1643
0
            memset(nos->data, 0,
1644
0
                   (size_t)nos->planestride *
1645
0
                                          (nos->n_chan +
1646
0
                                           (nos->has_shape ? 1 : 0) +
1647
0
                                           (nos->has_alpha_g ? 1 : 0)));
1648
0
    }
1649
1650
    /* Before we get started, lets see if we have somehow gotten into
1651
       what should be an impossible situation where the group color
1652
       information does not match the buffer color information. This
1653
       can occur is there were memory issues that have perhaps blown
1654
       away information, or in the example of Bug 705197 the PDF interpreter
1655
       reuses a pattern during a circular reference causing an aliasing
1656
       of two nested patterns, one of which has a softmask. The change in
1657
       the buffer size of the inner one blows away the buffer of the
1658
       outer one leading to a mismatch of color spaces. Here
1659
       we can at least catch the case when the color space sizes have
1660
       changed and avoid buffer over-runs that would occur when we try
1661
       to do the group composition */
1662
138k
    if (nos->n_chan - 1 != nos->group_color_info->num_components ||
1663
138k
        tos->n_chan - 1 != tos_num_color_comp)
1664
0
        return_error(gs_error_Fatal);
1665
1666
138k
    nos_num_color_comp = nos->group_color_info->num_components - tos->num_spots;
1667
138k
    tos_num_color_comp = tos_num_color_comp - tos->num_spots;
1668
1669
    /* Sanitise the dirty rectangles, in case some of the drawing routines
1670
     * have made them overly large. */
1671
138k
    rect_intersect(tos->dirty, tos->rect);
1672
138k
    rect_intersect(nos->dirty, nos->rect);
1673
    /* dirty = the marked bbox. rect = the entire bounds of the buffer. */
1674
    /* Everything marked on tos that fits onto nos needs to be merged down. */
1675
138k
    y0 = max(tos->dirty.p.y, nos->rect.p.y);
1676
138k
    y1 = min(tos->dirty.q.y, nos->rect.q.y);
1677
138k
    x0 = max(tos->dirty.p.x, nos->rect.p.x);
1678
138k
    x1 = min(tos->dirty.q.x, nos->rect.q.x);
1679
138k
    if (ctx->mask_stack) {
1680
        /* This can occur when we have a situation where we are ending out of
1681
           a group that has internal to it a soft mask and another group.
1682
           The soft mask left over from the previous trans group pop is put
1683
           into ctx->masbuf, since it is still active if another trans group
1684
           push occurs to use it.  If one does not occur, but instead we find
1685
           ourselves popping from a parent group, then this softmask is no
1686
           longer needed.  We will rc_decrement and set it to NULL. */
1687
0
        rc_decrement(ctx->mask_stack->rc_mask, "pdf14_pop_transparency_group");
1688
0
        if (ctx->mask_stack->rc_mask == NULL ){
1689
0
            gs_free_object(ctx->memory, ctx->mask_stack, "pdf14_pop_transparency_group");
1690
0
        }
1691
0
        ctx->mask_stack = NULL;
1692
0
    }
1693
138k
    ctx->mask_stack = mask_stack;  /* Restore the mask saved by pdf14_push_transparency_group. */
1694
138k
    tos->mask_stack = NULL;        /* Clean the pointer sinse the mask ownership is now passed to ctx. */
1695
138k
    if (tos->idle)
1696
116k
        goto exit;
1697
21.7k
    if (maskbuf != NULL && maskbuf->data == NULL && maskbuf->alpha == 255)
1698
0
        goto exit;
1699
1700
#if RAW_DUMP
1701
    /* Dump the current buffer to see what we have. */
1702
    dump_raw_buffer(ctx->memory,
1703
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1704
                    ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1705
                    ctx->stack->planestride, ctx->stack->rowstride,
1706
                    "aaTrans_Group_Pop", ctx->stack->data, ctx->stack->deep);
1707
    global_index++;
1708
#endif
1709
/* Note currently if a pattern space has transparency, the ICC profile is not used
1710
   for blending purposes.  Instead we rely upon the gray, rgb, or cmyk parent space.
1711
   This is partially due to the fact that pdf14_pop_transparency_group and
1712
   pdf14_push_transparnecy_group have no real ICC interaction and those are the
1713
   operations called in the tile transparency code.  Instead we may want to
1714
   look at pdf14_begin_transparency_group and pdf14_end_transparency group which
1715
   is where all the ICC information is handled.  We will return to look at that later */
1716
21.7k
    if (nos->group_color_info->icc_profile != NULL) {
1717
21.7k
        no_icc_match = !gsicc_profiles_equal(nos->group_color_info->icc_profile, curr_icc_profile);
1718
21.7k
    } else {
1719
        /* Let the other tests make the decision if we need to transform */
1720
0
        no_icc_match = false;
1721
0
    }
1722
    /* If the color spaces are different and we actually did do a swap of
1723
       the procs for color */
1724
21.7k
    if ((nos->group_color_info->group_color_mapping_procs != NULL &&
1725
21.7k
        nos_num_color_comp != tos_num_color_comp) || no_icc_match) {
1726
705
        if (x0 < x1 && y0 < y1) {
1727
479
            pdf14_buf *result;
1728
479
            bool did_alloc; /* We don't care here */
1729
1730
479
            if (has_matte) {
1731
0
                result = pdf14_transform_color_buffer_with_matte(pgs, ctx, dev,
1732
0
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1733
0
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1734
0
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false);
1735
0
                has_matte = false;
1736
479
            } else {
1737
479
                result = pdf14_transform_color_buffer_no_matte(pgs, ctx, dev,
1738
479
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1739
479
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1740
479
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false);
1741
479
            }
1742
479
            if (result == NULL) {
1743
                /* Clean up and return error code */
1744
0
                code = gs_error_unknownerror;
1745
0
                goto exit;
1746
0
            }
1747
1748
#if RAW_DUMP
1749
            /* Dump the current buffer to see what we have. */
1750
            dump_raw_buffer(ctx->memory,
1751
                            ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1752
                            ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_chan,
1753
                            ctx->stack->planestride, ctx->stack->rowstride,
1754
                            "aCMTrans_Group_ColorConv", ctx->stack->data,
1755
                            ctx->stack->deep);
1756
#endif
1757
             /* compose. never do overprint in this case */
1758
479
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1759
479
                 nos->group_color_info->isadditive,
1760
479
                 nos->group_color_info->blend_procs,
1761
479
                 has_matte, false, drawn_comps, ctx->memory, dev);
1762
479
        }
1763
21.0k
    } else {
1764
        /* Group color spaces are the same.  No color conversions needed */
1765
21.0k
        if (x0 < x1 && y0 < y1)
1766
16.3k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1767
16.3k
                                ctx->additive, pblend_procs, has_matte, overprint,
1768
16.3k
                                drawn_comps, ctx->memory, dev);
1769
21.0k
    }
1770
138k
exit:
1771
138k
    ctx->stack = nos;
1772
    /* We want to detect the cases where we have luminosity soft masks embedded
1773
       within one another.  The "alpha" channel really needs to be merged into
1774
       the luminosity channel in this case.  This will occur during the mask pop */
1775
138k
    if (ctx->smask_depth > 0 && maskbuf != NULL) {
1776
        /* Set the trigger so that we will blend if not alpha. Since
1777
           we have softmasks embedded in softmasks */
1778
11
        ctx->smask_blend = true;
1779
11
    }
1780
138k
    if_debug1m('v', ctx->memory, "[v]pop buf, idle=%d\n", tos->idle);
1781
138k
    pdf14_buf_free(tos);
1782
138k
    if (code < 0)
1783
0
        return_error(code);
1784
138k
    return 0;
1785
138k
}
1786
1787
/*
1788
 * Create a transparency mask that will be used as the mask for
1789
 * the next transparency group that is created afterwards.
1790
 * The sequence of calls is:
1791
 * push_mask, draw the mask, pop_mask, push_group, draw the group, pop_group
1792
 */
1793
static  int
1794
pdf14_push_transparency_mask(pdf14_ctx *ctx, gs_int_rect *rect, uint16_t bg_alpha,
1795
                             byte *transfer_fn, bool is_ident, bool idle,
1796
                             bool replacing, uint mask_id,
1797
                             gs_transparency_mask_subtype_t subtype,
1798
                             int numcomps, int Background_components,
1799
                             const float Background[], int Matte_components,
1800
                             const float Matte[], const float GrayBackground,
1801
                             pdf14_group_color_t* group_color)
1802
22.9k
{
1803
22.9k
    pdf14_buf *buf;
1804
22.9k
    int i;
1805
1806
22.9k
    if_debug2m('v', ctx->memory,
1807
22.9k
               "[v]pdf14_push_transparency_mask, idle=%d, replacing=%d\n",
1808
22.9k
               idle, replacing);
1809
22.9k
    ctx->smask_depth += 1;
1810
1811
22.9k
    if (ctx->stack == NULL) {
1812
0
        return_error(gs_error_VMerror);
1813
0
    }
1814
1815
    /* An optimization to consider is that if the SubType is Alpha
1816
       then we really should only be allocating the alpha band and
1817
       only draw with that channel.  Current architecture makes that
1818
       a bit tricky.  We need to create this based upon the size of
1819
       the color space + an alpha channel. NOT the device size
1820
       or the previous ctx size */
1821
    /* A mask doesn't worry about tags */
1822
22.9k
    buf = pdf14_buf_new(rect, false, false, false, idle, numcomps + 1, 0,
1823
22.9k
                        ctx->memory, ctx->deep);
1824
22.9k
    if (buf == NULL)
1825
0
        return_error(gs_error_VMerror);
1826
22.9k
    buf->alpha = bg_alpha;
1827
22.9k
    buf->is_ident = is_ident;
1828
    /* fill in, but these values aren't really used */
1829
22.9k
    buf->isolated = true;
1830
22.9k
    buf->knockout = false;
1831
22.9k
    buf->shape = 0xffff;
1832
22.9k
    buf->blend_mode = BLEND_MODE_Normal;
1833
22.9k
    buf->transfer_fn = transfer_fn;
1834
22.9k
    buf->matte_num_comps = Matte_components;
1835
22.9k
    buf->group_color_info = group_color;
1836
1837
22.9k
    if (Matte_components) {
1838
0
        buf->matte = (uint16_t *)gs_alloc_bytes(ctx->memory, Matte_components * sizeof(uint16_t) + CAL_SLOP,
1839
0
                                                "pdf14_push_transparency_mask");
1840
0
        if (buf->matte == NULL)
1841
0
            return_error(gs_error_VMerror);
1842
0
        for (i = 0; i < Matte_components; i++) {
1843
0
            buf->matte[i] = (uint16_t) floor(Matte[i] * 65535.0 + 0.5);
1844
0
        }
1845
0
    }
1846
22.9k
    buf->mask_id = mask_id;
1847
    /* If replacing=false, we start the mask for an image with SMask.
1848
       In this case the image's SMask temporary replaces the
1849
       mask of the containing group. Save the containing droup's mask
1850
       in buf->mask_stack */
1851
22.9k
    buf->mask_stack = ctx->mask_stack;
1852
22.9k
    if (buf->mask_stack){
1853
1.64k
        rc_increment(buf->mask_stack->rc_mask);
1854
1.64k
    }
1855
#if RAW_DUMP
1856
    /* Dump the current buffer to see what we have. */
1857
    if (ctx->stack->planestride > 0 ){
1858
        dump_raw_buffer(ctx->memory,
1859
                        ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1860
                        ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1861
                        ctx->stack->planestride, ctx->stack->rowstride,
1862
                        "Raw_Buf_PreSmask", ctx->stack->data, ctx->stack->deep);
1863
        global_index++;
1864
    }
1865
#endif
1866
22.9k
    buf->saved = ctx->stack;
1867
22.9k
    ctx->stack = buf;
1868
    /* Soft Mask related information so we know how to
1869
       compute luminosity when we pop the soft mask */
1870
22.9k
    buf->SMask_SubType = subtype;
1871
22.9k
    if (buf->data != NULL) {
1872
        /* We need to initialize it to the BC if it existed */
1873
        /* According to the spec, the CS has to be the same */
1874
        /* If the back ground component is black, then don't bother
1875
           with this.  Since we are forcing the rendering to gray
1876
           earlier now, go ahead and just use the GrayBackGround color
1877
           directly. */
1878
13.2k
        if ( Background_components && GrayBackground != 0.0 ) {
1879
0
            if (buf->deep) {
1880
0
                uint16_t gray = (uint16_t) (65535.0 * GrayBackground);
1881
0
                gs_memset16(buf->data, gray, buf->planestride);
1882
                /* If we have a background component that was not black, then we
1883
                   need to set the alpha for this mask as if we had drawn in the
1884
                   entire soft mask buffer */
1885
0
                gs_memset16(buf->data + buf->planestride, 65535,
1886
0
                            buf->planestride *(buf->n_chan - 1));
1887
0
            } else {
1888
0
                unsigned char gray = (unsigned char) (255.0 * GrayBackground);
1889
0
                memset(buf->data, gray, buf->planestride);
1890
                /* If we have a background component that was not black, then we
1891
                   need to set the alpha for this mask as if we had drawn in the
1892
                   entire soft mask buffer */
1893
0
                memset(buf->data + buf->planestride, 255,
1894
0
                       (size_t)buf->planestride * (buf->n_chan - 1));
1895
0
            }
1896
13.2k
        } else {
1897
            /* Compose mask with opaque background */
1898
13.2k
            memset(buf->data, 0, (size_t)buf->planestride * buf->n_chan);
1899
13.2k
        }
1900
13.2k
    }
1901
22.9k
    return 0;
1902
22.9k
}
1903
1904
static void pdf14_free_mask_stack(pdf14_ctx *ctx, gs_memory_t *memory)
1905
1.64k
{
1906
1.64k
    pdf14_mask_t *mask_stack = ctx->mask_stack;
1907
1908
1.64k
    if (mask_stack->rc_mask != NULL) {
1909
0
        pdf14_mask_t *curr_mask = mask_stack;
1910
0
        pdf14_mask_t *old_mask;
1911
0
        while (curr_mask != NULL) {
1912
            /* Force to decrement until free */
1913
0
            while (curr_mask->rc_mask != NULL)
1914
0
                rc_decrement(curr_mask->rc_mask, "pdf14_free_mask_stack");
1915
0
            old_mask = curr_mask;
1916
0
            curr_mask = curr_mask->previous;
1917
0
            gs_free_object(old_mask->memory, old_mask, "pdf14_free_mask_stack");
1918
0
        }
1919
1.64k
    } else {
1920
1.64k
        gs_free_object(memory, mask_stack, "pdf14_free_mask_stack");
1921
1.64k
    }
1922
1.64k
    ctx->mask_stack = NULL;
1923
1.64k
}
1924
1925
static  int
1926
pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev)
1927
22.9k
{
1928
22.9k
    pdf14_buf* tos = ctx->stack;
1929
22.9k
    pdf14_buf* nos = tos->saved;
1930
22.9k
    byte *new_data_buf;
1931
22.9k
    int icc_match;
1932
22.9k
    cmm_profile_t *des_profile = nos->group_color_info->icc_profile; /* If set, this should be a gray profile */
1933
22.9k
    cmm_profile_t *src_profile;
1934
22.9k
    gsicc_rendering_param_t rendering_params;
1935
22.9k
    gsicc_link_t *icc_link;
1936
22.9k
    gsicc_rendering_param_t render_cond;
1937
22.9k
    cmm_dev_profile_t *dev_profile;
1938
22.9k
    int code = 0;
1939
1940
22.9k
    dev_proc(dev, get_profile)(dev,  &dev_profile);
1941
22.9k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &src_profile,
1942
22.9k
                          &render_cond);
1943
22.9k
    ctx->smask_depth -= 1;
1944
    /* icc_match == -1 means old non-icc code.
1945
       icc_match == 0 means use icc code
1946
       icc_match == 1 mean no conversion needed */
1947
22.9k
    if (des_profile != NULL && src_profile != NULL ) {
1948
22.9k
        icc_match = gsicc_profiles_equal(des_profile, src_profile);
1949
22.9k
    } else {
1950
0
        icc_match = -1;
1951
0
    }
1952
22.9k
    if_debug1m('v', ctx->memory, "[v]pdf14_pop_transparency_mask, idle=%d\n",
1953
22.9k
               tos->idle);
1954
22.9k
    ctx->stack = tos->saved;
1955
22.9k
    tos->saved = NULL;  /* To avoid issues with GC */
1956
22.9k
    if (tos->mask_stack) {
1957
        /* During the soft mask push, the mask_stack was copied (not moved) from
1958
           the ctx to the tos mask_stack. We are done with this now so it is safe to
1959
           just set to NULL.  However, before we do that we must perform
1960
           rc decrement to match the increment that occured was made.  Also,
1961
           if this is the last ref count of the rc_mask, we should free the
1962
           buffer now since no other groups need it. */
1963
1.64k
        rc_decrement(tos->mask_stack->rc_mask,
1964
1.64k
                     "pdf14_pop_transparency_mask(tos->mask_stack->rc_mask)");
1965
1.64k
        if (tos->mask_stack->rc_mask) {
1966
1.64k
            if (tos->mask_stack->rc_mask->rc.ref_count == 1){
1967
1.64k
                rc_decrement(tos->mask_stack->rc_mask,
1968
1.64k
                            "pdf14_pop_transparency_mask(tos->mask_stack->rc_mask)");
1969
1.64k
            }
1970
1.64k
        }
1971
1.64k
        tos->mask_stack = NULL;
1972
1.64k
    }
1973
22.9k
    if (tos->data == NULL ) {
1974
        /* This can occur in clist rendering if the soft mask does
1975
           not intersect the current band.  It would be nice to
1976
           catch this earlier and just avoid creating the structure
1977
           to begin with.  For now we need to delete the structure
1978
           that was created.  Only delete if the alpha value is 65535 */
1979
9.69k
        if ((tos->alpha == 65535 && tos->is_ident) ||
1980
9.69k
            (!tos->is_ident && (tos->transfer_fn[tos->alpha>>8] == 255))) {
1981
388
            pdf14_buf_free(tos);
1982
388
            if (ctx->mask_stack != NULL) {
1983
0
                pdf14_free_mask_stack(ctx, ctx->memory);
1984
0
            }
1985
9.30k
        } else {
1986
            /* Assign as mask buffer */
1987
9.30k
            if (ctx->mask_stack != NULL) {
1988
795
                pdf14_free_mask_stack(ctx, ctx->memory);
1989
795
            }
1990
9.30k
            ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
1991
9.30k
            ctx->mask_stack->rc_mask = pdf14_rcmask_new(ctx->memory);
1992
9.30k
            ctx->mask_stack->rc_mask->mask_buf = tos;
1993
9.30k
        }
1994
9.69k
        ctx->smask_blend = false;  /* just in case */
1995
13.2k
    } else {
1996
        /* If we are already in the source space then there is no reason
1997
           to do the transformation */
1998
        /* Lets get this to a monochrome buffer and map it to a luminance only value */
1999
        /* This will reduce our memory.  We won't reuse the existing one, due */
2000
        /* Due to the fact that on certain systems we may have issues recovering */
2001
        /* the data after a resize */
2002
13.2k
        new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride + CAL_SLOP,
2003
13.2k
                                        "pdf14_pop_transparency_mask");
2004
13.2k
        if (new_data_buf == NULL)
2005
0
            return_error(gs_error_VMerror);
2006
        /* Initialize with 0.  Need to do this since in Smask_Luminosity_Mapping
2007
           we won't be filling everything during the remap if it had not been
2008
           written into by the PDF14 fill rect */
2009
13.2k
        memset(new_data_buf, 0, tos->planestride);
2010
        /* If the subtype was alpha, then just grab the alpha channel now
2011
           and we are all done */
2012
13.2k
        if (tos->SMask_SubType == TRANSPARENCY_MASK_Alpha) {
2013
14
            ctx->smask_blend = false;  /* not used in this case */
2014
14
            smask_copy(tos->rect.q.y - tos->rect.p.y,
2015
14
                       (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2016
14
                       tos->rowstride,
2017
14
                       (tos->data)+tos->planestride, new_data_buf);
2018
#if RAW_DUMP
2019
            /* Dump the current buffer to see what we have. */
2020
            dump_raw_buffer(ctx->memory,
2021
                            tos->rect.q.y-tos->rect.p.y,
2022
                            tos->rowstride>>tos->deep, tos->n_planes,
2023
                            tos->planestride, tos->rowstride,
2024
                            "SMask_Pop_Alpha(Mask_Plane1)",tos->data,
2025
                            tos->deep);
2026
            global_index++;
2027
#endif
2028
13.2k
        } else {
2029
13.2k
            if (icc_match == 1 || tos->n_chan == 2) {
2030
#if RAW_DUMP
2031
                /* Dump the current buffer to see what we have. */
2032
                dump_raw_buffer(ctx->memory,
2033
                                tos->rect.q.y-tos->rect.p.y,
2034
                                tos->rowstride>>tos->deep, tos->n_planes,
2035
                                tos->planestride, tos->rowstride,
2036
                                "SMask_Pop_Lum(Mask_Plane0)",tos->data,
2037
                                tos->deep);
2038
                global_index++;
2039
#endif
2040
                /* There is no need to color convert.  Data is already gray scale.
2041
                   We just need to copy the gray plane.  However it is
2042
                   possible that the soft mask could have a soft mask which
2043
                   would end us up with some alpha blending information
2044
                   (Bug691803). In fact, according to the spec, the alpha
2045
                   blending has to occur.  See FTS test fts_26_2601.pdf
2046
                   for an example of this.  Softmask buffer is intialized
2047
                   with BG values.  It would be nice to keep track if buffer
2048
                   ever has a alpha value not 1 so that we could detect and
2049
                   avoid this blend if not needed. */
2050
13.2k
                smask_blend(tos->data, tos->rect.q.x - tos->rect.p.x,
2051
13.2k
                            tos->rect.q.y - tos->rect.p.y, tos->rowstride,
2052
13.2k
                            tos->planestride, tos->deep);
2053
#if RAW_DUMP
2054
                /* Dump the current buffer to see what we have. */
2055
                dump_raw_buffer(ctx->memory,
2056
                                tos->rect.q.y-tos->rect.p.y,
2057
                                tos->rowstride>>tos->deep, tos->n_planes,
2058
                                tos->planestride, tos->rowstride,
2059
                                "SMask_Pop_Lum_Post_Blend",tos->data,
2060
                                tos->deep);
2061
                global_index++;
2062
#endif
2063
13.2k
                smask_copy(tos->rect.q.y - tos->rect.p.y,
2064
13.2k
                           (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2065
13.2k
                           tos->rowstride, tos->data, new_data_buf);
2066
13.2k
            } else {
2067
0
                if ( icc_match == -1 ) {
2068
                    /* The slow old fashioned way */
2069
0
                    smask_luminosity_mapping(tos->rect.q.y - tos->rect.p.y ,
2070
0
                        tos->rect.q.x - tos->rect.p.x,tos->n_chan,
2071
0
                        tos->rowstride, tos->planestride,
2072
0
                        tos->data,  new_data_buf, ctx->additive, tos->SMask_SubType,
2073
0
                        tos->deep
2074
#if RAW_DUMP
2075
                        , ctx->memory
2076
#endif
2077
0
                        );
2078
0
                } else {
2079
                    /* ICC case where we use the CMM */
2080
                    /* Request the ICC link for the transform that we will need to use */
2081
0
                    rendering_params.black_point_comp = gsBLACKPTCOMP_OFF;
2082
0
                    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
2083
0
                    rendering_params.override_icc = false;
2084
0
                    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
2085
0
                    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;
2086
0
                    rendering_params.cmm = gsCMM_DEFAULT;
2087
0
                    icc_link = gsicc_get_link_profile(pgs, dev, des_profile,
2088
0
                        src_profile, &rendering_params, pgs->memory, false);
2089
0
                    code = smask_icc(dev, tos->rect.q.y - tos->rect.p.y,
2090
0
                              tos->rect.q.x - tos->rect.p.x, tos->n_chan,
2091
0
                              tos->rowstride, tos->planestride,
2092
0
                              tos->data, new_data_buf, icc_link, tos->deep);
2093
                    /* Release the link */
2094
0
                    gsicc_release_link(icc_link);
2095
0
                }
2096
0
            }
2097
13.2k
        }
2098
        /* Free the old object, NULL test was above */
2099
13.2k
        gs_free_object(ctx->memory, tos->data, "pdf14_pop_transparency_mask");
2100
13.2k
        tos->data = new_data_buf;
2101
        /* Data is single channel now */
2102
13.2k
        tos->n_chan = 1;
2103
13.2k
        tos->n_planes = 1;
2104
        /* Assign as reference counted mask buffer */
2105
13.2k
        if (ctx->mask_stack != NULL) {
2106
            /* In this case, the source file is wacky as it already had a
2107
               softmask and now is getting a replacement. We need to clean
2108
               up the softmask stack before doing this free and creating
2109
               a new stack. Bug 693312 */
2110
852
            pdf14_free_mask_stack(ctx, ctx->memory);
2111
852
        }
2112
13.2k
        ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2113
13.2k
        if (ctx->mask_stack == NULL)
2114
0
            return gs_note_error(gs_error_VMerror);
2115
13.2k
        ctx->mask_stack->rc_mask = pdf14_rcmask_new(ctx->memory);
2116
13.2k
        if (ctx->mask_stack->rc_mask == NULL)
2117
0
            return gs_note_error(gs_error_VMerror);
2118
13.2k
        ctx->mask_stack->rc_mask->mask_buf = tos;
2119
13.2k
    }
2120
22.9k
    return code;
2121
22.9k
}
2122
2123
static pdf14_mask_t *
2124
pdf14_mask_element_new(gs_memory_t *memory)
2125
67.2k
{
2126
67.2k
    pdf14_mask_t *result;
2127
2128
67.2k
    result = gs_alloc_struct(memory, pdf14_mask_t, &st_pdf14_mask,
2129
67.2k
                             "pdf14_mask_element_new");
2130
67.2k
    if (result == NULL)
2131
0
        return NULL;
2132
    /* Get the reference counted mask */
2133
67.2k
    result->rc_mask = NULL;
2134
67.2k
    result->previous = NULL;
2135
67.2k
    result->memory = memory;
2136
67.2k
    return result;
2137
67.2k
}
2138
2139
static int
2140
pdf14_push_transparency_state(gx_device *dev, gs_gstate *pgs)
2141
0
{
2142
    /* We need to push the current soft mask.  We need to
2143
       be able to recover it if we draw a new one and
2144
       then obtain a Q operation ( a pop ) */
2145
2146
0
    pdf14_device *pdev = (pdf14_device *)dev;
2147
0
    pdf14_ctx *ctx = pdev->ctx;
2148
0
    pdf14_mask_t *new_mask;
2149
2150
0
    if_debug0m('v', ctx->memory, "pdf14_push_transparency_state\n");
2151
    /* We need to push the current mask buffer   */
2152
    /* Allocate a new element for the stack.
2153
       Don't do anything if there is no mask present.*/
2154
0
    if (ctx->mask_stack != NULL) {
2155
0
        new_mask = pdf14_mask_element_new(ctx->memory);
2156
        /* Duplicate and make the link */
2157
0
        new_mask->rc_mask = ctx->mask_stack->rc_mask;
2158
0
        rc_increment(new_mask->rc_mask);
2159
0
        new_mask->previous = ctx->mask_stack;
2160
0
        ctx->mask_stack = new_mask;
2161
0
    }
2162
#ifdef DEBUG
2163
    pdf14_debug_mask_stack_state(pdev->ctx);
2164
#endif
2165
0
    return 0;
2166
0
}
2167
2168
static int
2169
pdf14_pop_transparency_state(gx_device *dev, gs_gstate *pgs)
2170
267k
{
2171
    /* Pop the soft mask.  It is no longer needed. Likely due to
2172
       a Q that has occurred. */
2173
267k
    pdf14_device *pdev = (pdf14_device *)dev;
2174
267k
    pdf14_ctx *ctx = pdev->ctx;
2175
267k
    pdf14_mask_t *old_mask;
2176
2177
267k
    if_debug0m('v', ctx->memory, "pdf14_pop_transparency_state\n");
2178
    /* rc decrement the current link after we break it from
2179
       the list, then free the stack element.  Don't do
2180
       anything if there is no mask present. */
2181
267k
    if (ctx->mask_stack != NULL) {
2182
32.3k
        old_mask = ctx->mask_stack;
2183
32.3k
        ctx->mask_stack = ctx->mask_stack->previous;
2184
32.3k
        if (old_mask->rc_mask) {
2185
32.3k
            rc_decrement(old_mask->rc_mask, "pdf14_pop_transparency_state");
2186
32.3k
        }
2187
32.3k
        gs_free_object(old_mask->memory, old_mask, "pdf14_pop_transparency_state");
2188
        /* We need to have some special handling here for when we have nested
2189
           soft masks.  There may be a copy in the stack that we may need to
2190
           adjust. */
2191
32.3k
        if (ctx->smask_depth > 0) {
2192
11
            if (ctx->stack != NULL && ctx->stack->mask_stack != NULL) {
2193
0
                ctx->stack->mask_stack = ctx->mask_stack;
2194
0
            }
2195
11
        }
2196
32.3k
    }
2197
#ifdef DEBUG
2198
    pdf14_debug_mask_stack_state(pdev->ctx);
2199
#endif
2200
267k
    return 0;
2201
267k
}
2202
2203
static  int
2204
pdf14_open(gx_device *dev)
2205
44.6k
{
2206
44.6k
    pdf14_device *pdev = (pdf14_device *)dev;
2207
2208
    /* If we are reenabling the device dont create a new ctx. Bug 697456 */
2209
44.6k
    if (pdev->ctx == NULL) {
2210
44.6k
        bool has_tags = device_encodes_tags(dev);
2211
44.6k
        int bits_per_comp = ((dev->color_info.depth - has_tags*8) /
2212
44.6k
                             dev->color_info.num_components);
2213
44.6k
        pdev->ctx = pdf14_ctx_new(dev, bits_per_comp > 8);
2214
44.6k
        if (pdev->ctx == NULL)
2215
0
            return_error(gs_error_VMerror);
2216
2217
44.6k
        pdev->ctx->rect.p.x = 0;
2218
44.6k
        pdev->ctx->rect.p.y = 0;
2219
44.6k
        pdev->ctx->rect.q.x = dev->width;
2220
44.6k
        pdev->ctx->rect.q.y = dev->height;
2221
44.6k
        pdev->ctx->has_tags = has_tags;
2222
44.6k
        pdev->ctx->num_spots = pdev->color_info.num_components - pdev->num_std_colorants;
2223
44.6k
        pdev->ctx->additive = (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE);
2224
44.6k
        pdev->ctx->n_chan = pdev->color_info.num_components;
2225
44.6k
    }
2226
44.6k
    pdev->free_devicen = true;
2227
44.6k
    pdev->text_group = PDF14_TEXTGROUP_NO_BT;
2228
44.6k
    return 0;
2229
44.6k
}
2230
2231
static const gx_cm_color_map_procs pdf14_DeviceCMYKspot_procs = {
2232
    pdf14_gray_cs_to_cmyk_cm, pdf14_rgb_cs_to_cmyk_cm, pdf14_cmyk_cs_to_cmyk_cm
2233
};
2234
2235
static const gx_cm_color_map_procs pdf14_DeviceRGBspot_procs = {
2236
    pdf14_gray_cs_to_rgbspot_cm, pdf14_rgb_cs_to_rgbspot_cm, pdf14_cmyk_cs_to_rgbspot_cm
2237
};
2238
2239
static const gx_cm_color_map_procs pdf14_DeviceGrayspot_procs = {
2240
    pdf14_gray_cs_to_grayspot_cm, pdf14_rgb_cs_to_grayspot_cm, pdf14_cmyk_cs_to_grayspot_cm
2241
};
2242
2243
static const gx_cm_color_map_procs *
2244
pdf14_cmykspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2245
0
{
2246
0
    *tdev = dev;
2247
0
    return &pdf14_DeviceCMYKspot_procs;
2248
0
}
2249
2250
static const gx_cm_color_map_procs *
2251
pdf14_rgbspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2252
0
{
2253
0
    *tdev = dev;
2254
0
    return &pdf14_DeviceRGBspot_procs;
2255
0
}
2256
2257
static const gx_cm_color_map_procs *
2258
pdf14_grayspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2259
0
{
2260
0
    *tdev = dev;
2261
0
    return &pdf14_DeviceGrayspot_procs;
2262
0
}
2263
2264
static void
2265
be_rev_cpy(uint16_t *dst,const uint16_t *src,int n)
2266
0
{
2267
0
    for (; n != 0; n--) {
2268
0
        uint16_t in = *src++;
2269
0
        ((byte *)dst)[0] = in>>8;
2270
0
        ((byte *)dst)[1] = in;
2271
0
        dst++;
2272
0
    }
2273
0
}
2274
2275
/* Used to pass along information about the buffer created by the
2276
   pdf14 device.  This is used by the pattern accumulator when the
2277
   pattern contains transparency.  Note that if free_device is true then
2278
   we need to go ahead and get the buffer data copied and free up the
2279
   device.  This only occurs at the end of a pattern accumulation operation */
2280
int
2281
pdf14_get_buffer_information(const gx_device * dev,
2282
                             gx_pattern_trans_t *transbuff, gs_memory_t *mem,
2283
                             bool free_device)
2284
2.30k
{
2285
2.30k
    const pdf14_device * pdev = (pdf14_device *)dev;
2286
2.30k
    pdf14_buf *buf;
2287
2.30k
    gs_int_rect rect;
2288
2.30k
    int x1,y1,width,height;
2289
2290
2.30k
    if ( pdev->ctx == NULL){
2291
0
        return 0;  /* this can occur if the pattern is a clist */
2292
0
    }
2293
#ifdef DEBUG
2294
    pdf14_debug_mask_stack_state(pdev->ctx);
2295
#endif
2296
2.30k
    buf = pdev->ctx->stack;
2297
2.30k
    rect = buf->rect;
2298
2.30k
    transbuff->buf = (free_device ? NULL : buf);
2299
2.30k
    x1 = min(pdev->width, rect.q.x);
2300
2.30k
    y1 = min(pdev->height, rect.q.y);
2301
2.30k
    width = x1 - rect.p.x;
2302
2.30k
    height = y1 - rect.p.y;
2303
2304
2.30k
    transbuff->n_chan    = buf->n_chan;
2305
2.30k
    transbuff->has_tags  = buf->has_tags;
2306
2.30k
    transbuff->has_shape = buf->has_shape;
2307
2.30k
    transbuff->width     = buf->rect.q.x - buf->rect.p.x;
2308
2.30k
    transbuff->height    = buf->rect.q.y - buf->rect.p.y;
2309
2.30k
    transbuff->deep      = buf->deep;
2310
2311
2.30k
    if (width <= 0 || height <= 0 || buf->data == NULL) {
2312
114
        transbuff->planestride = 0;
2313
114
        transbuff->rowstride = 0;
2314
114
        return 0;
2315
114
    }
2316
2317
2.19k
    if (free_device) {
2318
702
        transbuff->pdev14 = NULL;
2319
702
        transbuff->rect = rect;
2320
702
        if ((width < transbuff->width) || (height < transbuff->height)) {
2321
            /* If the bbox is smaller than the whole buffer than go ahead and
2322
               create a new one to use.  This can occur if we drew in a smaller
2323
               area than was specified by the transparency group rect. */
2324
0
            int rowstride = ((width + 3) & -4)<<buf->deep;
2325
0
            int planestride = rowstride * height;
2326
0
            int k, j;
2327
0
            byte *buff_ptr_src, *buff_ptr_des;
2328
2329
0
            transbuff->planestride = planestride;
2330
0
            transbuff->rowstride = rowstride;
2331
0
            transbuff->transbytes =
2332
0
                         gs_alloc_bytes(mem,
2333
0
                                        (size_t)planestride *
2334
0
                                                (buf->n_chan +
2335
0
                                                 buf->has_tags ? 1 : 0) + CAL_SLOP,
2336
0
                                        "pdf14_get_buffer_information");
2337
0
            if (transbuff->transbytes == NULL)
2338
0
                return gs_error_VMerror;
2339
2340
0
            transbuff->mem = mem;
2341
0
            if (transbuff->deep) {
2342
0
                for (j = 0; j < transbuff->n_chan; j++) {
2343
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2344
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2345
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2346
0
                    for (k = 0; k < height; k++) {
2347
0
                        be_rev_cpy((uint16_t *)buff_ptr_des, (const uint16_t *)buff_ptr_src, rowstride>>1);
2348
0
                        buff_ptr_des += rowstride;
2349
0
                        buff_ptr_src += buf->rowstride;
2350
0
                    }
2351
0
                }
2352
0
            } else {
2353
0
                for (j = 0; j < transbuff->n_chan; j++) {
2354
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2355
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2356
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2357
0
                    for (k = 0; k < height; k++) {
2358
0
                        memcpy(buff_ptr_des, buff_ptr_src, rowstride);
2359
0
                        buff_ptr_des += rowstride;
2360
0
                        buff_ptr_src += buf->rowstride;
2361
0
                    }
2362
0
                }
2363
0
            }
2364
2365
702
        } else {
2366
            /* The entire buffer is used.  Go ahead and grab the pointer and
2367
               clear the pointer in the pdf14 device data buffer so it is not
2368
               freed when we close the device */
2369
702
            transbuff->planestride = buf->planestride;
2370
702
            transbuff->rowstride = buf->rowstride;
2371
702
            transbuff->transbytes = buf->data;
2372
702
            transbuff->mem = buf->memory;
2373
702
            buf->data = NULL;  /* So that the buffer is not freed */
2374
702
            if (transbuff->deep) {
2375
                /* We have the data in native endian. We need it in big endian. Do an in-place conversion. */
2376
                /* FIXME: This is a nop on big endian machines. Is the compiler smart enough to spot that? */
2377
0
                uint16_t *buff_ptr;
2378
0
                int j, k, z;
2379
0
                int rowstride = transbuff->rowstride>>1;
2380
0
                int planestride = transbuff->planestride;
2381
0
                for (j = 0; j < transbuff->n_chan; j++) {
2382
0
                    buff_ptr = (uint16_t *)(transbuff->transbytes + j * planestride);
2383
0
                    for (k = 0; k < height; k++) {
2384
0
                        for (z = 0; z < width; z++) {
2385
0
                            uint16_t in = buff_ptr[z];
2386
0
                            ((byte *)(&buff_ptr[z]))[0] = in>>8;
2387
0
                            ((byte *)(&buff_ptr[z]))[1] = in;
2388
0
                        }
2389
0
                        buff_ptr += rowstride;
2390
0
                    }
2391
0
                }
2392
0
            }
2393
702
        }
2394
#if RAW_DUMP
2395
        /* Dump the buffer that should be going into the pattern */;
2396
        dump_raw_buffer_be(buf->memory,
2397
                           height, width, transbuff->n_chan,
2398
                           transbuff->planestride, transbuff->rowstride,
2399
                           "pdf14_pattern_buff", transbuff->transbytes,
2400
                           transbuff->deep);
2401
        global_index++;
2402
#endif
2403
        /* Go ahead and free up the pdf14 device */
2404
702
        dev_proc(dev, close_device)((gx_device *)dev);
2405
1.49k
    } else {
2406
        /* Here we are coming from one of the fill image / pattern / mask
2407
           operations */
2408
1.49k
        transbuff->pdev14 = dev;
2409
1.49k
        transbuff->planestride = buf->planestride;
2410
1.49k
        transbuff->rowstride = buf->rowstride;
2411
1.49k
        transbuff->transbytes = buf->data;
2412
1.49k
        transbuff->mem = buf->memory;
2413
1.49k
        transbuff->rect = rect;
2414
#if RAW_DUMP
2415
    /* Dump the buffer that should be going into the pattern */;
2416
        dump_raw_buffer(buf->memory,
2417
                        height, width, buf->n_chan,
2418
                        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2419
                        "pdf14_pattern_buff",
2420
                        buf->data,
2421
                        transbuff->deep);
2422
        global_index++;
2423
#endif
2424
1.49k
    }
2425
2.19k
    return 0;
2426
2.19k
}
2427
2428
typedef void(*blend_image_row_proc_t) (const byte *gs_restrict buf_ptr,
2429
    int planestride, int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf);
2430
2431
2432
static int
2433
pdf14_put_image_color_convert(const pdf14_device* dev, gs_gstate* pgs, cmm_profile_t* src_profile,
2434
                        cmm_dev_profile_t* dev_target_profile, pdf14_buf** buf,
2435
                        byte** buf_ptr, bool was_blended, int x, int y, int width, int height)
2436
0
{
2437
0
    pdf14_buf* cm_result = NULL;
2438
0
    cmm_profile_t* des_profile;
2439
0
    gsicc_rendering_param_t render_cond;
2440
0
    bool did_alloc;
2441
0
    bool endian_swap;
2442
2443
0
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_target_profile, &des_profile,
2444
0
        &render_cond);
2445
2446
#if RAW_DUMP
2447
    dump_raw_buffer(dev->ctx->memory,
2448
        height, width, (*buf)->n_planes, (*buf)->planestride,
2449
        (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2450
    global_index++;
2451
#endif
2452
2453
    /* If we are doing a 16 bit buffer it will be big endian if we have already done the
2454
       blend, otherwise it will be native endian. GS expects its 16bit buffers to be BE
2455
       but for sanity pdf14 device maintains 16bit buffers in native format.  The CMM
2456
       will need to know if it is dealing with native or BE data. */
2457
0
    if (was_blended && (*buf)->deep) {
2458
        /* Data is in BE.  If we are in a LE machine, CMM will need to swap for
2459
           color conversion */
2460
#if ARCH_IS_BIG_ENDIAN
2461
        endian_swap = false;
2462
#else
2463
0
        endian_swap = true;
2464
0
#endif
2465
0
    } else {
2466
        /* Data is in native format. No swap needed for CMM */
2467
0
        endian_swap = false;
2468
0
    }
2469
2470
0
    cm_result = pdf14_transform_color_buffer_no_matte(pgs, dev->ctx, (gx_device*) dev, *buf,
2471
0
        *buf_ptr, src_profile, des_profile, x, y, width,
2472
0
        height, &did_alloc, (*buf)->deep, endian_swap);
2473
2474
0
    if (cm_result == NULL)
2475
0
        return_error(gs_error_VMerror);
2476
2477
    /* Update */
2478
0
    *buf = cm_result;
2479
2480
    /* Make sure our buf_ptr is pointing to the proper location */
2481
0
    if (did_alloc)
2482
0
        *buf_ptr = cm_result->data;  /* Note the lack of offset */
2483
2484
#if RAW_DUMP
2485
    dump_raw_buffer(dev->ctx->memory,
2486
        height, width, (*buf)->n_planes, (*buf)->planestride,
2487
        (*buf)->rowstride, "pdf14_put_image_color_convert_post", *buf_ptr, (*buf)->deep);
2488
    global_index++;
2489
#endif
2490
0
    return 0;
2491
0
}
2492
2493
/**
2494
 * pdf14_put_image: Put rendered image to target device.
2495
 * @pdev: The PDF 1.4 rendering device.
2496
 * @pgs: State for image draw operation.
2497
 * @target: The target device.
2498
 *
2499
 * Puts the rendered image in @pdev's buffer to @target. This is called
2500
 * as part of the sequence of popping the PDF 1.4 device filter.
2501
 *
2502
 * Return code: negative on error.
2503
 **/
2504
static  int
2505
pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
2506
43.9k
{
2507
43.9k
    const pdf14_device * pdev = (pdf14_device *)dev;
2508
43.9k
    int code;
2509
43.9k
    gs_image1_t image;
2510
43.9k
    gx_image_enum_common_t *info;
2511
43.9k
    pdf14_buf *buf = pdev->ctx->stack;
2512
43.9k
    gs_int_rect rect;
2513
43.9k
    int y;
2514
43.9k
    int num_comp;
2515
43.9k
    byte *linebuf, *linebuf_unaligned;
2516
43.9k
    gs_color_space *pcs;
2517
43.9k
    int x1, y1, width, height;
2518
43.9k
    byte *buf_ptr;
2519
43.9k
    int num_rows_left;
2520
43.9k
    cmm_profile_t* src_profile = NULL;
2521
43.9k
    cmm_profile_t* des_profile = NULL;
2522
43.9k
    cmm_dev_profile_t *pdf14dev_profile;
2523
43.9k
    cmm_dev_profile_t *dev_target_profile;
2524
43.9k
    uint16_t bg;
2525
43.9k
    bool has_tags = device_encodes_tags(dev);
2526
43.9k
    bool deep = pdev->ctx->deep;
2527
43.9k
    int planestride;
2528
43.9k
    int rowstride;
2529
43.9k
    blend_image_row_proc_t blend_row;
2530
43.9k
    bool color_mismatch = false;
2531
43.9k
    bool supports_alpha = false;
2532
43.9k
    int i;
2533
43.9k
    int alpha_offset, tag_offset;
2534
43.9k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
2535
43.9k
    int rendering_intent_saved;
2536
2537
    /* Nothing was ever drawn. */
2538
43.9k
    if (buf == NULL)
2539
2.14k
        return 0;
2540
2541
41.8k
    bg = buf->group_color_info->isadditive ? 65535 : 0;
2542
41.8k
    src_profile = buf->group_color_info->icc_profile;
2543
2544
41.8k
    num_comp = buf->n_chan - 1;
2545
41.8k
    rect = buf->rect;
2546
41.8k
    planestride = buf->planestride;
2547
41.8k
    rowstride = buf->rowstride;
2548
2549
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
2550
       potential problem. Bug 694190 */
2551
41.8k
    if (buf->saved != NULL) {
2552
1
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
2553
1
    }
2554
41.8k
    if_debug0m('v', dev->memory, "[v]pdf14_put_image\n");
2555
41.8k
    rect_intersect(rect, buf->dirty);
2556
41.8k
    x1 = min(pdev->width, rect.q.x);
2557
41.8k
    y1 = min(pdev->height, rect.q.y);
2558
41.8k
    width = x1 - rect.p.x;
2559
41.8k
    height = y1 - rect.p.y;
2560
#ifdef DUMP_TO_PNG
2561
    dump_planar_rgba(pdev->memory, buf);
2562
#endif
2563
41.8k
    if (width <= 0 || height <= 0 || buf->data == NULL)
2564
6.19k
        return 0;
2565
35.6k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
2566
2567
    /* Check that target is OK.  From fuzzing results the target could have been
2568
       destroyed, for e.g if it were a pattern accumulator that was closed
2569
       prematurely (Bug 694154).  We should always be able to to get an ICC
2570
       profile from the target. */
2571
35.6k
    code = dev_proc(target, get_profile)(target,  &dev_target_profile);
2572
35.6k
    if (code < 0)
2573
0
        return code;
2574
35.6k
    if (dev_target_profile == NULL)
2575
0
        return gs_throw_code(gs_error_Fatal);
2576
2577
35.6k
    if (src_profile == NULL) {
2578
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
2579
0
        if (code < 0) {
2580
0
            return code;
2581
0
        }
2582
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2583
0
    }
2584
2585
    /* Check if we have a color conversion issue */
2586
35.6k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2587
35.6k
    if (!gsicc_profiles_equal(des_profile, src_profile))
2588
2.13k
        color_mismatch = true;
2589
2590
    /* Check if target supports alpha */
2591
35.6k
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
2592
35.6k
    code = 0;
2593
2594
#if RAW_DUMP
2595
    dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2596
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2597
        "pre_final_blend", buf_ptr, deep);
2598
#endif
2599
2600
    /* Note. The logic below will need a little rework if we ever
2601
       have a device that has tags and alpha support */
2602
35.6k
    if (supports_alpha) {
2603
0
        if (!color_mismatch) {
2604
0
            alpha_offset = num_comp;
2605
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2606
2607
0
            for (i = 0; i < buf->n_planes; i++)
2608
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2609
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2610
0
                rect.p.x, rect.p.y, width, height,
2611
0
                rowstride, alpha_offset,
2612
0
                tag_offset);
2613
            /* Right now code has number of rows written */
2614
0
        } else {
2615
            /* In this case, just color convert and maintain alpha.  This is a case
2616
               where we either either blend in the right color space and have no
2617
               alpha for the output device or hand back the wrong color space with
2618
               alpha data.  We choose the later. */
2619
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
2620
0
                dev_target_profile, &buf, &buf_ptr, false, rect.p.x, rect.p.y,
2621
0
                width, height);
2622
0
            if (code < 0)
2623
0
                return code;
2624
2625
            /* reset */
2626
0
            rowstride = buf->rowstride;
2627
0
            planestride = buf->planestride;
2628
0
            num_comp = buf->n_chan - 1;
2629
0
            alpha_offset = num_comp;
2630
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2631
2632
            /* And then out */
2633
0
            for (i = 0; i < buf->n_planes; i++)
2634
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2635
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2636
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2637
0
                tag_offset);
2638
            /* Right now code has number of rows written */
2639
0
        }
2640
35.6k
    } else if (has_tags) {
2641
        /* We are going out to a device that supports tags */
2642
0
        if (deep) {
2643
0
            gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
2644
0
                buf->planestride, num_comp, bg, false);
2645
0
        } else {
2646
0
            gx_blend_image_buffer(buf_ptr, width, height, rowstride,
2647
0
                buf->planestride, num_comp, bg >> 8);
2648
0
        }
2649
2650
#if RAW_DUMP
2651
        dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2652
            pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2653
            "post_final_blend", buf_ptr, deep);
2654
#endif
2655
2656
        /* Take care of color issues */
2657
0
        if (color_mismatch) {
2658
            /* In this case, just color convert and maintain alpha.  This is a case
2659
               where we either either blend in the right color space and have no
2660
               alpha for the output device or hand back the wrong color space with
2661
               alpha data.  We choose the later. */
2662
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
2663
0
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height);
2664
0
            if (code < 0)
2665
0
                return code;
2666
2667
#if RAW_DUMP
2668
            dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2669
                pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2670
                "final_color_manage", buf_ptr, deep);
2671
            global_index++;
2672
#endif
2673
0
        }
2674
2675
        /* reset */
2676
0
        rowstride = buf->rowstride;
2677
0
        planestride = buf->planestride;
2678
0
        num_comp = buf->n_chan - 1;
2679
0
        alpha_offset = 0;  /* It is there but this indicates we have done the blend */
2680
0
        tag_offset = buf->has_tags ? buf->n_chan : 0;
2681
2682
        /* And then out */
2683
0
        for (i = 0; i < buf->n_planes; i++)
2684
0
            buf_ptrs[i] = buf_ptr + i * planestride;
2685
0
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2686
0
            rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2687
0
            tag_offset);
2688
        /* Right now code has number of rows written */
2689
2690
0
    }
2691
2692
    /* If code > 0 then put image worked.  Let it finish and then exit */
2693
35.6k
    if (code > 0) {
2694
        /* We processed some or all of the rows.  Continue until we are done */
2695
0
        num_rows_left = height - code;
2696
0
        while (num_rows_left > 0) {
2697
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2698
0
                                                rect.p.x, rect.p.y + code, width,
2699
0
                                                num_rows_left, rowstride,
2700
0
                                                alpha_offset, tag_offset);
2701
0
            num_rows_left = num_rows_left - code;
2702
0
        }
2703
0
        return 0;
2704
0
    }
2705
2706
    /* Target device did not support alpha or tags.
2707
     * Set color space in preparation for sending an image.
2708
     * color conversion will occur after blending with through
2709
     * the begin typed image work flow.
2710
     */
2711
2712
35.6k
    planestride = buf->planestride;
2713
35.6k
    rowstride = buf->rowstride;
2714
35.6k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
2715
35.6k
    if (code < 0)
2716
0
        return code;
2717
    /* Need to set this to avoid color management during the image color render
2718
       operation.  Exception is for the special case when the destination was
2719
       CIELAB.  Then we need to convert from default RGB to CIELAB in the put
2720
       image operation.  That will happen here as we should have set the profile
2721
       for the pdf14 device to RGB and the target will be CIELAB.  In addition,
2722
       the case when we have a blend color space that is different than the
2723
       target device color space */
2724
35.6k
    pcs->cmm_icc_profile_data = src_profile;
2725
2726
    /* pcs takes a reference to the profile data it just retrieved. */
2727
35.6k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_image");
2728
35.6k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
2729
35.6k
    gs_image_t_init_adjust(&image, pcs, false);
2730
35.6k
    image.ImageMatrix.xx = (float)width;
2731
35.6k
    image.ImageMatrix.yy = (float)height;
2732
35.6k
    image.Width = width;
2733
35.6k
    image.Height = height;
2734
35.6k
    image.BitsPerComponent = deep ? 16 : 8;
2735
35.6k
    image.ColorSpace = pcs;
2736
35.6k
    ctm_only_writable(pgs).xx = (float)width;
2737
35.6k
    ctm_only_writable(pgs).xy = 0;
2738
35.6k
    ctm_only_writable(pgs).yx = 0;
2739
35.6k
    ctm_only_writable(pgs).yy = (float)height;
2740
35.6k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
2741
35.6k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
2742
    /* Make sure that the relative colorimetric rendering intent is
2743
       used for this image. */
2744
35.6k
    rendering_intent_saved = pgs->renderingintent;
2745
35.6k
    pgs->renderingintent = gsRELATIVECOLORIMETRIC;
2746
35.6k
    code = dev_proc(target, begin_typed_image) (target,
2747
35.6k
                                                pgs, NULL,
2748
35.6k
                                                (gs_image_common_t *)&image,
2749
35.6k
                                                NULL, NULL, NULL,
2750
35.6k
                                                pgs->memory, &info);
2751
35.6k
    pgs->renderingintent = rendering_intent_saved;
2752
35.6k
    if (code < 0) {
2753
0
        rc_decrement_only_cs(pcs, "pdf14_put_image");
2754
0
        return code;
2755
0
    }
2756
#if RAW_DUMP
2757
    /* Dump the current buffer to see what we have. */
2758
    dump_raw_buffer(pdev->ctx->memory,
2759
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
2760
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
2761
                    pdev->ctx->stack->n_planes,
2762
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2763
                    "pdF14_putimage", pdev->ctx->stack->data, deep);
2764
    dump_raw_buffer(pdev->ctx->memory,
2765
                    height, width, buf->n_planes,
2766
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2767
                    "PDF14_PUTIMAGE_SMALL", buf_ptr, deep);
2768
    global_index++;
2769
    clist_band_count++;
2770
#endif
2771
    /* Allocate on 32-byte border for AVX CMYK case. Four byte overflow for RGB case */
2772
    /* 28 byte overflow for AVX CMYK case. */
2773
35.6k
#define SSE_ALIGN 32
2774
35.6k
#define SSE_OVERFLOW 28
2775
35.6k
    linebuf_unaligned = gs_alloc_bytes(pdev->memory, width * (num_comp<<deep) + SSE_ALIGN + SSE_OVERFLOW, "pdf14_put_image");
2776
35.6k
    if (linebuf_unaligned == NULL)
2777
0
        return gs_error_VMerror;
2778
35.6k
    linebuf = linebuf_unaligned + ((-(intptr_t)linebuf_unaligned) & (SSE_ALIGN-1));
2779
2780
35.6k
    blend_row = deep ? gx_build_blended_image_row16 :
2781
35.6k
                       gx_build_blended_image_row;
2782
#ifdef WITH_CAL
2783
    blend_row = cal_get_blend_row(pdev->memory->gs_lib_ctx->core->cal_ctx,
2784
                                  blend_row, num_comp, deep);
2785
#endif
2786
2787
35.6k
    if (!deep)
2788
35.6k
        bg >>= 8;
2789
439k
    for (y = 0; y < height; y++) {
2790
403k
        gx_image_plane_t planes;
2791
403k
        int rows_used;
2792
2793
403k
        blend_row(buf_ptr, buf->planestride, width, num_comp, bg, linebuf);
2794
403k
        planes.data = linebuf;
2795
403k
        planes.data_x = 0;
2796
403k
        planes.raster = width * num_comp;
2797
403k
        info->procs->plane_data(info, &planes, 1, &rows_used);
2798
        /* todo: check return value */
2799
403k
        buf_ptr += buf->rowstride;
2800
403k
    }
2801
35.6k
    gs_free_object(pdev->memory, linebuf_unaligned, "pdf14_put_image");
2802
35.6k
    info->procs->end_image(info, true);
2803
    /* This will also decrement the device profile */
2804
35.6k
    rc_decrement_only_cs(pcs, "pdf14_put_image");
2805
35.6k
    return code;
2806
35.6k
}
2807
2808
/* Overprint simulation with spots.  Collapse to CMYK */
2809
static void
2810
template_spots_to_cmyk(byte *buf_ptr, int width, int height, int rowstride,
2811
    int planestride, int num_comp, int spot_start, int tag_offset,
2812
    cmyk_composite_map *map, bool keep_alpha)
2813
0
{
2814
0
    int comp_num;
2815
0
    uint cyan, magenta, yellow, black;
2816
0
    cmyk_composite_map *cmyk_map_entry;
2817
0
    int x, y;
2818
0
    int position;
2819
0
    byte comp, a;
2820
2821
0
    for (y = 0; y < height; y++) {
2822
0
        position = y * rowstride;
2823
0
        for (x = 0; x < width; x++) {
2824
0
            a = buf_ptr[position + planestride * num_comp];
2825
0
            if (a != 0) {
2826
0
                cyan = buf_ptr[position] * frac_1;
2827
0
                magenta = buf_ptr[position + planestride] * frac_1;
2828
0
                yellow = buf_ptr[position + planestride * 2] * frac_1;
2829
0
                black = buf_ptr[position + planestride * 3] * frac_1;
2830
0
                cmyk_map_entry = &(map[4]);
2831
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2832
0
                    comp = buf_ptr[position + planestride * comp_num];
2833
0
                    cyan += cmyk_map_entry->c * comp;
2834
0
                    magenta += cmyk_map_entry->m * comp;
2835
0
                    yellow += cmyk_map_entry->y * comp;
2836
0
                    black += cmyk_map_entry->k * comp;
2837
0
                    cmyk_map_entry++;
2838
0
                }
2839
0
                cyan /= frac_1;
2840
0
                magenta /= frac_1;
2841
0
                yellow /= frac_1;
2842
0
                black /= frac_1;
2843
2844
0
                if (cyan > 255)
2845
0
                    cyan = 255;
2846
0
                if (magenta > 255)
2847
0
                    magenta = 255;
2848
0
                if (yellow > 255)
2849
0
                    yellow = 255;
2850
0
                if (black > 255)
2851
0
                    black = 255;
2852
2853
0
                buf_ptr[position] = cyan;
2854
0
                buf_ptr[position + planestride] = magenta;
2855
0
                buf_ptr[position + planestride * 2] = yellow;
2856
0
                buf_ptr[position + planestride * 3] = black;
2857
0
            }
2858
0
            if (keep_alpha) {
2859
                /* Move the alpha and tag data */
2860
0
                buf_ptr[position + planestride * 4] = a;
2861
0
                if (tag_offset > 0) {
2862
0
                    buf_ptr[position + planestride * 5] =
2863
0
                        buf_ptr[position + planestride * tag_offset];
2864
0
                }
2865
0
            } else {
2866
                /* Remove alpha but keep tags */
2867
0
                if (tag_offset > 0) {
2868
0
                    buf_ptr[position + planestride * 4] =
2869
0
                        buf_ptr[position + planestride * tag_offset];
2870
0
                }
2871
2872
0
            }
2873
0
            position += 1;
2874
0
        }
2875
0
    }
2876
0
}
2877
2878
static void
2879
template_spots_to_cmyk_16(byte *buf_ptr_, int width, int height, int rowstride,
2880
    int planestride, int num_comp, int spot_start, int tag_offset,
2881
    cmyk_composite_map *map, bool keep_alpha)
2882
0
{
2883
0
    int comp_num;
2884
0
    ulong cyan, magenta, yellow, black;
2885
0
    cmyk_composite_map *cmyk_map_entry;
2886
0
    int x, y;
2887
0
    int position;
2888
0
    ulong comp, a;
2889
0
    uint16_t *buf_ptr = (uint16_t *)(void *)buf_ptr_;
2890
2891
    /* planestride and rowstride are in bytes, and we want them in shorts */
2892
0
    planestride >>= 1;
2893
0
    rowstride >>= 1;
2894
2895
0
    for (y = 0; y < height; y++) {
2896
0
        position = y * rowstride;
2897
0
        for (x = 0; x < width; x++) {
2898
0
            a = buf_ptr[position + planestride * num_comp];
2899
0
            if (a != 0) {
2900
0
                cyan = (ulong)buf_ptr[position] * frac_1_long;
2901
0
                magenta = (ulong)buf_ptr[position + planestride] * frac_1_long;
2902
0
                yellow = (ulong)buf_ptr[position + planestride * 2] * frac_1_long;
2903
0
                black = (ulong)buf_ptr[position + planestride * 3] * frac_1_long;
2904
0
                cmyk_map_entry = &(map[4]);
2905
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2906
0
                    comp = buf_ptr[position + planestride * comp_num];
2907
0
                    cyan += (ulong)cmyk_map_entry->c * comp;
2908
0
                    magenta += (ulong)cmyk_map_entry->m * comp;
2909
0
                    yellow += (ulong)cmyk_map_entry->y * comp;
2910
0
                    black += (ulong)cmyk_map_entry->k * comp;
2911
0
                    cmyk_map_entry++;
2912
0
                }
2913
0
                cyan /= frac_1_long;
2914
0
                magenta /= frac_1_long;
2915
0
                yellow /= frac_1_long;
2916
0
                black /= frac_1_long;
2917
2918
0
                if (cyan > 65535)
2919
0
                    cyan = 65535;
2920
0
                if (magenta > 65535)
2921
0
                    magenta = 65535;
2922
0
                if (yellow > 65535)
2923
0
                    yellow = 65535;
2924
0
                if (black > 65535)
2925
0
                    black = 65535;
2926
2927
#if ARCH_IS_BIG_ENDIAN
2928
                buf_ptr[position] = cyan;
2929
                buf_ptr[position + planestride] = magenta;
2930
                buf_ptr[position + planestride * 2] = yellow;
2931
                buf_ptr[position + planestride * 3] = black;
2932
#else
2933
0
                ((byte *)&buf_ptr[position])[0] = cyan >> 8;
2934
0
                ((byte *)&buf_ptr[position])[1] = cyan;
2935
0
                ((byte *)&buf_ptr[position + planestride])[0] = magenta >> 8;
2936
0
                ((byte *)&buf_ptr[position + planestride])[1] = magenta;
2937
0
                ((byte *)&buf_ptr[position + planestride * 2])[0] = yellow >> 8;
2938
0
                ((byte *)&buf_ptr[position + planestride * 2])[1] = yellow;
2939
0
                ((byte *)&buf_ptr[position + planestride * 3])[0] = black >> 8;
2940
0
                ((byte *)&buf_ptr[position + planestride * 3])[1] = black;
2941
0
#endif
2942
0
            }
2943
            /* Move the alpha and tag data */
2944
#if ARCH_IS_BIG_ENDIAN
2945
            if (keep_alpha) {
2946
                buf_ptr[position + planestride * 4] = a;
2947
                if (tag_offset > 0) {
2948
                    buf_ptr[position + planestride * 5] =
2949
                        buf_ptr[position + planestride * tag_offset];
2950
                }
2951
            } else {
2952
                if (tag_offset > 0) {
2953
                    buf_ptr[position + planestride * 4] =
2954
                        buf_ptr[position + planestride * tag_offset];
2955
                }
2956
            }
2957
#else
2958
0
            if (keep_alpha) {
2959
0
                ((byte *)&buf_ptr[position + planestride * 4])[0] = a >> 8;
2960
0
                ((byte *)&buf_ptr[position + planestride * 4])[1] = a;
2961
0
                if (tag_offset > 0) {
2962
0
                    ((byte *)&buf_ptr[position + planestride * 5])[0] =
2963
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2964
0
                    ((byte *)&buf_ptr[position + planestride * 5])[1] =
2965
0
                        buf_ptr[position + planestride * tag_offset];
2966
0
                }
2967
0
            } else {
2968
0
                if (tag_offset > 0) {
2969
0
                    ((byte *)&buf_ptr[position + planestride * 4])[0] =
2970
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2971
0
                    ((byte *)&buf_ptr[position + planestride * 4])[1] =
2972
0
                        buf_ptr[position + planestride * tag_offset];
2973
0
                }
2974
0
            }
2975
0
#endif
2976
0
            position += 1;
2977
0
        }
2978
0
    }
2979
0
}
2980
2981
static void
2982
pdf14_spots_to_cmyk(byte *buf_ptr, int width, int height, int rowstride,
2983
    int planestride, int num_comp, int spot_start, int tag_offset,
2984
    cmyk_composite_map *map, bool keep_alpha, bool deep)
2985
0
{
2986
0
    if (deep) {
2987
0
        if (keep_alpha) {
2988
0
            if (tag_offset > 0) {
2989
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2990
0
                    planestride, num_comp, spot_start, tag_offset,
2991
0
                    map, true);
2992
0
            } else {
2993
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2994
0
                    planestride, num_comp, spot_start, 0,
2995
0
                    map, true);
2996
0
            }
2997
0
        } else {
2998
0
            if (tag_offset > 0) {
2999
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3000
0
                    planestride, num_comp, spot_start, tag_offset,
3001
0
                    map, false);
3002
0
            } else {
3003
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3004
0
                    planestride, num_comp, spot_start, 0,
3005
0
                    map, false);
3006
0
            }
3007
0
        }
3008
0
    } else {
3009
0
        if (keep_alpha) {
3010
0
            if (tag_offset > 0) {
3011
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3012
0
                    planestride, num_comp, spot_start, tag_offset,
3013
0
                    map, true);
3014
0
            } else {
3015
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3016
0
                    planestride, num_comp, spot_start, 0,
3017
0
                    map, true);
3018
0
            }
3019
0
        } else {
3020
0
            if (tag_offset > 0) {
3021
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3022
0
                    planestride, num_comp, spot_start, tag_offset,
3023
0
                    map, false);
3024
0
            } else {
3025
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3026
0
                    planestride, num_comp, spot_start, 0,
3027
0
                    map, false);
3028
0
            }
3029
0
        }
3030
0
    }
3031
0
}
3032
3033
/* This is for the case where we have mixture of spots and additive color.
3034
   For example, RGB + spots or Gray + spots */
3035
static void
3036
pdf14_blend_image_mixed_buffer(byte* buf_ptr, int width, int height, int rowstride,
3037
    int planestride, int num_comp, int spot_start)
3038
0
{
3039
0
    int x, y;
3040
0
    int position;
3041
0
    byte comp, a;
3042
0
    int tmp, comp_num;
3043
3044
0
    for (y = 0; y < height; y++) {
3045
0
        position = y * rowstride;
3046
0
        for (x = 0; x < width; x++) {
3047
0
            a = buf_ptr[position + planestride * num_comp];
3048
0
            if ((a + 1) & 0xfe) {
3049
0
                a ^= 0xff;
3050
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3051
0
                    comp = buf_ptr[position + planestride * comp_num];
3052
0
                    tmp = ((0xff - comp) * a) + 0x80;
3053
0
                    comp += (tmp + (tmp >> 8)) >> 8;
3054
0
                    buf_ptr[position + planestride * comp_num] = comp;
3055
0
                }
3056
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3057
0
                    comp = buf_ptr[position + planestride * comp_num];
3058
0
                    tmp = ((-comp) * a) + 0x80;
3059
0
                    comp += (tmp + (tmp >> 8)) >> 8;
3060
0
                    buf_ptr[position + planestride * comp_num] = comp;
3061
0
                }
3062
0
            } else if (a == 0) {
3063
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3064
0
                    buf_ptr[position + planestride * comp_num] = 0xff;
3065
0
                }
3066
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3067
0
                    buf_ptr[position + planestride * comp_num] = 0;
3068
0
                }
3069
0
            }
3070
0
            position += 1;
3071
0
        }
3072
0
    }
3073
0
}
3074
3075
static void
3076
pdf14_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, int rowstride,
3077
    int planestride, int num_comp, int spot_start)
3078
0
{
3079
0
    uint16_t* buf_ptr = (uint16_t*)(void*)buf_ptr_;
3080
0
    int x, y;
3081
0
    int position;
3082
0
    int comp, a;
3083
0
    int tmp, comp_num;
3084
3085
    /* planestride and rowstride are in bytes, and we want them in shorts */
3086
0
    planestride >>= 1;
3087
0
    rowstride >>= 1;
3088
3089
    /* Note that the input here is native endian, and the output must be in big endian! */
3090
0
    for (y = 0; y < height; y++) {
3091
0
        position = y * rowstride;
3092
0
        for (x = 0; x < width; x++) {
3093
            /* composite RGBA (or CMYKA, etc.) pixel with over solid background */
3094
0
            a = buf_ptr[position + planestride * num_comp];
3095
0
            if (a == 0) {
3096
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3097
0
                    buf_ptr[position + planestride * comp_num] = 0xffff;
3098
0
                }
3099
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3100
0
                    buf_ptr[position + planestride * comp_num] = 0;
3101
0
                }
3102
0
            } else if (a == 0xffff) {
3103
#if ARCH_IS_BIG_ENDIAN
3104
#else
3105
                /* Convert from native -> big endian */
3106
0
                for (comp_num = 0; comp_num < num_comp; comp_num++) {
3107
0
                    comp = buf_ptr[position + planestride * comp_num];
3108
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3109
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3110
0
                }
3111
0
#endif
3112
0
            } else {
3113
0
                a ^= 0xffff;
3114
0
                a += a >> 15; /* a is now 0 to 0x10000 */
3115
0
                a >>= 1; /* We can only use 15 bits as bg-comp has a sign bit we can't lose */
3116
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3117
0
                    comp = buf_ptr[position + planestride * comp_num];
3118
0
                    tmp = ((0xffff - comp) * a) + 0x4000;
3119
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3120
                    /* Store as big endian */
3121
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3122
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3123
0
                }
3124
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3125
0
                    comp = buf_ptr[position + planestride * comp_num];
3126
0
                    tmp = ((0 - comp) * a) + 0x4000;
3127
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3128
                    /* Store as big endian */
3129
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3130
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3131
0
                }
3132
0
            }
3133
0
            position += 1;
3134
0
        }
3135
0
    }
3136
0
}
3137
3138
static pdf14_buf*
3139
insert_empty_planes(pdf14_ctx* ctx, pdf14_buf** src_buf, int num_new_planes, int insert_index)
3140
0
{
3141
0
    int planestride = (*src_buf)->planestride;
3142
0
    int src_n_planes = (*src_buf)->n_planes;
3143
0
    int src_n_chan = (*src_buf)->n_chan;
3144
0
    int des_n_planes = src_n_planes + num_new_planes;
3145
0
    int des_n_chan = src_n_chan + num_new_planes;
3146
0
    byte *src_ptr = (*src_buf)->data;
3147
0
    byte* des_ptr;
3148
0
    byte *des_data;
3149
0
    bool deep = ctx->deep;
3150
3151
0
    des_data = gs_alloc_bytes(ctx->memory,
3152
0
        (size_t)planestride * des_n_planes + CAL_SLOP,
3153
0
        "insert_empty_planes");
3154
0
    if (des_data == NULL)
3155
0
        return NULL;
3156
3157
0
    des_ptr = des_data;
3158
3159
    /* First copy portion prior to insert point */
3160
0
    memcpy(des_ptr, src_ptr, (planestride * insert_index) << deep);
3161
3162
    /* New planes */
3163
0
    des_ptr += (planestride * insert_index) << deep;
3164
0
    src_ptr += (planestride * insert_index) << deep;
3165
0
    memset(des_ptr, 0, (planestride * num_new_planes) << deep);
3166
3167
    /* Extra planes (i.e. doc spots, tags) */
3168
0
    des_ptr += (planestride * num_new_planes) << deep;
3169
0
    memcpy(des_ptr, src_ptr, (planestride * (src_n_planes - insert_index)) << deep);
3170
3171
    /* Set up buffer structure */
3172
0
    gs_free_object(ctx->memory, (*src_buf)->data, "insert_empty_planes");
3173
0
    (*src_buf)->n_planes = des_n_planes;
3174
0
    (*src_buf)->n_chan = des_n_chan;
3175
0
    (*src_buf)->data = des_data;
3176
3177
0
    return *src_buf;
3178
0
}
3179
3180
static int
3181
pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target,
3182
    gs_gstate* pgs, pdf14_buf* buf, int planestride_in,
3183
    int rowstride_in, int x0, int y0, int width, int height,
3184
    int num_comp, uint16_t bg, bool has_tags, gs_int_rect rect_in,
3185
    gs_separations* pseparations, bool deep)
3186
0
{
3187
0
    pdf14_device* pdev = (pdf14_device*)dev;
3188
0
    int code = 0;
3189
0
    int y;
3190
0
    int num_rows_left;
3191
0
    int i;
3192
0
    gs_int_rect rect = rect_in;
3193
0
    int planestride = planestride_in;
3194
0
    int rowstride = rowstride_in;
3195
0
    byte* buf_ptr = NULL;
3196
0
    cmm_profile_t* src_profile = buf->group_color_info->icc_profile;
3197
0
    cmm_profile_t* des_profile = NULL;
3198
0
    cmm_dev_profile_t* dev_target_profile;
3199
0
    cmm_dev_profile_t* pdf14dev_profile;
3200
0
    bool color_mismatch = false;
3201
0
    bool supports_alpha = false;
3202
0
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
3203
0
    int alpha_offset = num_comp;
3204
0
    int tag_offset = has_tags ? num_comp + 1 : 0;
3205
0
    gs_color_space *pcs;
3206
0
    gs_image1_t image;
3207
0
    gx_image_enum_common_t *info;
3208
0
    gx_image_plane_t planes[GS_IMAGE_MAX_COMPONENTS];
3209
0
    pdf14_buf *cm_result = NULL;
3210
0
    bool did_alloc;
3211
0
    bool target_sep_device = dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0);
3212
0
    bool has_spots = pdev->ctx->num_spots > 0;
3213
0
    bool blend_spots = !target_sep_device && has_spots;
3214
3215
    /* Check if group color space is CMYK based */
3216
0
    code = dev_proc(target, get_profile)(target, &dev_target_profile);
3217
0
    if (code < 0)
3218
0
        return code;
3219
0
    if (dev_target_profile == NULL)
3220
0
        return gs_throw_code(gs_error_Fatal);
3221
3222
0
    if (src_profile == NULL) {
3223
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
3224
0
        if (code < 0) {
3225
0
            return code;
3226
0
        }
3227
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3228
0
    }
3229
3230
    /* If the target device does not support spot colors and we have spot colors
3231
       here due to overprint simulation (blend_spots == true), then we will need to convert the base
3232
       colors to CMYK if it is RGB or Gray so tha we can blend in the spot colors */
3233
0
    if (blend_spots && src_profile->data_cs != gsCMYK) {
3234
3235
0
        cm_result = pdf14_transform_color_buffer_no_matte(pgs, pdev->ctx, (gx_device *)dev, buf,
3236
0
            buf->data, src_profile, pgs->icc_manager->default_cmyk, 0, 0, buf->rect.q.x,
3237
0
            buf->rect.q.y, &did_alloc, buf->deep, false);
3238
0
        if (cm_result == NULL)
3239
0
            return_error(gs_error_VMerror);
3240
3241
        /* Update */
3242
0
        buf = cm_result;
3243
0
        src_profile = pgs->icc_manager->default_cmyk;
3244
0
        num_comp = buf->n_chan - 1;
3245
0
        bg = 0;
3246
0
        tag_offset = has_tags ? num_comp + 1 : 0;
3247
0
        alpha_offset = num_comp;
3248
3249
#if RAW_DUMP
3250
        buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3251
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3252
            "convertbase_to_cmyk_for_spot_blend", buf_ptr, deep);
3253
        global_index++;
3254
#endif
3255
0
    }
3256
3257
    /* Fix order map if needed */
3258
0
    for (i = 0; i < num_comp; i++) {
3259
0
        pdev->devn_params.separation_order_map[i] = i;
3260
0
    }
3261
3262
    /* Check if we have a color conversion issue */
3263
0
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3264
0
    if (!gsicc_profiles_equal(des_profile, src_profile))
3265
0
        color_mismatch = true;
3266
3267
    /* Check if target supports alpha */
3268
0
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
3269
0
    code = 0;
3270
3271
0
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3272
3273
    /* Note. The logic below will need a little rework if we ever
3274
       have a device that has tags and alpha support */
3275
0
    if (supports_alpha) {
3276
3277
        /* If doing simulated overprint, Bring the spot color channels into
3278
           CMYK. Data is planar and 16 bit data in native format. */
3279
0
        if (pdev->overprint_sim && pdev->devn_params.page_spot_colors > 0) {
3280
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3281
3282
            /* In the clist case, we need to get equiv spots out of the pseudo-band. */
3283
0
            if (pdev->pclist_device != NULL) {
3284
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3285
3286
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3287
0
                if (code < 0)
3288
0
                    return code;
3289
0
            }
3290
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3291
3292
            /* Now we go to big endian */
3293
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3294
0
                planestride, num_comp, src_profile->num_comps,
3295
0
                tag_offset, cmyk_map, true, deep);
3296
3297
            /* Reset buffer information. We have CMYK+alpha and maybe tags */
3298
0
            buf->n_chan = buf->n_chan - buf->num_spots;
3299
0
            buf->n_planes = buf->n_planes - buf->num_spots;
3300
0
            buf->num_spots = 0;
3301
0
            num_comp = buf->n_chan - 1;
3302
0
            tag_offset = has_tags ? buf->n_planes - 1 : 0; /* Tags at end */
3303
0
        }
3304
3305
0
        if (!color_mismatch) {
3306
0
            for (i = 0; i < buf->n_planes; i++)
3307
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3308
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3309
0
                rect.p.x, rect.p.y, width, height,
3310
0
                rowstride, alpha_offset, tag_offset);
3311
            /* Right now code has number of rows written */
3312
0
        } else {
3313
            /* In this case, just color convert and maintain alpha.
3314
               This is a case where we either either blend in the
3315
               right color space and have no alpha for the output
3316
               device or hand back the wrong color space with
3317
               alpha data.  We choose the later. */
3318
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
3319
0
                        dev_target_profile, &buf, &buf_ptr, false, rect.p.x,
3320
0
                        rect.p.y, width, height);
3321
0
            if (code < 0)
3322
0
                return code;
3323
3324
            /* reset */
3325
0
            rowstride = buf->rowstride;
3326
0
            planestride = buf->planestride;
3327
0
            num_comp = buf->n_chan - 1;
3328
0
            alpha_offset = num_comp;
3329
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3330
3331
            /* And then out */
3332
0
            for (i = 0; i < buf->n_planes; i++)
3333
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3334
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3335
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
3336
0
                tag_offset);
3337
            /* Right now code has number of rows written.  Writing continues below */
3338
0
        }
3339
0
    } else {
3340
        /* Device could not handle the alpha data (we actually don't have
3341
           a device that does spot colorants and has an alpha channel so
3342
           the above code is untested.  Go ahead and preblend now and then
3343
           color convert if needed */
3344
#if RAW_DUMP
3345
           /* Dump before and after the blend to make sure we are doing that ok */
3346
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3347
            "pre_put_image_blend_image", buf_ptr, deep);
3348
        global_index++;
3349
#endif
3350
3351
0
        if (color_mismatch && (src_profile->data_cs == gsRGB || src_profile->data_cs == gsGRAY)) {
3352
0
            if (deep) {
3353
            /* In this case, we are NOT going to bring the spots into the CMYK
3354
               equivalent colors, since otherwise src_profile would be CMYK based.  So
3355
               16 bit data will be converted now from native endian to big endian during
3356
               the blending process */
3357
0
                pdf14_blend_image_mixed_buffer16(buf_ptr, width, height, rowstride,
3358
0
                    planestride, num_comp, src_profile->num_comps);
3359
0
            } else {
3360
0
                pdf14_blend_image_mixed_buffer(buf_ptr, width, height, rowstride,
3361
0
                    planestride, num_comp, src_profile->num_comps);
3362
0
            }
3363
0
        } else {
3364
0
            if (deep) {
3365
            /* In this case, if blend_spots == true, we will shortly be bringing
3366
               the spot colors to CMYK equivalent colors. It is at that time that
3367
               we will convert from native endian to big endian. In all other
3368
               cases this blending will due to conversion from native to BE */
3369
0
                bool keep_native = (blend_spots == true);
3370
3371
0
                gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
3372
0
                    planestride, num_comp, bg, keep_native);
3373
0
            } else {
3374
0
                gx_blend_image_buffer(buf_ptr, width, height, rowstride,
3375
0
                    planestride, num_comp, bg >> 8);
3376
0
            }
3377
0
        }
3378
3379
#if RAW_DUMP
3380
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3381
            "post_put_image_blend_image", buf_ptr, deep);
3382
        global_index++;
3383
#endif
3384
3385
        /* If doing simulated overprint and we are not going to a sep device and
3386
           we have spot colors, then bring the spot color channels into CMYK
3387
           (We should have already converted our base color space to CMYK if it was RGB or gray).
3388
           At this point, data is planar and 16 bit data is still in native format. It is
3389
           here that 16 bit data will be converted to BE. Otherwise it will have been converted
3390
           above during the alpha blend operation. */
3391
0
        if (blend_spots) {
3392
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3393
3394
            /* In the clist case, we need to get equiv spots out of the
3395
               pseudo-band. */
3396
0
            if (pdev->pclist_device != NULL) {
3397
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3398
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3399
0
                if (code < 0)
3400
0
                    return code;
3401
0
            }
3402
3403
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3404
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3405
0
                planestride, num_comp, src_profile->num_comps,
3406
0
                tag_offset, cmyk_map, false, deep);
3407
3408
            /* Reset buffer information. We have CMYK and maybe tags */
3409
0
            num_comp = 4;
3410
0
            alpha_offset = 0;
3411
0
            buf->n_chan = buf->n_chan - buf->num_spots - 1;     /* No spots or alpha */
3412
0
            buf->n_planes = buf->n_planes - buf->num_spots - 1; /* No spots or alpha */
3413
0
            tag_offset = has_tags ? buf->n_chan : 0;      /* Tags at end */
3414
0
            buf->num_spots = 0;
3415
3416
#if RAW_DUMP
3417
            dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3418
                "post_put_image_spot_to_cmyk", buf_ptr, deep);
3419
            global_index++;
3420
#endif
3421
0
        }
3422
3423
        /* Map to the destination color space */
3424
0
        if (color_mismatch) {
3425
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
3426
0
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height);
3427
0
            if (code < 0)
3428
0
                return code;
3429
3430
            /* reset */
3431
0
            rowstride = buf->rowstride;
3432
0
            planestride = buf->planestride;
3433
0
            num_comp = buf->n_chan;
3434
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3435
0
        }
3436
3437
        /* We may need to pad the buffers to ensure that any additional spot
3438
           channels that are not created by the ICC color conversion (or
3439
           non-conversion if this is not an NCLR profile) get placed properly.
3440
           It is up to the target device to
3441
           handle these planes how it sees fit based upon the image data
3442
           and/or any tags plane during any put image call.  We *could*
3443
           do something here to possibly communicate through the put_image
3444
           call where the page related spots start, but that would/could
3445
           be confusing, especially for long term maintenance. Easier just
3446
           to have put_image hand all the data */
3447
0
        if (dev_target_profile->spotnames != NULL &&
3448
0
            dev_target_profile->spotnames->count > des_profile->num_comps) {
3449
0
            int num_new_planes = dev_target_profile->spotnames->count - des_profile->num_comps;
3450
0
            int insert_index = des_profile->num_comps;
3451
0
            pdf14_buf* result;
3452
3453
0
            result = insert_empty_planes(pdev->ctx, &buf, num_new_planes, insert_index);
3454
0
            if (result == NULL)
3455
0
                return_error(gs_error_VMerror);
3456
3457
0
            num_comp = buf->n_chan;
3458
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3459
0
            buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3460
0
        }
3461
#if RAW_DUMP
3462
        /* Dump after the CS transform */
3463
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3464
            "post_put_image_color_convert", buf_ptr, deep);
3465
        global_index++;
3466
        /* clist_band_count++; */
3467
#endif
3468
3469
        /* Try put_image again. This can occur if the
3470
           target, like psdcmyk and tiffsep, support put_image */
3471
0
        alpha_offset = 0;
3472
0
        for (i = 0; i < buf->n_planes; i++)
3473
0
            buf_ptrs[i] = buf_ptr + i * planestride;
3474
0
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3475
0
            rect.p.x, rect.p.y, width, height,
3476
0
            rowstride, alpha_offset, tag_offset);
3477
0
    }
3478
3479
    /* Put image was succesful.  We processed some or all of the rows.
3480
       Continue until we are done */
3481
0
    if (code > 0) {
3482
0
        num_rows_left = height - code;
3483
0
        while (num_rows_left > 0) {
3484
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3485
0
                rect.p.x, rect.p.y + code, width, num_rows_left, rowstride,
3486
0
                alpha_offset, tag_offset);
3487
0
            if (code < 0) {
3488
0
                return code;
3489
0
            }
3490
0
            num_rows_left = num_rows_left - code;
3491
0
        }
3492
0
        return 0;
3493
0
    }
3494
3495
    /* Sep devices all support put_image (tiffsep and psdcmyk)
3496
       as well as those devices that support alpha (pngalpha,
3497
       png16malpha). If we are here, then we are doing an
3498
       overprint simulation on some other device. Image data
3499
       is aleady blended and in device color space. */
3500
0
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
3501
0
    if (code < 0)
3502
0
        return code;
3503
3504
    /* Already in destination CS */
3505
0
    pcs->cmm_icc_profile_data = des_profile;
3506
3507
    /* pcs takes a reference to the profile data it just retrieved. */
3508
0
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_blended_image_cmykspot");
3509
0
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
3510
0
    gs_image_t_init_adjust(&image, pcs, false);
3511
0
    image.ImageMatrix.xx = (float)width;
3512
0
    image.ImageMatrix.yy = (float)height;
3513
0
    image.Width = width;
3514
0
    image.Height = height;
3515
0
    image.BitsPerComponent = deep ? 16 : 8;
3516
0
    image.ColorSpace = pcs;
3517
0
    image.format = gs_image_format_component_planar;
3518
3519
0
    ctm_only_writable(pgs).xx = (float)width;
3520
0
    ctm_only_writable(pgs).xy = 0;
3521
0
    ctm_only_writable(pgs).yx = 0;
3522
0
    ctm_only_writable(pgs).yy = (float)height;
3523
0
    ctm_only_writable(pgs).tx = (float)rect.p.x;
3524
0
    ctm_only_writable(pgs).ty = (float)rect.p.y;
3525
0
    code = dev_proc(target, begin_typed_image) (target,
3526
0
        pgs, NULL, (gs_image_common_t *)&image,
3527
0
        NULL, NULL, NULL, pgs->memory, &info);
3528
0
    if (code < 0) {
3529
0
        rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3530
0
        return code;
3531
0
    }
3532
#if RAW_DUMP
3533
    /* Dump the current buffer to see what we have. */
3534
    dump_raw_buffer(pdev->ctx->memory,
3535
        pdev->ctx->stack->rect.q.y - pdev->ctx->stack->rect.p.y,
3536
        pdev->ctx->stack->rect.q.x - pdev->ctx->stack->rect.p.x,
3537
        pdev->ctx->stack->n_planes,
3538
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3539
        "put_image_final_big", pdev->ctx->stack->data, deep);
3540
    dump_raw_buffer(pdev->ctx->memory,
3541
        height, width, buf->n_planes,
3542
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3543
        "put_image_final_small", buf_ptr, deep);
3544
    global_index++;
3545
    clist_band_count++;
3546
#endif
3547
3548
0
    for (i = 0; i < num_comp; i++) {
3549
0
        planes[i].data = buf_ptr + i * planestride;
3550
0
        planes[i].data_x = 0;
3551
0
        planes[i].raster = buf->rowstride;
3552
0
    }
3553
3554
0
    for (y = 0; y < height; y++) {
3555
0
        int rows_used;
3556
3557
0
        info->procs->plane_data(info, (const gx_image_plane_t*) &planes, 1, &rows_used);
3558
3559
0
        for (i = 0; i < num_comp; i++) {
3560
0
            planes[i].data += buf->rowstride;
3561
0
        }
3562
0
    }
3563
0
    info->procs->end_image(info, true);
3564
3565
    /* This will also decrement the profile */
3566
0
    rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3567
0
    return code;
3568
0
}
3569
3570
/**
3571
 * pdf14_cmykspot_put_image: Put rendered image to target device.
3572
 * @pdev: The PDF 1.4 rendering device.
3573
 * @pgs: State for image draw operation.
3574
 * @target: The target device.
3575
 *
3576
 * Puts the rendered image in @pdev's buffer to @target. This is called
3577
 * as part of the sequence of popping the PDF 1.4 device filter.
3578
 *
3579
 * Return code: negative on error.
3580
 **/
3581
static  int
3582
pdf14_cmykspot_put_image(gx_device *dev, gs_gstate *pgs, gx_device *target)
3583
0
{
3584
0
    pdf14_device *pdev = (pdf14_device *)dev;
3585
0
    pdf14_buf *buf = pdev->ctx->stack;
3586
0
    gs_int_rect rect;
3587
0
    int x1, y1, width, height;
3588
0
    gs_devn_params *pdevn_params = &pdev->devn_params;
3589
0
    gs_separations *pseparations = &pdevn_params->separations;
3590
0
    int planestride;
3591
0
    int rowstride;
3592
0
    bool deep = pdev->ctx->deep;
3593
0
    uint16_t bg;
3594
0
    int num_comp;
3595
3596
    /* Nothing was ever drawn. */
3597
0
    if (buf == NULL)
3598
0
        return 0;
3599
3600
0
    bg = buf->group_color_info->isadditive ? 65535 : 0;
3601
0
    num_comp = buf->n_chan - 1;
3602
0
    rect = buf->rect;
3603
0
    planestride = buf->planestride;
3604
0
    rowstride = buf->rowstride;
3605
3606
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3607
       potential problem. Bug 694190 */
3608
0
    if (buf->saved != NULL) {
3609
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3610
0
    }
3611
0
    if_debug0m('v', dev->memory, "[v]pdf14_cmykspot_put_image\n");
3612
0
    rect_intersect(rect, buf->dirty);
3613
0
    x1 = min(pdev->width, rect.q.x);
3614
0
    y1 = min(pdev->height, rect.q.y);
3615
0
    width = x1 - rect.p.x;
3616
0
    height = y1 - rect.p.y;
3617
0
    if (width <= 0 || height <= 0 || buf->data == NULL)
3618
0
        return 0;
3619
3620
#if RAW_DUMP
3621
    /* Dump the current buffer to see what we have. */
3622
    dump_raw_buffer(pdev->ctx->memory,
3623
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
3624
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
3625
                    pdev->ctx->stack->n_planes,
3626
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3627
                    "CMYK_SPOT_PUTIMAGE", pdev->ctx->stack->data,
3628
                    pdev->ctx->stack->deep);
3629
3630
    global_index++;
3631
    clist_band_count++;
3632
#endif
3633
3634
0
    return pdf14_put_blended_image_cmykspot(dev, target, pgs,
3635
0
                      buf, planestride, rowstride,
3636
0
                      rect.p.x, rect.p.y, width, height, num_comp, bg,
3637
0
                      buf->has_tags, rect, pseparations, deep);
3638
0
}
3639
3640
/**
3641
 * pdf14_custom_put_image: Put rendered image to target device.
3642
 * @pdev: The PDF 1.4 rendering device.
3643
 * @pgs: State for image draw operation.
3644
 * @target: The target device.
3645
 *
3646
 * Puts the rendered image in @pdev's buffer to @target. This is called
3647
 * as part of the sequence of popping the PDF 1.4 device filter.
3648
 *
3649
 * Return code: negative on error.
3650
 **/
3651
static  int
3652
pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
3653
0
{
3654
0
    pdf14_device * pdev = (pdf14_device *)dev;
3655
0
    pdf14_buf *buf = pdev->ctx->stack;
3656
0
    bool deep = pdev->ctx->deep;
3657
0
    gs_int_rect rect;
3658
0
    int x0, y0;
3659
0
    int planestride;
3660
0
    int rowstride;
3661
0
    int num_comp;
3662
0
    uint16_t bg;
3663
0
    int x1, y1, width, height;
3664
0
    byte *buf_ptr;
3665
3666
    /* Nothing was ever drawn. */
3667
0
    if (buf == NULL)
3668
0
        return 0;
3669
3670
0
    bg = pdev->ctx->additive ? 0xffff : 0;
3671
0
    num_comp = buf->n_chan - 1;
3672
0
    rect = buf->rect;
3673
0
    x0 = rect.p.x;
3674
0
    y0 = rect.p.y;
3675
0
    planestride = buf->planestride;
3676
0
    rowstride = buf->rowstride;
3677
3678
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3679
       potential problem. Bug 694190 */
3680
0
    if (buf->saved != NULL) {
3681
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3682
0
    }
3683
0
    if_debug0m('v', dev->memory, "[v]pdf14_custom_put_image\n");
3684
0
    rect_intersect(rect, buf->dirty);
3685
0
    x1 = min(pdev->width, rect.q.x);
3686
0
    y1 = min(pdev->height, rect.q.y);
3687
0
    width = x1 - rect.p.x;
3688
0
    height = y1 - rect.p.y;
3689
0
    if (width <= 0 || height <= 0 || buf->data == NULL)
3690
0
        return 0;
3691
0
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x)<<deep);
3692
3693
0
    return gx_put_blended_image_custom(target, buf_ptr,
3694
0
                      planestride, rowstride,
3695
0
                      x0, y0, width, height, num_comp, bg, deep);
3696
0
}
3697
3698
/* This is rather nasty: in the event we are interrupted (by an error) between a push and pop
3699
 * of one or more groups, we have to cycle through any ICC profile changes since the push
3700
 * putting everything back how it was, and cleaning up the reference counts.
3701
 */
3702
static void pdf14_cleanup_group_color_profiles (pdf14_device *pdev)
3703
90.3k
{
3704
90.3k
    if (pdev->ctx && pdev->ctx->stack) {
3705
42.5k
        pdf14_buf *buf, *next;
3706
3707
42.5k
        for (buf = pdev->ctx->stack->saved; buf != NULL; buf = next) {
3708
19
            pdf14_group_color_t *group_color_info = buf->group_color_info;
3709
19
            next = buf->saved;
3710
38
            while (group_color_info) {
3711
19
               if (group_color_info->icc_profile != NULL) {
3712
19
                   cmm_profile_t *group_profile;
3713
19
                   gsicc_rendering_param_t render_cond;
3714
19
                   cmm_dev_profile_t *dev_profile;
3715
19
                   int code = dev_proc((gx_device *)pdev, get_profile)((gx_device *)pdev,  &dev_profile);
3716
3717
19
                   if (code >= 0) {
3718
19
                       gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
3719
19
                                             &render_cond);
3720
3721
19
                       gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
3722
19
                                               -1, "pdf14_end_transparency_group");
3723
19
                       pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
3724
19
                           group_color_info->icc_profile;
3725
19
                       group_color_info->icc_profile = NULL;
3726
19
                   }
3727
19
               }
3728
3729
19
               group_color_info = group_color_info->previous;
3730
19
            }
3731
19
        }
3732
42.5k
    }
3733
90.3k
}
3734
3735
static  int
3736
pdf14_close(gx_device *dev)
3737
45.3k
{
3738
45.3k
    pdf14_device *pdev = (pdf14_device *)dev;
3739
3740
45.3k
    pdf14_cleanup_group_color_profiles(pdev);
3741
3742
45.3k
    if (pdev->ctx) {
3743
44.6k
        pdf14_ctx_free(pdev->ctx);
3744
44.6k
        pdev->ctx = NULL;
3745
44.6k
    }
3746
45.3k
    return 0;
3747
45.3k
}
3748
3749
/* This is called when something has gone wrong and the interpreter received a
3750
   stop while in the middle of doing something with the PDF14 device.  We need
3751
   to clean up and end this in a graceful manner */
3752
static int
3753
pdf14_discard_trans_layer(gx_device *dev, gs_gstate * pgs)
3754
0
{
3755
0
    pdf14_device *pdev = (pdf14_device *)dev;
3756
    /* The things that need to be cleaned up */
3757
0
    pdf14_ctx *ctx = pdev->ctx;
3758
0
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
3759
0
    pdf14_group_color_t *group_color = pdev->color_model_stack;
3760
3761
    /* Free up the smask color */
3762
0
    if (smaskcolor != NULL) {
3763
0
        smaskcolor->ref_count = 1;
3764
0
        pdf14_decrement_smask_color(pgs, dev);
3765
0
        pdev->smaskcolor = NULL;
3766
0
    }
3767
3768
    /* Free up the nested color procs and decrement the profiles */
3769
0
    if (group_color != NULL) {
3770
0
        while (group_color->previous != NULL)
3771
0
            pdf14_pop_group_color(dev, pgs);
3772
0
        gs_free_object(dev->memory->stable_memory, group_color, "pdf14_discard_trans_layer");
3773
0
        pdev->color_model_stack = NULL;
3774
0
    }
3775
3776
    /* Start the context clean up */
3777
0
    if (ctx != NULL) {
3778
0
        pdf14_buf *buf, *next;
3779
0
        pdf14_group_color_t *procs, *prev_procs;
3780
3781
0
        if (ctx->mask_stack != NULL) {
3782
0
            pdf14_free_mask_stack(ctx, ctx->memory);
3783
0
        }
3784
3785
        /* Now the stack of buffers */
3786
0
        for (buf = ctx->stack; buf != NULL; buf = next) {
3787
0
            next = buf->saved;
3788
3789
0
            gs_free_object(ctx->memory, buf->transfer_fn, "pdf14_discard_trans_layer");
3790
0
            gs_free_object(ctx->memory, buf->matte, "pdf14_discard_trans_layer");
3791
0
            gs_free_object(ctx->memory, buf->data, "pdf14_discard_trans_layer");
3792
0
            gs_free_object(ctx->memory, buf->backdrop, "pdf14_discard_trans_layer");
3793
            /* During the soft mask push, the mask_stack was copied (not moved) from
3794
               the ctx to the tos mask_stack. We are done with this now so it is safe
3795
               to free this one object */
3796
0
            gs_free_object(ctx->memory, buf->mask_stack, "pdf14_discard_trans_layer");
3797
0
            for (procs = buf->group_color_info; procs != NULL; procs = prev_procs) {
3798
0
                prev_procs = procs->previous;
3799
0
                gs_free_object(ctx->memory, procs, "pdf14_discard_trans_layer");
3800
0
            }
3801
0
            gs_free_object(ctx->memory, buf, "pdf14_discard_trans_layer");
3802
0
        }
3803
        /* Finally the context itself */
3804
0
        gs_free_object(ctx->memory, ctx, "pdf14_discard_trans_layer");
3805
0
        pdev->ctx = NULL;
3806
0
    }
3807
0
    return 0;
3808
0
}
3809
3810
static  int
3811
pdf14_output_page(gx_device * dev, int num_copies, int flush)
3812
0
{
3813
0
    pdf14_device * pdev = (pdf14_device *)dev;
3814
3815
0
    if (pdev->target != NULL)
3816
0
        return (*dev_proc(pdev->target, output_page)) (pdev->target, num_copies, flush);
3817
0
    return 0;
3818
0
}
3819
3820
314k
#define COPY_PARAM(p) dev->p = target->p
3821
224k
#define COPY_ARRAY_PARAM(p) memcpy(dev->p, target->p, sizeof(dev->p))
3822
3823
/*
3824
 * Copy device parameters back from a target.  This copies all standard
3825
 * parameters related to page size and resolution, but not any of the
3826
 * color-related parameters, as the pdf14 device retains its own color
3827
 * handling. This routine is parallel to gx_device_copy_params().
3828
 * Note that it DOES copy the devn_params since these are required to
3829
 * keep agreement with colorant name->number mapping, and don't change
3830
 * with the pdf14 color handling.
3831
 */
3832
static  void
3833
gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target)
3834
44.9k
{
3835
44.9k
    cmm_dev_profile_t *profile_targ;
3836
44.9k
    cmm_dev_profile_t *profile_dev14;
3837
44.9k
    pdf14_device *pdev = (pdf14_device*) dev;
3838
44.9k
    cmm_profile_t *blend_profile = NULL;
3839
44.9k
    int k;
3840
3841
44.9k
    COPY_PARAM(width);
3842
44.9k
    COPY_PARAM(height);
3843
44.9k
    COPY_ARRAY_PARAM(MediaSize);
3844
44.9k
    COPY_ARRAY_PARAM(ImagingBBox);
3845
44.9k
    COPY_PARAM(ImagingBBox_set);
3846
44.9k
    COPY_ARRAY_PARAM(HWResolution);
3847
44.9k
    COPY_ARRAY_PARAM(Margins);
3848
44.9k
    COPY_ARRAY_PARAM(HWMargins);
3849
44.9k
    COPY_PARAM(PageCount);
3850
44.9k
    COPY_PARAM(MaxPatternBitmap);
3851
44.9k
    COPY_PARAM(graphics_type_tag);
3852
44.9k
    COPY_PARAM(interpolate_control);
3853
44.9k
    memcpy(&(dev->space_params), &(target->space_params), sizeof(gdev_space_params));
3854
3855
44.9k
    if (dev->icc_struct == NULL) {
3856
44.9k
        dev->icc_struct = gsicc_new_device_profile_array(dev);
3857
44.9k
        profile_dev14 = dev->icc_struct;
3858
44.9k
        dev_proc((gx_device *) target, get_profile)((gx_device *) target,
3859
44.9k
                                          &(profile_targ));
3860
3861
224k
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
3862
179k
            if (profile_targ->device_profile[k] != NULL) {
3863
44.9k
                gsicc_adjust_profile_rc(profile_targ->device_profile[k], 1, "gs_pdf14_device_copy_params");
3864
44.9k
            }
3865
179k
            if (profile_dev14->device_profile[k] != NULL) {
3866
0
                gsicc_adjust_profile_rc(profile_dev14->device_profile[k], -1, "gs_pdf14_device_copy_params");
3867
0
            }
3868
179k
            profile_dev14->device_profile[k] = profile_targ->device_profile[k];
3869
179k
            profile_dev14->rendercond[k] = profile_targ->rendercond[k];
3870
179k
        }
3871
3872
44.9k
        dev->icc_struct->devicegraytok = profile_targ->devicegraytok;
3873
44.9k
        dev->icc_struct->graydetection = profile_targ->graydetection;
3874
44.9k
        dev->icc_struct->pageneutralcolor = profile_targ->pageneutralcolor;
3875
44.9k
        dev->icc_struct->supports_devn = profile_targ->supports_devn;
3876
44.9k
        dev->icc_struct->usefastcolor = profile_targ->usefastcolor;
3877
44.9k
        dev->icc_struct->blacktext = profile_targ->blacktext;
3878
44.9k
        dev->icc_struct->blackvector = profile_targ->blackvector;
3879
3880
44.9k
        switch (pdev->blend_cs_state) {
3881
44.9k
            case PDF14_BLEND_CS_UNSPECIFIED:
3882
44.9k
            case PDF14_BLEND_CS_TARGET_CIELAB:
3883
                /* PDF14_BLEND_CS_TARGET_CIELAB handled
3884
                   during the device push, when we have
3885
                   access to the pgs */
3886
44.9k
                break;
3887
0
            case PDF14_BLEND_CS_OUTPUTINTENT:
3888
0
                blend_profile = profile_targ->oi_profile;
3889
0
                break;
3890
0
            case PDF14_BLEND_CS_SPECIFIED:
3891
0
                blend_profile = profile_targ->blend_profile;
3892
0
                break;
3893
0
            default:
3894
0
                break;
3895
44.9k
        }
3896
3897
44.9k
        if (blend_profile != NULL) {
3898
            /* Set the device profile to the blend profile. Note only default profile is set */
3899
0
            gsicc_adjust_profile_rc(blend_profile, 1, "gs_pdf14_device_copy_params");
3900
0
            gsicc_adjust_profile_rc(profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "gs_pdf14_device_copy_params");
3901
0
            profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE] = blend_profile;
3902
0
        }
3903
3904
44.9k
        profile_dev14->overprint_control = profile_targ->overprint_control;
3905
44.9k
    }
3906
44.9k
#undef COPY_ARRAY_PARAM
3907
44.9k
#undef COPY_PARAM
3908
44.9k
}
3909
3910
/*
3911
 * This is a forwarding version of the put_params device proc.  It is only
3912
 * used when the PDF 1.4 compositor devices are closed.  The routine will
3913
 * check if the target device has closed and, if so, close itself.  The routine
3914
 * also sync the device parameters.
3915
 */
3916
static  int
3917
pdf14_forward_put_params(gx_device * dev, gs_param_list * plist)
3918
0
{
3919
0
    pdf14_device * pdev = (pdf14_device *)dev;
3920
0
    gx_device * tdev = pdev->target;
3921
0
    bool was_open = tdev->is_open;
3922
0
    int code = 0;
3923
3924
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
3925
0
        gx_device_decache_colors(dev);
3926
0
        if (!tdev->is_open) {
3927
0
            code = gs_closedevice(dev);
3928
0
            if (code == 0)
3929
0
                code = was_open ? 1 : 0;   /* target device closed */
3930
0
        }
3931
0
        gx_device_copy_params(dev, tdev);
3932
0
    }
3933
0
    return code;
3934
0
}
3935
3936
/* Function prototypes */
3937
int put_param_pdf14_spot_names(gx_device * pdev,
3938
                gs_separations * pseparations, gs_param_list * plist);
3939
0
#define PDF14NumSpotColorsParamName "PDF14NumSpotColors"
3940
3941
/*
3942
 * The put_params method for the PDF 1.4 device will check if the
3943
 * target device has closed and, if so, close itself.  Note:  This routine is
3944
 * currently being used by both the pdf14_clist_device and the pdf_device.
3945
 * Please make sure that any changes are either applicable to both devices
3946
 * or clone the routine for each device.
3947
 */
3948
static  int
3949
pdf14_put_params(gx_device * dev, gs_param_list * plist)
3950
0
{
3951
0
    pdf14_device * pdev = (pdf14_device *)dev;
3952
0
    gx_device * tdev = pdev->target;
3953
0
    bool was_open = tdev->is_open;
3954
0
    int code = 0;
3955
3956
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
3957
0
        gx_device_decache_colors(dev);
3958
0
        if (!tdev->is_open) {
3959
0
            code = gs_closedevice(dev);
3960
0
            if (code == 0)
3961
0
                code = was_open ? 1 : 0;   /* target device closed */
3962
0
        }
3963
0
        gs_pdf14_device_copy_params(dev, tdev);
3964
0
    }
3965
0
    return code;
3966
0
}
3967
3968
/*
3969
 * Copy marking related parameters into the PDF 1.4 device structure for use
3970
 * by pdf14_fill_rectangle.
3971
 */
3972
static  void
3973
pdf14_set_marking_params(gx_device *dev, const gs_gstate *pgs)
3974
1.79M
{
3975
1.79M
    pdf14_device * pdev = (pdf14_device *)dev;
3976
3977
1.79M
    if (pgs->alphaisshape) {
3978
13.4k
        pdev->opacity = 1.0;
3979
13.4k
        if (pgs->is_fill_color) {
3980
10.6k
            pdev->shape = pgs->fillconstantalpha;
3981
10.6k
        } else {
3982
2.80k
            pdev->shape = pgs->strokeconstantalpha;
3983
2.80k
        }
3984
1.78M
    } else {
3985
1.78M
        pdev->shape = 1.0;
3986
1.78M
        if (pgs->is_fill_color) {
3987
837k
            pdev->opacity = pgs->fillconstantalpha;
3988
947k
        } else {
3989
947k
            pdev->opacity = pgs->strokeconstantalpha;
3990
947k
        }
3991
1.78M
    }
3992
1.79M
    pdev->alpha = pdev->opacity * pdev->shape;
3993
1.79M
    pdev->blend_mode = pgs->blend_mode;
3994
1.79M
    if (pdev->icc_struct->overprint_control != gs_overprint_control_disable) {
3995
1.79M
        pdev->overprint = pgs->overprint;
3996
1.79M
        pdev->stroke_overprint = pgs->stroke_overprint;
3997
1.79M
    } else {
3998
0
        pdev->overprint = false;
3999
0
        pdev->stroke_overprint = false;
4000
0
    }
4001
4002
1.79M
    pdev->fillconstantalpha = pgs->fillconstantalpha;
4003
1.79M
    pdev->strokeconstantalpha = pgs->strokeconstantalpha;
4004
4005
1.79M
    if_debug6m('v', dev->memory,
4006
1.79M
               "[v]set_marking_params, opacity = %g, shape = %g, bm = %d, op = %d, eop = %d seop = %d\n",
4007
1.79M
               pdev->opacity, pdev->shape, pgs->blend_mode, pgs->overprint, pdev->effective_overprint_mode,
4008
1.79M
               pdev->stroke_effective_op_mode);
4009
1.79M
}
4010
4011
static  void
4012
update_lop_for_pdf14(gs_gstate *pgs, const gx_drawing_color *pdcolor)
4013
1.18M
{
4014
1.18M
    bool hastrans = false;
4015
4016
    /* We'd really rather not have to set the pdf14 bit in the lop, as this
4017
     * makes other operations much slower. We have no option however, if the
4018
     * current colour involves transparency, or if it's anything other than
4019
     * a completely solid (or transparent) operation in the normal blend mode.
4020
     */
4021
1.18M
    if (pdcolor != NULL)
4022
1.18M
    {
4023
1.18M
        if (gx_dc_is_pattern1_color(pdcolor) &&
4024
1.18M
            gx_pattern1_get_transptr(pdcolor) != NULL) {
4025
702
            hastrans = true;
4026
1.18M
        } else if (gx_dc_is_pattern2_color(pdcolor)) {
4027
            /* FIXME: Here we assume that ALL type 2 patterns are
4028
             * transparent - this test could be better. */
4029
5.86k
            hastrans = true;
4030
5.86k
        }
4031
1.18M
    }
4032
    /* The only idempotent blend modes are Normal, Darken and Lighten.
4033
       This appears to be the only place where this test is done so
4034
       not adding a is_idempotent method */
4035
1.18M
    if ((pgs->blend_mode != BLEND_MODE_Normal &&
4036
1.18M
        pgs->blend_mode != BLEND_MODE_Darken &&
4037
1.18M
        pgs->blend_mode != BLEND_MODE_Lighten) ||
4038
1.18M
        (pgs->fillconstantalpha != 1.0) ||
4039
1.18M
        (pgs->strokeconstantalpha != 1.0) ||
4040
1.18M
        (hastrans))
4041
124k
    {
4042
        /*
4043
         * The blend operations are not idempotent.  Force non-idempotent
4044
         * filling and stroking operations.
4045
         */
4046
124k
        pgs->log_op |= lop_pdf14;
4047
124k
    }
4048
1.18M
}
4049
4050
static int
4051
push_shfill_group(pdf14_clist_device *pdev,
4052
                  gs_gstate *pgs,
4053
                  gs_fixed_rect *box)
4054
6
{
4055
6
    gs_transparency_group_params_t params = { 0 };
4056
6
    int code;
4057
6
    gs_rect cb;
4058
6
    gs_gstate fudged_pgs = *pgs;
4059
4060
6
    params.shade_group = true;
4061
4062
    /* gs_begin_transparency_group takes a bbox that it then
4063
     * transforms by ctm. Our bbox has already been transformed,
4064
     * so clear out the ctm. */
4065
6
    fudged_pgs.ctm.xx = 1.0;
4066
6
    fudged_pgs.ctm.xy = 0;
4067
6
    fudged_pgs.ctm.yx = 0;
4068
6
    fudged_pgs.ctm.yy = 1.0;
4069
6
    fudged_pgs.ctm.tx = 0;
4070
6
    fudged_pgs.ctm.ty = 0;
4071
6
    cb.p.x = fixed2int_pixround(box->p.x);
4072
6
    cb.p.y = fixed2int_pixround(box->p.y);
4073
6
    cb.q.x = fixed2int_pixround(box->q.x);
4074
6
    cb.q.y = fixed2int_pixround(box->q.y);
4075
4076
6
    params.Isolated = false;
4077
6
    params.Knockout = true;
4078
6
    params.page_group = false;
4079
6
    params.group_opacity = fudged_pgs.fillconstantalpha;
4080
6
    params.group_shape = 1.0;
4081
6
    code = gs_begin_transparency_group(&fudged_pgs, &params, &cb, PDF14_BEGIN_TRANS_GROUP);
4082
4083
    /* We have the group handle the blendmode and the opacity,
4084
     * and continue with the existing graphics state reset
4085
     * to normal, opaque operation. We could do it the other
4086
     * way around, but this way means that if we push a knockout
4087
     * group for a stroke, and then the code calls back into
4088
     * the fill operation as part of doing the stroking, we don't
4089
     * push another one. */
4090
6
    gs_setblendmode(pgs, BLEND_MODE_Normal);
4091
6
    gs_setfillconstantalpha(pgs, 1.0);
4092
6
    gs_setstrokeconstantalpha(pgs, 1.0);
4093
6
    if (pdev) {
4094
6
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
4095
6
        if (code < 0)
4096
0
            return code;
4097
6
    }
4098
4099
6
    return code;
4100
6
}
4101
4102
static int
4103
pop_shfill_group(gs_gstate *pgs)
4104
6
{
4105
6
     return gs_end_transparency_group(pgs);
4106
6
}
4107
4108
static int
4109
pdf14_fill_path(gx_device *dev, const gs_gstate *pgs,
4110
                           gx_path *ppath, const gx_fill_params *params,
4111
                           const gx_drawing_color *pdcolor,
4112
                           const gx_clip_path *pcpath)
4113
990k
{
4114
990k
    gs_gstate new_pgs = *pgs;
4115
990k
    int code = 0;
4116
990k
    gs_pattern2_instance_t *pinst = NULL;
4117
990k
    int push_group = 0;
4118
4119
990k
    code = pdf14_initialize_ctx(dev, dev->color_info.num_components,
4120
990k
        dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, pgs);
4121
990k
    if (code < 0)
4122
0
        return code;
4123
4124
990k
    if (pdcolor == NULL)
4125
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4126
990k
    ((pdf14_device *)dev)->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_STROKE;
4127
990k
    if (gx_dc_is_pattern1_color(pdcolor)){
4128
2.18k
        if( gx_pattern1_get_transptr(pdcolor) != NULL ||
4129
2.18k
            gx_pattern1_clist_has_trans(pdcolor) ){
4130
            /* In this case, we need to push a transparency group
4131
               and tile the pattern color, which is stored in
4132
               a pdf14 device buffer in the ctile object memember
4133
               variable ttrans */
4134
#if RAW_DUMP
4135
            /* Since we do not get a put_image to view what
4136
               we have do it now */
4137
            if (gx_pattern1_get_transptr(pdcolor) != NULL) {
4138
                const pdf14_device * ppatdev14 = (const pdf14_device *)
4139
                                pdcolor->colors.pattern.p_tile->ttrans->pdev14;
4140
                if (ppatdev14 != NULL) {  /* can occur during clist reading */
4141
                    byte *buf_ptr = ppatdev14->ctx->stack->data  +
4142
                        ppatdev14->ctx->stack->rect.p.y *
4143
                        ppatdev14->ctx->stack->rowstride +
4144
                        ppatdev14->ctx->stack->rect.p.x;
4145
                    dump_raw_buffer(ppatdev14->ctx->memory,
4146
                                    (ppatdev14->ctx->stack->rect.q.y -
4147
                                     ppatdev14->ctx->stack->rect.p.y),
4148
                                    (ppatdev14->ctx->stack->rect.q.x -
4149
                                     ppatdev14->ctx->stack->rect.p.x),
4150
                                    ppatdev14->ctx->stack->n_planes,
4151
                                    ppatdev14->ctx->stack->planestride,
4152
                                    ppatdev14->ctx->stack->rowstride,
4153
                                    "Pattern_Fill", buf_ptr,
4154
                                    ppatdev14->ctx->stack->deep);
4155
                    global_index++;
4156
                } else {
4157
                     gx_pattern_trans_t *patt_trans =
4158
                                        pdcolor->colors.pattern.p_tile->ttrans;
4159
                     dump_raw_buffer(patt_trans->mem,
4160
                                     patt_trans->rect.q.y-patt_trans->rect.p.y,
4161
                                     patt_trans->rect.q.x-patt_trans->rect.p.x,
4162
                                     patt_trans->n_chan,
4163
                                     patt_trans->planestride, patt_trans->rowstride,
4164
                                     "Pattern_Fill_clist",
4165
                                     patt_trans->transbytes +
4166
                                         patt_trans->rect.p.y * patt_trans->rowstride +
4167
                                         (patt_trans->rect.p.x<<patt_trans->deep),
4168
                                     patt_trans->deep);
4169
                    global_index++;
4170
                }
4171
            }
4172
#endif
4173
1.60k
            pdf14_set_marking_params(dev, &new_pgs);
4174
1.60k
            code = pdf14_tile_pattern_fill(dev, &new_pgs, ppath,
4175
1.60k
                params, pdcolor, pcpath);
4176
1.60k
            new_pgs.trans_device = NULL;
4177
1.60k
            new_pgs.has_transparency = false;
4178
1.60k
            return code;
4179
1.60k
        }
4180
2.18k
    }
4181
989k
    if (gx_dc_is_pattern2_color(pdcolor) ||
4182
989k
        pdcolor->type == &gx_dc_devn_masked) {
4183
        /* Non-idempotent blends require a transparency
4184
         * group to be pushed because shadings might
4185
         * paint several pixels twice. */
4186
0
        push_group = pgs->fillconstantalpha != 1.0 ||
4187
0
               !blend_is_idempotent(gs_currentblendmode(pgs));
4188
0
        pinst =
4189
0
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
4190
0
        pinst->saved->has_transparency = true;
4191
        /* The transparency color space operations are driven
4192
           by the pdf14 clist writer device.  */
4193
0
        pinst->saved->trans_device = dev;
4194
0
    }
4195
989k
    if (push_group) {
4196
0
        gs_fixed_rect box;
4197
0
        if (pcpath)
4198
0
            gx_cpath_outer_box(pcpath, &box);
4199
0
        else
4200
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4201
0
        if (ppath) {
4202
0
            gs_fixed_rect path_box;
4203
4204
0
            gx_path_bbox(ppath, &path_box);
4205
0
            if (box.p.x < path_box.p.x)
4206
0
                box.p.x = path_box.p.x;
4207
0
            if (box.p.y < path_box.p.y)
4208
0
                box.p.y = path_box.p.y;
4209
0
            if (box.q.x > path_box.q.x)
4210
0
                box.q.x = path_box.q.x;
4211
0
            if (box.q.y > path_box.q.y)
4212
0
                box.q.y = path_box.q.y;
4213
0
        }
4214
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4215
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4216
0
    } else
4217
989k
        update_lop_for_pdf14(&new_pgs, pdcolor);
4218
989k
    pdf14_set_marking_params(dev, &new_pgs);
4219
989k
    if (code >= 0) {
4220
989k
        new_pgs.trans_device = dev;
4221
989k
        new_pgs.has_transparency = true;
4222
        /* ppath can permissibly be NULL here, if we want to have a
4223
         * shading or a pattern fill the clipping path. This upsets
4224
         * coverity, which is not smart enough to realise that the
4225
         * validity of a NULL ppath depends on the type of pdcolor.
4226
         * We'll mark it as a false positive. */
4227
989k
        code = gx_default_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4228
989k
        new_pgs.trans_device = NULL;
4229
989k
        new_pgs.has_transparency = false;
4230
989k
    }
4231
989k
    if (code >= 0 && push_group) {
4232
0
        code = pop_shfill_group(&new_pgs);
4233
0
        pdf14_set_marking_params(dev, pgs);
4234
0
    }
4235
989k
    if (pinst != NULL){
4236
0
        pinst->saved->trans_device = NULL;
4237
0
    }
4238
989k
    return code;
4239
990k
}
4240
4241
static  int
4242
pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs,
4243
                             gx_path *ppath, const gx_stroke_params *params,
4244
                             const gx_drawing_color *pdcolor,
4245
                             const gx_clip_path *pcpath)
4246
129k
{
4247
129k
    gs_gstate new_pgs = *pgs;
4248
129k
    int push_group = 0;
4249
129k
    int code = 0;
4250
4251
129k
    if (pdcolor == NULL)
4252
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4253
4254
129k
    code = pdf14_initialize_ctx(dev, dev->color_info.num_components,
4255
129k
        dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, pgs);
4256
129k
    if (code < 0)
4257
0
        return code;
4258
4259
129k
    if (gx_dc_is_pattern2_color(pdcolor)) {
4260
        /* Non-idempotent blends require a transparency
4261
         * group to be pushed because shadings might
4262
         * paint several pixels twice. */
4263
0
        push_group = pgs->strokeconstantalpha != 1.0 ||
4264
0
               !blend_is_idempotent(gs_currentblendmode(pgs));
4265
0
    }
4266
129k
    if (push_group) {
4267
0
        gs_fixed_rect box;
4268
0
        if (pcpath)
4269
0
            gx_cpath_outer_box(pcpath, &box);
4270
0
        else
4271
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4272
4273
        /* For fill_path, we accept ppath == NULL to mean
4274
         * fill the entire clipping region. That makes no
4275
         * sense for stroke_path, hence ppath is always non
4276
         * NULL here. */
4277
0
        {
4278
0
            gs_fixed_rect path_box;
4279
0
            gs_fixed_point expansion;
4280
4281
0
            gx_path_bbox(ppath, &path_box);
4282
            /* Expand the path bounding box by the scaled line width. */
4283
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
4284
                /* The expansion is so large it caused a limitcheck. */
4285
0
                path_box.p.x = path_box.p.y = min_fixed;
4286
0
                path_box.q.x = path_box.q.y = max_fixed;
4287
0
            } else {
4288
0
                expansion.x += pgs->fill_adjust.x;
4289
0
                expansion.y += pgs->fill_adjust.y;
4290
                /*
4291
                 * It's theoretically possible for the following computations to
4292
                 * overflow, so we need to check for this.
4293
                 */
4294
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
4295
0
                                path_box.p.x - expansion.x);
4296
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
4297
0
                                path_box.p.y - expansion.y);
4298
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
4299
0
                                path_box.q.x + expansion.x);
4300
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
4301
0
                                path_box.q.y + expansion.y);
4302
0
            }
4303
0
            if (box.p.x < path_box.p.x)
4304
0
                box.p.x = path_box.p.x;
4305
0
            if (box.p.y < path_box.p.y)
4306
0
                box.p.y = path_box.p.y;
4307
0
            if (box.q.x > path_box.q.x)
4308
0
                box.q.x = path_box.q.x;
4309
0
            if (box.q.y > path_box.q.y)
4310
0
                box.q.y = path_box.q.y;
4311
0
        }
4312
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4313
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
4314
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4315
0
    } else
4316
129k
        update_lop_for_pdf14(&new_pgs, pdcolor);
4317
129k
    pdf14_set_marking_params(dev, &new_pgs);
4318
129k
    if (code >= 0) {
4319
129k
        PDF14_OP_FS_STATE save_op_state = ((pdf14_device *)dev)->op_state;
4320
4321
129k
        ((pdf14_device*)dev)->op_state = PDF14_OP_STATE_STROKE;
4322
129k
        code = gx_default_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4323
129k
        ((pdf14_device*)dev)->op_state = save_op_state;
4324
129k
    }
4325
129k
    if (code >= 0 && push_group) {
4326
0
        code = pop_shfill_group(&new_pgs);
4327
0
        pdf14_set_marking_params(dev, pgs);
4328
0
    }
4329
4330
129k
    return code;
4331
129k
}
4332
4333
static int
4334
pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
4335
    const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill,
4336
    const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke,
4337
    const gx_clip_path *pcpath)
4338
7.48k
{
4339
7.48k
    union {
4340
7.48k
        const gs_gstate *cpgs;
4341
7.48k
        gs_gstate *pgs;
4342
7.48k
    } const_breaker;
4343
7.48k
    gs_gstate *pgs;
4344
7.48k
    int code, code2;
4345
7.48k
    gs_transparency_group_params_t params = { 0 };
4346
7.48k
    gs_fixed_rect clip_bbox;
4347
7.48k
    gs_rect bbox, group_stroke_box;
4348
7.48k
    gs_fixed_rect path_bbox;
4349
7.48k
    int expansion_code;
4350
7.48k
    gs_fixed_point expansion;
4351
7.48k
    pdf14_device *p14dev = (pdf14_device *)dev;
4352
7.48k
    float stroke_alpha = cpgs->strokeconstantalpha;
4353
7.48k
    float fill_alpha = cpgs->fillconstantalpha;
4354
7.48k
    gs_blend_mode_t blend_mode = cpgs->blend_mode;
4355
7.48k
    PDF14_OP_FS_STATE save_op_state = p14dev->op_state;
4356
4357
    /* Break const just once, neatly */
4358
7.48k
    const_breaker.cpgs = cpgs;
4359
7.48k
    pgs = const_breaker.pgs;
4360
4361
7.48k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
4362
7.48k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
4363
0
        return 0;
4364
4365
7.48k
    code = pdf14_initialize_ctx(dev, dev->color_info.num_components,
4366
7.48k
        dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, cpgs);
4367
7.48k
    if (code < 0)
4368
0
        return code;
4369
4370
7.48k
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
4371
7.48k
    if (code < 0 && code != gs_error_unknownerror)
4372
0
        return code;
4373
7.48k
    if (code == gs_error_unknownerror) {
4374
        /* didn't get clip box from gx_curr_fixed_bbox */
4375
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
4376
0
        clip_bbox.q.x = int2fixed(dev->width);
4377
0
        clip_bbox.q.y = int2fixed(dev->height);
4378
0
    }
4379
7.48k
    if (pcpath)
4380
7.48k
        rect_intersect(clip_bbox, pcpath->outer_box);
4381
4382
    /* expand the ppath using stroke expansion rule, then intersect it */
4383
7.48k
    code = gx_path_bbox(ppath, &path_bbox);
4384
7.48k
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0)
4385
3.67k
        return 0;    /* ignore empty path */
4386
3.80k
    if (code < 0)
4387
0
        return code;
4388
3.80k
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
4389
3.80k
    if (expansion_code >= 0) {
4390
3.41k
        path_bbox.p.x -= expansion.x;
4391
3.41k
        path_bbox.p.y -= expansion.y;
4392
3.41k
        path_bbox.q.x += expansion.x;
4393
3.41k
        path_bbox.q.y += expansion.y;
4394
3.41k
    }
4395
3.80k
    rect_intersect(path_bbox, clip_bbox);
4396
3.80k
    bbox.p.x = fixed2float(path_bbox.p.x);
4397
3.80k
    bbox.p.y = fixed2float(path_bbox.p.y);
4398
3.80k
    bbox.q.x = fixed2float(path_bbox.q.x);
4399
3.80k
    bbox.q.y = fixed2float(path_bbox.q.y);
4400
4401
3.80k
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
4402
3.80k
    if (code < 0)
4403
2
        return code;
4404
3.80k
    if (p14dev->overprint != pgs->overprint || p14dev->stroke_overprint != pgs->stroke_overprint) {
4405
0
        p14dev->overprint = pgs->overprint;
4406
0
        p14dev->stroke_overprint = pgs->stroke_overprint;
4407
0
    }
4408
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
4409
3.80k
    if (fill_alpha == stroke_alpha &&
4410
3.80k
        p14dev->overprint && p14dev->stroke_overprint &&
4411
3.80k
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
4412
        /* Push a non-isolated non-knockout group with alpha = 1.0 and
4413
           compatible overprint mode.  Group will be composited with
4414
           original alpha and blend mode */
4415
0
        params.Isolated = false;
4416
0
        params.group_color_type = UNKNOWN;
4417
0
        params.Knockout = false;
4418
0
        params.page_group = false;
4419
0
        params.group_opacity = 1.0;
4420
0
        params.group_shape = fill_alpha;
4421
4422
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
4423
0
        code = pdf14_begin_transparency_group(dev, &params,
4424
0
                                              &group_stroke_box, pgs, dev->memory);
4425
0
        if (code < 0)
4426
0
            return code;
4427
4428
        /* Change fill alpha to 1.0 and blend mode to compatible overprint for actual drawing */
4429
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
4430
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4431
4432
0
        p14dev->op_state = PDF14_OP_STATE_FILL;
4433
0
        code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
4434
0
        if (code < 0)
4435
0
            goto cleanup;
4436
4437
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
4438
0
        gs_swapcolors_quick(pgs); /* flips stroke_color_index (to stroke) */
4439
0
        p14dev->op_state = PDF14_OP_STATE_STROKE;
4440
0
        code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
4441
0
        gs_swapcolors_quick(pgs); /* this flips pgs->stroke_color_index back as well */
4442
0
        if (code < 0)
4443
0
            goto cleanup;       /* bail out (with colors swapped back to fill) */
4444
4445
3.80k
    } else {
4446
        /* Push a non-isolated knockout group. Do not change the alpha or
4447
            blend modes. Note: we need to draw those that have alpha = 0 */
4448
3.80k
        params.Isolated = false;
4449
3.80k
        params.group_color_type = UNKNOWN;
4450
3.80k
        params.Knockout = true;
4451
3.80k
        params.page_group = false;
4452
3.80k
        params.group_shape = 1.0;
4453
3.80k
        params.group_opacity = 1.0;
4454
4455
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
4456
3.80k
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
4457
3.80k
        code = pdf14_begin_transparency_group(dev, &params, &group_stroke_box,
4458
3.80k
                                              pgs, dev->memory);
4459
4460
        /* restore blend mode for actual drawing in the group */
4461
3.80k
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4462
4463
        /* If we are in an overprint situation, set the blend mode to compatible
4464
            overprint */
4465
3.80k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4466
3.80k
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4467
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4468
3.80k
        code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
4469
3.80k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4470
3.80k
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4471
0
            (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4472
3.80k
        if (code < 0)
4473
0
            goto cleanup;
4474
4475
        /* Note that the stroke can end up doing fill methods */
4476
3.80k
        (void)gs_setfillconstantalpha(pgs, stroke_alpha);
4477
4478
3.80k
        gs_swapcolors_quick(pgs);
4479
3.80k
        p14dev->op_state = PDF14_OP_STATE_STROKE;
4480
3.80k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->stroke_overprint &&
4481
3.80k
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4482
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4483
3.80k
        code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
4484
        /* Don't need to restore blendmode here, as it will be restored below. */
4485
3.80k
        gs_swapcolors_quick(pgs);
4486
3.80k
        if (code < 0)
4487
0
            goto cleanup;
4488
        /* Bug 703324 we need to reset the fill constant alpha in the graphics
4489
         * state to the correct saved value. We also need to reset the 'opacity' member of the
4490
         * device, because some device methods (eg fill_masked_image) don't take a graphics
4491
         * state pointer as a parameter and so are unable to set the opacity value themselves.
4492
         * We therefore need to make sure it is set according to the current fill state.
4493
         */
4494
3.80k
        (void)gs_setfillconstantalpha(pgs, fill_alpha);
4495
3.80k
        pdf14_set_marking_params(dev, pgs);
4496
3.80k
    }
4497
4498
3.80k
cleanup:
4499
    /* Restore the state */
4500
3.80k
    p14dev->op_state = save_op_state;
4501
3.80k
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4502
3.80k
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
4503
3.80k
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
4504
4505
3.80k
    code2 = pdf14_end_transparency_group(dev, pgs);
4506
3.80k
    if (code2 < 0) {
4507
        /* At this point things have gone very wrong. We should just shut down */
4508
0
        code = gs_abort_pdf14trans_device(pgs);
4509
0
        return code2;
4510
0
    }
4511
3.80k
    return code;
4512
3.80k
}
4513
4514
static int
4515
pdf14_copy_alpha(gx_device * dev, const byte * data, int data_x,
4516
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4517
                      gx_color_index color, int depth)
4518
0
{
4519
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4520
0
                                  color, NULL, depth, false);
4521
0
}
4522
4523
static int
4524
pdf14_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
4525
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4526
                      const gx_drawing_color *pdcolor, int depth)
4527
0
{
4528
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4529
0
                                  0, pdcolor, depth, true);
4530
0
}
4531
4532
static int
4533
do_pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
4534
                          int aa_raster, gx_bitmap_id id, int x, int y,
4535
                          int w, int h, gx_color_index color,
4536
                          const gx_device_color *pdc, int depth, bool devn)
4537
0
{
4538
0
    const byte *aa_row;
4539
0
    pdf14_device *pdev = (pdf14_device *)dev;
4540
0
    pdf14_buf *buf = pdev->ctx->stack;
4541
0
    int i, j, k;
4542
0
    byte *line, *dst_ptr;
4543
0
    byte src[PDF14_MAX_PLANES];
4544
0
    byte dst[PDF14_MAX_PLANES] = { 0 };
4545
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4546
0
    bool additive = pdev->ctx->additive;
4547
0
    int rowstride = buf->rowstride;
4548
0
    int planestride = buf->planestride;
4549
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4550
0
    bool has_alpha_g = buf->has_alpha_g;
4551
0
    bool has_shape = buf->has_shape;
4552
0
    bool has_tags = buf->has_tags;
4553
0
    bool knockout = buf->knockout;
4554
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4555
0
        blend_mode == BLEND_MODE_Compatible ||
4556
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4557
0
    int num_chan = buf->n_chan;
4558
0
    int num_comp = num_chan - 1;
4559
0
    int shape_off = num_chan * planestride;
4560
0
    int alpha_g_off = shape_off + (has_shape ? planestride : 0);
4561
0
    int tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4562
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4563
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
4564
0
                                 pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4565
0
    gx_color_index comps;
4566
0
    byte shape = 0; /* Quiet compiler. */
4567
0
    byte src_alpha;
4568
0
    int alpha2_aa, alpha_aa, sx;
4569
0
    int alpha_aa_act;
4570
0
    int xoff;
4571
0
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
4572
0
    int shift = 8;
4573
4574
0
    if (buf->data == NULL)
4575
0
        return 0;
4576
0
    aa_row = data;
4577
0
    if (has_tags) {
4578
0
        curr_tag = (color >> (num_comp*8)) & 0xff;
4579
0
    }
4580
4581
0
    if (devn) {
4582
0
        if (additive) {
4583
0
            for (j = 0; j < num_comp; j++) {
4584
0
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
4585
0
            }
4586
0
        } else {
4587
0
            for (j = 0; j < num_comp; j++) {
4588
0
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
4589
0
            }
4590
0
        }
4591
0
    } else
4592
0
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
4593
0
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
4594
0
    if (has_shape)
4595
0
        shape = (byte)floor (255 * pdev->shape + 0.5);
4596
    /* Limit the area we write to the bounding rectangle for this buffer */
4597
0
    if (x < buf->rect.p.x) {
4598
0
        xoff = data_x + buf->rect.p.x - x;
4599
0
        w += x - buf->rect.p.x;
4600
0
        x = buf->rect.p.x;
4601
0
    } else {
4602
0
        xoff = data_x;
4603
0
    }
4604
0
    if (y < buf->rect.p.y) {
4605
0
      h += y - buf->rect.p.y;
4606
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4607
0
      y = buf->rect.p.y;
4608
0
    }
4609
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
4610
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
4611
    /* Update the dirty rectangle. */
4612
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
4613
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
4614
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
4615
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
4616
0
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4617
4618
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
4619
0
        dst_ptr = line;
4620
0
        sx = xoff;
4621
0
        for (i = 0; i < w; ++i, ++sx) {
4622
            /* Complement the components for subtractive color spaces */
4623
0
            if (additive) {
4624
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
4625
0
                    dst[k] = dst_ptr[k * planestride];
4626
0
            } else { /* Complement the components for subtractive color spaces */
4627
0
                for (k = 0; k < num_comp; ++k)
4628
0
                    dst[k] = 255 - dst_ptr[k * planestride];
4629
0
                dst[num_comp] = dst_ptr[num_comp * planestride];  /* alpha */
4630
0
            }
4631
            /* Get the aa alpha from the buffer */
4632
0
            switch(depth)
4633
0
            {
4634
0
            case 2:  /* map 0 - 3 to 0 - 255 */
4635
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
4636
0
                break;
4637
0
            case 4:
4638
0
                alpha2_aa = aa_row[sx >> 1];
4639
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
4640
0
                break;
4641
0
            case 8:
4642
0
                alpha_aa = aa_row[sx];
4643
0
                break;
4644
0
            default:
4645
0
                return_error(gs_error_rangecheck);
4646
0
            }
4647
0
            if (alpha_aa != 0) {  /* This does happen */
4648
0
                if (alpha_aa != 255) {
4649
                    /* We have an alpha value from aa */
4650
0
                    alpha_aa_act = alpha_aa;
4651
0
                    if (src_alpha != 255) {
4652
                        /* Need to combine it with the existing alpha */
4653
0
                        int tmp = src_alpha * alpha_aa_act + 0x80;
4654
0
                        alpha_aa_act = (tmp + (tmp >> 8)) >> 8;
4655
0
                    }
4656
                    /* Set our source alpha value appropriately */
4657
0
                    src[num_comp] = alpha_aa_act;
4658
0
                } else {
4659
                    /* We may have to reset this is it was changed as we
4660
                       moved across the row */
4661
0
                    src[num_comp] = src_alpha;
4662
0
                }
4663
0
                if (knockout) {
4664
0
                    if (buf->isolated) {
4665
0
                        art_pdf_knockoutisolated_group_8(dst, src, num_comp);
4666
0
                    } else {
4667
0
                        art_pdf_composite_knockout_8(dst, src, num_comp,
4668
0
                            blend_mode, pdev->blend_procs, pdev);
4669
0
                    }
4670
0
                } else {
4671
0
                    art_pdf_composite_pixel_alpha_8(dst, src, num_comp, blend_mode, num_comp,
4672
0
                                                    pdev->blend_procs, pdev);
4673
0
                }
4674
                /* Complement the results for subtractive color spaces */
4675
0
                if (additive) {
4676
0
                    for (k = 0; k < num_chan; ++k)
4677
0
                        dst_ptr[k * planestride] = dst[k];
4678
0
                } else {
4679
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
4680
0
                        for (k = 0, comps = drawn_comps; comps != 0;
4681
0
                                ++k, comps >>= 1) {
4682
0
                            if ((comps & 0x1) != 0) {
4683
0
                                dst_ptr[k * planestride] = 255 - dst[k];
4684
0
                            }
4685
0
                        }
4686
                        /* The alpha channel */
4687
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4688
0
                    } else {
4689
0
                        for (k = 0; k < num_comp; ++k)
4690
0
                            dst_ptr[k * planestride] = 255 - dst[k];
4691
                        /* The alpha channel */
4692
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4693
0
                    }
4694
0
                }
4695
0
                if (has_alpha_g) {
4696
0
                    int tmp = (255 - dst_ptr[alpha_g_off]) * (255 - src[num_comp]) + 0x80;
4697
0
                    dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4698
0
                }
4699
0
                if (has_shape) {
4700
0
                    int tmp = (255 - dst_ptr[shape_off]) * (255 - shape) + 0x80;
4701
0
                    dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4702
0
                }
4703
0
                if (has_tags) {
4704
                    /* If alpha is 100% then set to curr_tag, else or */
4705
                    /* other than Normal BM, we always OR */
4706
0
                    if (src[num_comp] == 255 && tag_blend) {
4707
0
                        dst_ptr[tag_off] = curr_tag;
4708
0
                    } else {
4709
0
                        dst_ptr[tag_off] |= curr_tag;
4710
0
                    }
4711
0
                }
4712
0
            }
4713
0
            ++dst_ptr;
4714
0
        }
4715
0
        line += rowstride;
4716
0
    }
4717
0
    return 0;
4718
0
}
4719
4720
static int
4721
do_pdf14_copy_alpha_color_16(gx_device * dev, const byte * data, int data_x,
4722
                             int aa_raster, gx_bitmap_id id, int x, int y,
4723
                             int w, int h, gx_color_index color,
4724
                             const gx_device_color *pdc, int depth, bool devn)
4725
0
{
4726
0
    const byte *aa_row;
4727
0
    pdf14_device *pdev = (pdf14_device *)dev;
4728
0
    pdf14_buf *buf = pdev->ctx->stack;
4729
0
    int i, j, k;
4730
0
    byte *line;
4731
0
    uint16_t *dst_ptr;
4732
0
    uint16_t src[PDF14_MAX_PLANES];
4733
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
4734
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4735
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4736
0
        blend_mode == BLEND_MODE_Compatible ||
4737
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4738
0
    bool additive = pdev->ctx->additive;
4739
0
    int rowstride = buf->rowstride;
4740
0
    int planestride = buf->planestride;
4741
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4742
0
    bool has_alpha_g = buf->has_alpha_g;
4743
0
    bool has_shape = buf->has_shape;
4744
0
    bool has_tags = buf->has_tags;
4745
0
    bool knockout = buf->knockout;
4746
0
    int num_chan = buf->n_chan;
4747
0
    int num_comp = num_chan - 1;
4748
0
    int shape_off = num_chan * planestride;
4749
0
    int alpha_g_off = shape_off + (has_shape ? planestride : 0);
4750
0
    int tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4751
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4752
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
4753
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4754
0
    gx_color_index comps;
4755
0
    uint16_t shape = 0; /* Quiet compiler. */
4756
0
    uint16_t src_alpha;
4757
0
    int alpha2_aa, alpha_aa, sx;
4758
0
    int alpha_aa_act;
4759
0
    int xoff;
4760
4761
0
    if (buf->data == NULL)
4762
0
        return 0;
4763
0
    aa_row = data;
4764
0
    if (has_tags) {
4765
0
        curr_tag = (color >> (num_comp*16)) & 0xff;
4766
0
    }
4767
4768
0
    if (devn) {
4769
0
        if (additive) {
4770
0
            for (j = 0; j < num_comp; j++) {
4771
0
                src[j] = pdc->colors.devn.values[j];
4772
0
            }
4773
0
        } else {
4774
0
            for (j = 0; j < num_comp; j++) {
4775
0
                src[j] = 65535 - pdc->colors.devn.values[j];
4776
0
            }
4777
0
        }
4778
0
    } else
4779
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
4780
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
4781
0
    if (has_shape)
4782
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
4783
    /* Limit the area we write to the bounding rectangle for this buffer */
4784
0
    if (x < buf->rect.p.x) {
4785
0
        xoff = data_x + buf->rect.p.x - x;
4786
0
        w += x - buf->rect.p.x;
4787
0
        x = buf->rect.p.x;
4788
0
    } else {
4789
0
        xoff = data_x;
4790
0
    }
4791
0
    if (y < buf->rect.p.y) {
4792
0
      h += y - buf->rect.p.y;
4793
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4794
0
      y = buf->rect.p.y;
4795
0
    }
4796
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
4797
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
4798
    /* Update the dirty rectangle. */
4799
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
4800
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
4801
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
4802
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
4803
0
    line = buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
4804
4805
0
    planestride >>= 1;
4806
0
    rowstride   >>= 1;
4807
0
    alpha_g_off >>= 1;
4808
0
    shape_off   >>= 1;
4809
0
    tag_off     >>= 1;
4810
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
4811
0
        dst_ptr = (uint16_t *)(void *)line;
4812
0
        sx = xoff;
4813
0
        for (i = 0; i < w; ++i, ++sx) {
4814
            /* Complement the components for subtractive color spaces */
4815
0
            if (additive) {
4816
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
4817
0
                    dst[k] = dst_ptr[k * planestride];
4818
0
            } else { /* Complement the components for subtractive color spaces */
4819
0
                for (k = 0; k < num_comp; ++k)
4820
0
                    dst[k] = 65535 - dst_ptr[k * planestride];
4821
0
                dst[num_comp] = dst_ptr[num_comp * planestride];  /* alpha */
4822
0
            }
4823
            /* Get the aa alpha from the buffer */
4824
0
            switch(depth)
4825
0
            {
4826
0
            case 2:  /* map 0 - 3 to 0 - 255 */
4827
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
4828
0
                break;
4829
0
            case 4:
4830
0
                alpha2_aa = aa_row[sx >> 1];
4831
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
4832
0
                break;
4833
0
            case 8:
4834
0
                alpha_aa = aa_row[sx];
4835
0
                break;
4836
0
            default:
4837
0
                return_error(gs_error_rangecheck);
4838
0
            }
4839
0
            if (alpha_aa != 0) {  /* This does happen */
4840
0
                if (alpha_aa != 255) {
4841
                    /* We have an alpha value from aa */
4842
0
                    alpha_aa_act = alpha_aa * 0x101;
4843
0
                    if (src_alpha != 65535) {
4844
                        /* Need to combine it with the existing alpha */
4845
0
                        int tmp = src_alpha * alpha_aa_act + 0x8000;
4846
0
                        alpha_aa_act = (tmp + (tmp >> 16)) >> 16;
4847
0
                    }
4848
                    /* Set our source alpha value appropriately */
4849
0
                    src[num_comp] = alpha_aa_act;
4850
0
                } else {
4851
                    /* We may have to reset this is it was changed as we
4852
                       moved across the row */
4853
0
                    src[num_comp] = src_alpha;
4854
0
                }
4855
0
                if (knockout) {
4856
0
                    if (buf->isolated) {
4857
0
                        art_pdf_knockoutisolated_group_16(dst, src, num_comp);
4858
0
                    } else {
4859
0
                        art_pdf_composite_knockout_16(dst, src, num_comp,
4860
0
                            blend_mode, pdev->blend_procs, pdev);
4861
0
                    }
4862
0
                } else {
4863
0
                    art_pdf_composite_pixel_alpha_16(dst, src, num_comp, blend_mode, num_comp,
4864
0
                                                     pdev->blend_procs, pdev);
4865
0
                }
4866
                /* Complement the results for subtractive color spaces */
4867
0
                if (additive) {
4868
0
                    for (k = 0; k < num_chan; ++k)
4869
0
                        dst_ptr[k * planestride] = dst[k];
4870
0
                } else {
4871
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
4872
0
                        for (k = 0, comps = drawn_comps; comps != 0;
4873
0
                                ++k, comps >>= 1) {
4874
0
                            if ((comps & 0x1) != 0) {
4875
0
                                dst_ptr[k * planestride] = 65535 - dst[k];
4876
0
                            }
4877
0
                        }
4878
                        /* The alpha channel */
4879
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4880
0
                    } else {
4881
0
                        for (k = 0; k < num_comp; ++k)
4882
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
4883
                        /* The alpha channel */
4884
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4885
0
                    }
4886
0
                }
4887
0
                if (has_alpha_g) {
4888
0
                    int tmp = (65535 - dst_ptr[alpha_g_off]) * (65535 - src[num_comp]) + 0x8000;
4889
0
                    dst_ptr[alpha_g_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
4890
0
                }
4891
0
                if (has_shape) {
4892
0
                    int tmp = (65535 - dst_ptr[shape_off]) * (65535 - shape) + 0x8000;
4893
0
                    dst_ptr[shape_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
4894
0
                }
4895
0
                if (has_tags) {
4896
                    /* If alpha is 100% then set to curr_tag, else or */
4897
                    /* other than Normal BM, we always OR */
4898
0
                    if (src[num_comp] == 65535 && tag_blend) {
4899
0
                        dst_ptr[tag_off] = curr_tag;
4900
0
                    } else {
4901
0
                        dst_ptr[tag_off] |= curr_tag;
4902
0
                    }
4903
0
                }
4904
0
            }
4905
0
            ++dst_ptr;
4906
0
        }
4907
0
        line += rowstride;
4908
0
    }
4909
0
    return 0;
4910
0
}
4911
4912
static int
4913
pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
4914
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4915
                      gx_color_index color, const gx_device_color *pdc,
4916
                      int depth, bool devn)
4917
0
{
4918
0
    bool deep = device_is_deep(dev);
4919
0
    int code;
4920
4921
0
    code = pdf14_initialize_ctx(dev, dev->color_info.num_components,
4922
0
        dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, NULL);
4923
0
    if (code < 0)
4924
0
        return code;
4925
4926
0
    if (deep)
4927
0
        return do_pdf14_copy_alpha_color_16(dev, data, data_x, aa_raster,
4928
0
                                            id, x, y, w, h,
4929
0
                                            color, pdc, depth, devn);
4930
0
    else
4931
0
        return do_pdf14_copy_alpha_color(dev, data, data_x, aa_raster,
4932
0
                                         id, x, y, w, h,
4933
0
                                         color, pdc, depth, devn);
4934
0
}
4935
4936
static  int
4937
pdf14_fill_mask(gx_device * orig_dev,
4938
                     const byte * data, int dx, int raster, gx_bitmap_id id,
4939
                     int x, int y, int w, int h,
4940
                     const gx_drawing_color * pdcolor, int depth,
4941
                     gs_logical_operation_t lop, const gx_clip_path * pcpath)
4942
1.07M
{
4943
1.07M
    gx_device *dev;
4944
1.07M
    pdf14_device *p14dev = (pdf14_device *)orig_dev;
4945
1.07M
    gx_device_clip cdev;
4946
1.07M
    gx_color_tile *ptile = NULL;
4947
1.07M
    int code = 0;
4948
1.07M
    gs_int_rect group_rect;
4949
1.07M
    gx_pattern_trans_t *fill_trans_buffer = NULL;
4950
1.07M
    bool has_pattern_trans = false;
4951
1.07M
    cmm_dev_profile_t *dev_profile;
4952
4953
1.07M
    if (pdcolor == NULL)
4954
0
        return_error(gs_error_unknownerror);  /* color must be defined */
4955
4956
1.07M
    code = pdf14_initialize_ctx(orig_dev, orig_dev->color_info.num_components,
4957
1.07M
        orig_dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, NULL);
4958
1.07M
    if (code < 0)
4959
0
        return code;
4960
4961
    /* If we are doing a fill with a pattern that has a transparency then
4962
       go ahead and do a push and a pop of the transparency group */
4963
1.07M
    if (gx_dc_is_pattern1_color(pdcolor)) {
4964
0
        if( gx_pattern1_get_transptr(pdcolor) != NULL) {
4965
0
            ptile = pdcolor->colors.pattern.p_tile;
4966
            /* Set up things in the ptile so that we get the proper
4967
               blending etc */
4968
            /* Set the blending procs and the is_additive setting based
4969
               upon the number of channels */
4970
0
            if (ptile->ttrans->n_chan-1 < 4) {
4971
0
                ptile->ttrans->blending_procs = &rgb_blending_procs;
4972
0
                ptile->ttrans->is_additive = true;
4973
0
            } else {
4974
0
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
4975
0
                ptile->ttrans->is_additive = false;
4976
0
            }
4977
            /* Set the procs so that we use the proper filling method. */
4978
0
            gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
4979
            /* Based upon if the tiles overlap pick the type of rect
4980
               fill that we will want to use */
4981
0
            if (ptile->has_overlap) {
4982
                /* This one does blending since there is tile overlap */
4983
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
4984
0
            } else {
4985
                /* This one does no blending since there is no tile overlap */
4986
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
4987
0
            }
4988
            /* Push the group */
4989
0
            group_rect.p.x = x;
4990
0
            group_rect.p.y = max(0,y);
4991
0
            group_rect.q.x = x + w;
4992
0
            group_rect.q.y = y + h;
4993
0
            if (!(w <= 0 || h <= 0)) {
4994
4995
0
                pdf14_group_color_t *group_color_info = pdf14_clone_group_color_info((gx_device *) p14dev, p14dev->ctx->stack->group_color_info);
4996
0
                if (group_color_info == NULL)
4997
0
                    return gs_error_VMerror;
4998
4999
0
                code = pdf14_push_transparency_group(p14dev->ctx, &group_rect,
5000
0
                     1, 0, 65535, 65535, 65535, ptile->blending_mode, 0, 0,
5001
0
                     ptile->ttrans->n_chan-1, false, false, NULL, NULL,
5002
0
                     group_color_info, NULL, NULL);
5003
0
                if (code < 0)
5004
0
                    return code;
5005
                /* Set up the output buffer information now that we have
5006
                   pushed the group */
5007
0
                fill_trans_buffer = new_pattern_trans_buff(p14dev->memory);
5008
0
                pdf14_get_buffer_information((gx_device *) p14dev,
5009
0
                                              fill_trans_buffer, NULL, false);
5010
                /* Store this in the appropriate place in pdcolor.  This
5011
                   is released later after the mask fill */
5012
0
                ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5013
0
                has_pattern_trans = true;
5014
0
            }
5015
0
        }
5016
0
    }
5017
1.07M
    if (pcpath != 0) {
5018
222k
        gx_make_clip_device_on_stack(&cdev, pcpath, orig_dev);
5019
222k
        dev = (gx_device *) & cdev;
5020
222k
    } else
5021
849k
        dev = orig_dev;
5022
1.07M
    if (depth > 1) {
5023
        /****** CAN'T DO ROP OR HALFTONE WITH ALPHA ******/
5024
0
        code = (*dev_proc(dev, copy_alpha))
5025
0
            (dev, data, dx, raster, id, x, y, w, h,
5026
0
             gx_dc_pure_color(pdcolor), depth);
5027
1.07M
    } else {
5028
1.07M
        code = pdcolor->type->fill_masked(pdcolor, data, dx, raster, id,
5029
1.07M
                                          x, y, w, h, dev, lop, false);
5030
1.07M
    }
5031
1.07M
    if (has_pattern_trans) {
5032
0
        if (code >= 0)
5033
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5034
0
        if (code >= 0)
5035
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx,
5036
0
                                                p14dev->blend_procs,
5037
0
                                                p14dev->color_info.num_components,
5038
0
                                                dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5039
0
                                                orig_dev);
5040
0
        gs_free_object(p14dev->memory, ptile->ttrans->fill_trans_buffer,
5041
0
                       "pdf14_fill_mask");
5042
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5043
0
    }
5044
1.07M
    return code;
5045
1.07M
}
5046
5047
5048
5049
/* Used for filling rects when we are doing a fill with a pattern that
5050
   has transparency */
5051
static  int
5052
pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
5053
                        gx_path * ppath, const gx_fill_params * params,
5054
                        const gx_device_color * pdevc,
5055
                        const gx_clip_path * pcpath)
5056
1.60k
{
5057
1.60k
    int code;
5058
1.60k
    gs_gstate *pgs_noconst = (gs_gstate *)pgs; /* Break const. */
5059
1.60k
    gs_fixed_rect clip_box;
5060
1.60k
    gs_fixed_rect outer_box;
5061
1.60k
    pdf14_device * p14dev = (pdf14_device *)pdev;
5062
1.60k
    gs_int_rect rect;
5063
1.60k
    gx_clip_rect *curr_clip_rect;
5064
1.60k
    gx_color_tile *ptile = NULL;
5065
1.60k
    int k;
5066
1.60k
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5067
1.60k
    gs_int_point phase;  /* Needed during clist rendering for band offset */
5068
1.60k
    int n_chan_tile;
5069
1.60k
    gx_clip_path cpath_intersection;
5070
1.60k
    gx_path path_ttrans;
5071
1.60k
    gs_blend_mode_t blend_mode;
5072
1.60k
    pdf14_group_color_t *group_color_info;
5073
5074
1.60k
    if (ppath == NULL)
5075
0
        return_error(gs_error_unknownerror);  /* should not happen */
5076
1.60k
    if (pcpath != NULL) {
5077
1.60k
        code = gx_cpath_init_local_shared_nested(&cpath_intersection, pcpath, ppath->memory, 1);
5078
1.60k
    } else {
5079
0
        (*dev_proc(pdev, get_clipping_box)) (pdev, &clip_box);
5080
0
        gx_cpath_init_local(&cpath_intersection, ppath->memory);
5081
0
        code = gx_cpath_from_rectangle(&cpath_intersection, &clip_box);
5082
0
    }
5083
1.60k
    if (code < 0)
5084
0
        return code;
5085
1.60k
    code = gx_cpath_intersect_with_params(&cpath_intersection, ppath,
5086
1.60k
                                          params->rule, pgs_noconst, params);
5087
1.60k
    if (code < 0)
5088
0
        return code;
5089
    /* One (common) case worth optimising for is where we have a pattern that
5090
     * is positioned such that only one repeat of the tile is actually
5091
     * visible. In this case, we can restrict the size of the blending group
5092
     * we need to produce to be that of the actual area of the tile that is
5093
     * used. */
5094
1.60k
    ptile = pdevc->colors.pattern.p_tile;
5095
1.60k
    if (ptile->ttrans != NULL)
5096
1.60k
    {
5097
1.60k
        if ((cpath_intersection.outer_box.p.x < 0) ||
5098
1.60k
            (cpath_intersection.outer_box.p.y < 0) ||
5099
1.60k
            (cpath_intersection.outer_box.q.x > int2fixed(ptile->ttrans->width)) ||
5100
1.60k
            (cpath_intersection.outer_box.q.y > int2fixed(ptile->ttrans->height)))
5101
1.60k
        {
5102
            /* More than one repeat of the tile would be visible, so we can't
5103
             * use the optimisation here. (Actually, this test isn't quite
5104
             * right - it actually tests whether more than the '0th' repeat
5105
             * of the tile is visible. A better test would test if just one
5106
             * repeat of the tile was visible, irrespective of which one.
5107
             * This is (hopefully) relatively rare, and would make the code
5108
             * below more complex too, so we're ignoring that for now. If it
5109
             * becomes evident that it's a case that matters we can revisit
5110
             * it.) */
5111
1.60k
        } else {
5112
            /* Only the 0th repeat is visible. Restrict the size further to
5113
             * just the used area of that patch. */
5114
0
            gx_path_init_local(&path_ttrans, ppath->memory);
5115
0
            code = gx_path_add_rectangle(&path_ttrans,
5116
0
                                         int2fixed(ptile->ttrans->rect.p.x),
5117
0
                                         int2fixed(ptile->ttrans->rect.p.y),
5118
0
                                         int2fixed(ptile->ttrans->rect.q.x),
5119
0
                                         int2fixed(ptile->ttrans->rect.q.y));
5120
0
            if (code < 0)
5121
0
                return code;
5122
0
            code = gx_cpath_intersect(&cpath_intersection, &path_ttrans,
5123
0
                                      params->rule, pgs_noconst);
5124
0
            gx_path_free(&path_ttrans, "pdf14_tile_pattern_fill(path_ttrans)");
5125
0
            if (code < 0)
5126
0
                return code;
5127
0
        }
5128
1.60k
    }
5129
    /* Now let us push a transparency group into which we are
5130
     * going to tile the pattern.  */
5131
1.60k
    if (ppath != NULL) {
5132
1.60k
        pdf14_device save_pdf14_dev;    /* save area for p14dev */
5133
5134
1.60k
        gx_cpath_outer_box(&cpath_intersection, &outer_box);
5135
1.60k
        rect.p.x = fixed2int(outer_box.p.x);
5136
1.60k
        rect.p.y = fixed2int(outer_box.p.y);
5137
1.60k
        rect.q.x = fixed2int_ceiling(outer_box.q.x);
5138
1.60k
        rect.q.y = fixed2int_ceiling(outer_box.q.y);
5139
5140
        /* The color space of this group must be the same as that of the
5141
           tile.  Then when we pop the group, if there is a mismatch between
5142
           the tile color space and the current context we will do the proper
5143
           conversion.  In this way, we ensure that if the tile has any overlapping
5144
           occuring it will be blended in the proper manner i.e in the tile
5145
           underlying color space. */
5146
1.60k
        if (ptile->cdev == NULL) {
5147
1.60k
            if (ptile->ttrans == NULL)
5148
0
                return_error(gs_error_unknownerror);  /* should not happen */
5149
1.60k
            n_chan_tile = ptile->ttrans->n_chan;
5150
1.60k
        } else {
5151
0
            n_chan_tile = ptile->cdev->common.color_info.num_components+1;
5152
0
        }
5153
1.60k
        blend_mode = ptile->blending_mode;
5154
1.60k
        memcpy(&save_pdf14_dev, p14dev, sizeof(pdf14_device));
5155
5156
1.60k
        group_color_info = pdf14_clone_group_color_info(pdev, p14dev->ctx->stack->group_color_info);
5157
1.60k
        if (group_color_info == NULL)
5158
0
            return gs_error_VMerror;
5159
5160
1.60k
        code = pdf14_push_transparency_group(p14dev->ctx, &rect, 1, 0, (uint16_t)floor(65535 * p14dev->alpha + 0.5),
5161
1.60k
                                             (uint16_t)floor(65535 * p14dev->shape + 0.5), (uint16_t)floor(65535 * p14dev->opacity + 0.5),
5162
1.60k
                                              blend_mode, 0, 0, n_chan_tile - 1, false, false,
5163
1.60k
                                              NULL, NULL, group_color_info, pgs_noconst, pdev);
5164
1.60k
        if (code < 0)
5165
0
            return code;
5166
5167
        /* Set the blending procs and the is_additive setting based
5168
           upon the number of channels */
5169
1.60k
        if (ptile->cdev == NULL) {
5170
1.60k
            if (n_chan_tile-1 < 4) {
5171
1.60k
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5172
1.60k
                ptile->ttrans->is_additive = true;
5173
1.60k
            } else {
5174
0
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5175
0
                ptile->ttrans->is_additive = false;
5176
0
            }
5177
1.60k
        }
5178
        /* Now lets go through the rect list and fill with the pattern */
5179
        /* First get the buffer that we will be filling */
5180
1.60k
        if (ptile->cdev == NULL) {
5181
1.60k
            fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5182
1.60k
            pdf14_get_buffer_information(pdev, fill_trans_buffer, NULL, false);
5183
            /* Based upon if the tiles overlap pick the type of rect fill that we will
5184
               want to use */
5185
1.60k
            if (ptile->has_overlap) {
5186
                /* This one does blending since there is tile overlap */
5187
2
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5188
1.60k
            } else {
5189
                /* This one does no blending since there is no tile overlap */
5190
1.60k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5191
1.60k
            }
5192
            /* fill the rectangles */
5193
1.60k
            phase.x = pdevc->phase.x;
5194
1.60k
            phase.y = pdevc->phase.y;
5195
1.60k
            if (cpath_intersection.rect_list->list.head != NULL){
5196
0
                curr_clip_rect = cpath_intersection.rect_list->list.head->next;
5197
0
                for( k = 0; k < cpath_intersection.rect_list->list.count && code >= 0; k++){
5198
0
                    if_debug5m('v', pgs->memory,
5199
0
                               "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5200
0
                               curr_clip_rect->xmin, curr_clip_rect->ymin,
5201
0
                               curr_clip_rect->xmax-curr_clip_rect->xmin,
5202
0
                               curr_clip_rect->ymax-curr_clip_rect->ymin, (int)ptile->id);
5203
0
                    code = gx_trans_pattern_fill_rect(curr_clip_rect->xmin, curr_clip_rect->ymin,
5204
0
                                                      curr_clip_rect->xmax, curr_clip_rect->ymax, ptile,
5205
0
                                                      fill_trans_buffer, phase, pdev, pdevc, 1);
5206
0
                    curr_clip_rect = curr_clip_rect->next;
5207
0
                }
5208
1.60k
            } else if (cpath_intersection.rect_list->list.count == 1) {
5209
                /* The case when there is just a single rect */
5210
1.60k
                if_debug5m('v', pgs->memory,
5211
1.60k
                           "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5212
1.60k
                           cpath_intersection.rect_list->list.single.xmin,
5213
1.60k
                           cpath_intersection.rect_list->list.single.ymin,
5214
1.60k
                           cpath_intersection.rect_list->list.single.xmax-
5215
1.60k
                              cpath_intersection.rect_list->list.single.xmin,
5216
1.60k
                           cpath_intersection.rect_list->list.single.ymax-
5217
1.60k
                              cpath_intersection.rect_list->list.single.ymin,
5218
1.60k
                           (int)ptile->id);
5219
1.60k
                code = gx_trans_pattern_fill_rect(cpath_intersection.rect_list->list.single.xmin,
5220
1.60k
                                                  cpath_intersection.rect_list->list.single.ymin,
5221
1.60k
                                                  cpath_intersection.rect_list->list.single.xmax,
5222
1.60k
                                                  cpath_intersection.rect_list->list.single.ymax,
5223
1.60k
                                                  ptile, fill_trans_buffer, phase, pdev, pdevc, 1);
5224
1.60k
            }
5225
1.60k
        } else {
5226
            /* Clist pattern with transparency.  Create a clip device from our
5227
               cpath_intersection.  The above non-clist case could probably be
5228
               done this way too, which will reduce the amount of code here.
5229
               That is for another day though due to time constraints*/
5230
0
            gx_device *dev;
5231
0
            gx_device_clip clipdev;
5232
5233
0
            gx_make_clip_device_on_stack(&clipdev, &cpath_intersection, pdev);
5234
0
            dev = (gx_device *)&clipdev;
5235
0
            phase.x = pdevc->phase.x;
5236
0
            phase.y = pdevc->phase.y;
5237
0
            code = gx_trans_pattern_fill_rect(rect.p.x, rect.p.y, rect.q.x, rect.q.y,
5238
0
                                              ptile, fill_trans_buffer, phase,
5239
0
                                              dev, pdevc, 1);
5240
5241
0
        }
5242
        /* We're done drawing with the pattern, remove the reference to the
5243
         * pattern device
5244
         */
5245
1.60k
        p14dev->pclist_device = NULL;
5246
1.60k
        if (code < 0)
5247
0
            return code;
5248
5249
        /* free our buffer object */
5250
1.60k
        if (fill_trans_buffer != NULL) {
5251
1.60k
            gs_free_object(pgs->memory, fill_trans_buffer, "pdf14_tile_pattern_fill");
5252
1.60k
            ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5253
1.60k
        }
5254
        /* pop our transparency group which will force the blending.
5255
           This was all needed for Bug 693498 */
5256
1.60k
        code = pdf14_pop_transparency_group(pgs_noconst, p14dev->ctx,
5257
1.60k
                                            p14dev->blend_procs,
5258
1.60k
                                            p14dev->color_info.num_components,
5259
1.60k
                                            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5260
1.60k
                                            pdev);
5261
1.60k
        memcpy(p14dev, &save_pdf14_dev, sizeof(pdf14_device));
5262
1.60k
        p14dev->pclist_device = NULL;
5263
1.60k
    }
5264
1.60k
    gx_cpath_free(&cpath_intersection, "pdf14_tile_pattern_fill");
5265
1.60k
    return code;
5266
1.60k
}
5267
5268
/* Useful function that should probably go elsewhere.
5269
 * Call this function to find the topmost pdf14 device in the device chain,
5270
 * or NULL if there is not one.
5271
 */
5272
static pdf14_device *find_pdf14_device(gx_device *dev)
5273
0
{
5274
0
    pdf14_device *pdev;
5275
5276
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, &pdev, sizeof(pdev)) <= 0)
5277
0
        return NULL;
5278
0
    return pdev;
5279
0
}
5280
5281
/* Imager render for pattern transparency filling.  This is just here to catch
5282
   the final flush, at which time we will pop the group and reset a few items */
5283
static  int
5284
pdf14_pattern_trans_render(gx_image_enum * penum, const byte * buffer, int data_x,
5285
                    uint w, int h, gx_device * dev)
5286
0
{
5287
0
    int code;
5288
0
    pdf14_device * p14dev;
5289
0
    const gs_gstate * pgs = penum->pgs;
5290
0
    gx_device_color * pdcolor = (penum->icolor1);
5291
0
    gx_color_tile *ptile = pdcolor->colors.pattern.p_tile;
5292
5293
    /* Pass along to the original renderer */
5294
0
    code = (ptile->ttrans->image_render)(penum, buffer, data_x, w, h, dev);
5295
0
    if (code < 0)
5296
0
        return code;
5297
    /* On our final time through here, go ahead and pop the transparency
5298
       group and reset the procs in the device color. And free the fill
5299
       trans buffer object */
5300
0
    if (h == 0 && ptile->trans_group_popped == false) {
5301
0
        p14dev = find_pdf14_device(dev);
5302
5303
0
        if (p14dev->pclist_device == NULL) {
5304
            /* Used if we are on clist writing phase.  Would only
5305
               occur if we somehow failed in high level clist
5306
               image writing */
5307
0
            code = gs_end_transparency_group((gs_gstate *) pgs);
5308
0
        } else {
5309
            /* Used if we are on clist reading phase.  If we had high level
5310
               image in clist */
5311
0
            cmm_dev_profile_t *dev_profile;
5312
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5313
0
            if (code < 0)
5314
0
                return code;
5315
5316
0
            if_debug2m('v', p14dev->ctx->memory,
5317
0
                      "[v*] Popping trans group pattern fill, uid = %ld id = %ld \n",
5318
0
                       ptile->uid.id, ptile->id);
5319
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx, p14dev->blend_procs,
5320
0
                    p14dev->color_info.num_components,
5321
0
                    dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5322
0
                    (gx_device *) p14dev);
5323
0
        }
5324
0
        pdcolor->colors.pattern.p_tile->trans_group_popped = true;
5325
0
        gs_free_object(pgs->memory, ptile->ttrans->fill_trans_buffer,
5326
0
                       "pdf14_pattern_trans_render");
5327
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5328
0
    }
5329
0
    return code;
5330
0
}
5331
5332
/* This function is used to get things in place for filling a mask image
5333
   with a pattern that has transparency.  It is used by pdf14_begin_type_image
5334
   and pdf14_clist_begin_type_image */
5335
static int
5336
pdf14_patt_trans_image_fill(gx_device * dev, const gs_gstate * pgs,
5337
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5338
                           const gs_int_rect * prect,
5339
                           const gx_drawing_color * pdcolor,
5340
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5341
                           gx_image_enum_common_t ** pinfo)
5342
0
{
5343
0
    const gs_image_t *pim = (const gs_image_t *)pic;
5344
0
    pdf14_device * p14dev = (pdf14_device *)dev;
5345
0
    gx_color_tile *ptile;
5346
0
    int code;
5347
0
    gs_int_rect group_rect;
5348
0
    gx_image_enum *penum;
5349
0
    gs_rect bbox_in, bbox_out;
5350
0
    gx_pattern_trans_t *fill_trans_buffer;
5351
5352
0
    ptile = pdcolor->colors.pattern.p_tile;
5353
    /* Set up things in the ptile so that we get the proper
5354
       blending etc */
5355
    /* Set the blending procs and the is_additive setting based
5356
       upon the number of channels */
5357
0
    if (ptile->ttrans->n_chan-1 < 4) {
5358
0
        ptile->ttrans->blending_procs = &rgb_blending_procs;
5359
0
        ptile->ttrans->is_additive = true;
5360
0
    } else {
5361
0
        ptile->ttrans->blending_procs = &cmyk_blending_procs;
5362
0
        ptile->ttrans->is_additive = false;
5363
0
    }
5364
    /* Set the blending mode in the ptile based upon the current
5365
       setting in the gs_gstate */
5366
0
    ptile->blending_mode = pgs->blend_mode;
5367
    /* Based upon if the tiles overlap pick the type of rect
5368
       fill that we will want to use */
5369
0
    if (ptile->has_overlap) {
5370
        /* This one does blending since there is tile overlap */
5371
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5372
0
    } else {
5373
        /* This one does no blending since there is no tile overlap */
5374
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5375
0
    }
5376
    /* Set the procs so that we use the proper filling method. */
5377
0
    gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5378
    /* Let the imaging stuff get set up */
5379
0
    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
5380
0
                            prect, pdcolor,pcpath, mem, pinfo);
5381
0
    if (code < 0)
5382
0
        return code;
5383
    /* Now Push the group */
5384
    /* First apply the inverse of the image matrix to our
5385
       image size to get our bounding box. */
5386
0
    bbox_in.p.x = 0;
5387
0
    bbox_in.p.y = 0;
5388
0
    bbox_in.q.x = pim->Width;
5389
0
    bbox_in.q.y = pim->Height;
5390
0
    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
5391
0
                                &bbox_out);
5392
0
    if (code < 0)
5393
0
        return code;
5394
    /* That in turn will get hit by the matrix in the gs_gstate */
5395
0
    code = compute_group_device_int_rect(p14dev, &group_rect,
5396
0
                                            &bbox_out, (gs_gstate *)pgs);
5397
0
    if (code < 0)
5398
0
        return code;
5399
0
    if (!(pim->Width == 0 || pim->Height == 0)) {
5400
0
        if_debug2m('v', p14dev->ctx->memory,
5401
0
                   "[v*] Pushing trans group patt_trans_image_fill, uid = %ld id = %ld \n",
5402
0
                   ptile->uid.id, ptile->id);
5403
5404
0
        code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, 1, 0, 65535, 65535,
5405
0
                                             65535, pgs->blend_mode, 0, 0,
5406
0
                                             ptile->ttrans->n_chan-1, false, false,
5407
0
                                             NULL, NULL, NULL, (gs_gstate *)pgs, dev);
5408
5409
        /* Set up the output buffer information now that we have
5410
           pushed the group */
5411
0
        fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5412
0
        pdf14_get_buffer_information(dev, fill_trans_buffer, NULL, false);
5413
5414
        /* Store this in the appropriate place in pdcolor.  This
5415
           is released later in pdf14_pattern_trans_render when
5416
           we are all done with the mask fill */
5417
0
        ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5418
5419
        /* Change the renderer to handle this case so we can catch the
5420
           end.  We will then pop the group and reset the pdcolor proc.
5421
           Keep the base renderer also. */
5422
0
        penum = (gx_image_enum *) *pinfo;
5423
0
        ptile->ttrans->image_render = penum->render;
5424
0
        penum->render = &pdf14_pattern_trans_render;
5425
0
        ptile->trans_group_popped = false;
5426
0
    }
5427
0
    return code;
5428
0
}
5429
5430
static  int
5431
pdf14_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
5432
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5433
                           const gs_int_rect * prect,
5434
                           const gx_drawing_color * pdcolor,
5435
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5436
                           gx_image_enum_common_t ** pinfo)
5437
11.1k
{
5438
11.1k
    const gs_image_t *pim = (const gs_image_t *)pic;
5439
11.1k
    int code;
5440
5441
11.1k
    code = pdf14_initialize_ctx(dev, dev->color_info.num_components,
5442
11.1k
        dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, pgs);
5443
11.1k
    if (code < 0)
5444
0
        return code;
5445
5446
    /* If we are filling an image mask with a pattern that has a transparency
5447
       then we need to do some special handling */
5448
11.1k
    if (pim->ImageMask) {
5449
0
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
5450
0
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
5451
                /* If we are in a final run through here for this case then
5452
                   go ahead and push the transparency group.   Also, update
5453
                   the proc for the pattern color so that we used the
5454
                   appropriate fill operation.  Note that the group
5455
                   is popped and the proc will be reset when we flush the
5456
                   image data.  This is handled in a special pdf14 image
5457
                   renderer which will end up installed for this case.
5458
                   Detect setting of begin_image to gx_no_begin_image.
5459
                   (final recursive call) */
5460
0
                if (dev_proc(dev, begin_typed_image) != gx_default_begin_typed_image) {
5461
0
                    code = pdf14_patt_trans_image_fill(dev, pgs, pmat, pic,
5462
0
                                                prect, pdcolor, pcpath, mem,
5463
0
                                                pinfo);
5464
0
                    return code;
5465
0
                }
5466
0
            }
5467
0
        }
5468
0
    }
5469
11.1k
    pdf14_set_marking_params(dev, pgs);
5470
11.1k
    return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor,
5471
11.1k
                                        pcpath, mem, pinfo);
5472
11.1k
}
5473
5474
static  void
5475
pdf14_set_params(gs_gstate * pgs,
5476
                 gx_device * dev,
5477
                 const gs_pdf14trans_params_t * pparams)
5478
617k
{
5479
617k
    if_debug0m('v', dev->memory, "[v]pdf14_set_params\n");
5480
617k
    if (pparams->changed & PDF14_SET_BLEND_MODE)
5481
4.21k
        pgs->blend_mode = pparams->blend_mode;
5482
617k
    if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
5483
43.9k
        pgs->text_knockout = pparams->text_knockout;
5484
617k
    if (pparams->changed & PDF14_SET_AIS)
5485
21.2k
        pgs->alphaisshape = pparams->ais;
5486
617k
    if (pparams->changed & PDF14_SET_OVERPRINT)
5487
4.87k
        pgs->overprint = pparams->overprint;
5488
617k
    if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
5489
4.87k
        pgs->stroke_overprint = pparams->stroke_overprint;
5490
617k
    if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
5491
275k
        pgs->fillconstantalpha = pparams->fillconstantalpha;
5492
617k
    if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
5493
268k
        pgs->strokeconstantalpha = pparams->strokeconstantalpha;
5494
617k
    if (pparams->changed & PDF_SET_FILLSTROKE_STATE) {
5495
335k
        gs_swapcolors_quick(pgs);
5496
335k
        if (pparams->op_fs_state == PDF14_OP_STATE_STROKE)
5497
97.9k
            pgs->is_fill_color = false;
5498
237k
        else
5499
237k
            pgs->is_fill_color = true;
5500
335k
    }
5501
617k
    pdf14_set_marking_params(dev, pgs);
5502
617k
}
5503
5504
/*
5505
 * This open_device method for the PDF 1.4 compositor devices is only used
5506
 * when these devices are disabled.  This routine is about as close to
5507
 * a pure "forwarding" open_device operation as is possible. Its only
5508
 * significant function is to ensure that the is_open field of the
5509
 * PDF 1.4 compositor devices matches that of the target device.
5510
 *
5511
 * We assume this procedure is called only if the device is not already
5512
 * open, and that gs_opendevice will take care of the is_open flag.
5513
 */
5514
static  int
5515
pdf14_forward_open_device(gx_device * dev)
5516
0
{
5517
0
    gx_device_forward * pdev = (gx_device_forward *)dev;
5518
0
    gx_device * tdev = pdev->target;
5519
0
    int code;
5520
5521
    /* The PDF 1.4 compositing devices must have a target */
5522
0
    if (tdev == 0)
5523
0
        return_error(gs_error_unknownerror);
5524
0
    if ((code = gs_opendevice(tdev)) >= 0)
5525
0
        gx_device_copy_params(dev, tdev);
5526
0
    return code;
5527
0
}
5528
5529
/*
5530
 * Convert all device procs to be 'forwarding'.  The caller is responsible
5531
 * for setting any device procs that should not be forwarded.
5532
 */
5533
static  void
5534
pdf14_forward_device_procs(gx_device * dev)
5535
44.2k
{
5536
44.2k
    gx_device_forward *pdev = (gx_device_forward *)dev;
5537
44.2k
    pdf14_device *p14dev = (pdf14_device*)dev;
5538
5539
    /* If doing simulated overprint with spot colors
5540
       then makes sure to reset devn setting */
5541
44.2k
    if (p14dev->overprint_sim &&
5542
44.2k
        p14dev->color_info.num_components > 4)
5543
0
        p14dev->icc_struct->supports_devn =
5544
0
            p14dev->target_support_devn;
5545
5546
    /*
5547
     * We are using gx_device_forward_fill_in_procs to set the various procs.
5548
     * This will ensure that any new device procs are also set.  However that
5549
     * routine only changes procs which are NULL.  Thus we start by setting all
5550
     * procs to NULL.
5551
     */
5552
44.2k
    memset(&(pdev->procs), 0, size_of(pdev->procs));
5553
44.2k
    gx_device_forward_fill_in_procs(pdev);
5554
    /*
5555
     * gx_device_forward_fill_in_procs does not forward all procs.
5556
     * Set the remainding procs to also forward.
5557
     */
5558
44.2k
    set_dev_proc(dev, close_device, gx_forward_close_device);
5559
44.2k
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
5560
44.2k
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
5561
44.2k
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
5562
44.2k
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
5563
44.2k
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
5564
44.2k
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
5565
44.2k
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
5566
44.2k
    set_dev_proc(dev, get_profile, gx_forward_get_profile);
5567
44.2k
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
5568
    /* These are forwarding devices with minor tweaks. */
5569
44.2k
    set_dev_proc(dev, open_device, pdf14_forward_open_device);
5570
44.2k
    set_dev_proc(dev, put_params, pdf14_forward_put_params);
5571
44.2k
}
5572
5573
/*
5574
 * Disable the PDF 1.4 compositor device.  Once created, the PDF 1.4
5575
 * compositor device is never removed.  (We do not have a remove compositor
5576
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
5577
 * routine implements that action.
5578
 */
5579
int
5580
pdf14_disable_device(gx_device * dev)
5581
43.9k
{
5582
43.9k
    gx_device_forward * pdev = (gx_device_forward *)dev;
5583
5584
43.9k
    if_debug0m('v', dev->memory, "[v]pdf14_disable_device\n");
5585
43.9k
    dev->color_info = pdev->target->color_info;
5586
43.9k
    pdf14_forward_device_procs(dev);
5587
43.9k
    set_dev_proc(dev, composite, pdf14_forward_composite);
5588
43.9k
    return 0;
5589
43.9k
}
5590
5591
/*
5592
 * The default color space for PDF 1.4 blend modes is based upon the process
5593
 * color model of the output device.
5594
 */
5595
static  pdf14_default_colorspace_t
5596
pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum,
5597
                                 pdf14_blend_cs_t *blend_cs_state)
5598
101k
{
5599
    /* If a blend color space was specified, then go ahead and use that to
5600
       define the default color space for the blend modes.  Only Gray, RGB
5601
       or CMYK blend color spaces are allowed.  Note we do not allow this
5602
       setting if we are dealing with a separation device. */
5603
101k
    cmm_dev_profile_t *dev_profile;
5604
101k
    cmm_profile_t *blend_profile = NULL;
5605
101k
    pdf14_blend_cs_t temp_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5606
101k
    int code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
5607
101k
    bool valid_blend_cs = false;
5608
5609
101k
    *blend_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5610
5611
    /* Are we using a blend color space or the output intent color space? Also
5612
       is there a conflict in the settings. i.e. has someone set a blend color
5613
       space and tried to use the output intent with simulate overprint setting.
5614
    */
5615
101k
    if (dev_profile->overprint_control == gs_overprint_control_simulate &&
5616
101k
        dev_profile->oi_profile != NULL &&
5617
101k
        !gsicc_profiles_equal(dev_profile->oi_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5618
        /* If blend profile is also set, throw a warning about output intent not being used. We have
5619
           possible conflicting command line settings and we will err on using the blend profile
5620
           if one was specified. */
5621
0
        if (dev_profile->blend_profile != NULL &&
5622
0
            !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->oi_profile)) {
5623
0
            blend_profile = dev_profile->blend_profile;
5624
0
            temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5625
0
            emprintf(pdev->memory, "Warning: OI profile not used for blending CS\n");
5626
0
        } else {
5627
            /* All good, use the output intent profile as we have one
5628
               and are doing simulate overprint with a different device
5629
               profile set. */
5630
0
            blend_profile = dev_profile->oi_profile;
5631
0
            temp_cs_state = PDF14_BLEND_CS_OUTPUTINTENT;
5632
0
        }
5633
101k
    } else if (dev_profile->blend_profile != NULL &&
5634
101k
               !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5635
        /* Blend profile is different than device profile */
5636
0
        blend_profile = dev_profile->blend_profile;
5637
0
        temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5638
0
    }
5639
5640
    /* Make sure any blend color space is valid along with other cond */
5641
101k
    if (code == 0 && blend_profile != NULL && !use_pdf14_accum) {
5642
0
        if (!blend_profile->isdevlink &&
5643
0
            !blend_profile->islab &&
5644
0
            (blend_profile->data_cs == gsGRAY ||
5645
0
             blend_profile->data_cs == gsRGB ||
5646
0
             blend_profile->data_cs == gsCMYK)) {
5647
            /* Also, do not allow the use of the blend space when we are pushing
5648
               a pattern pdf14 device.  Those should inherit from the parent */
5649
0
            if (!(gx_device_is_pattern_clist(pdev) ||
5650
0
                  gx_device_is_pattern_accum(pdev))) {
5651
0
                valid_blend_cs = true;
5652
0
            }
5653
0
        }
5654
0
    }
5655
5656
    /* If num components is one, just go ahead and use gray.  This avoids
5657
       issues with additive/subtractive mono color devices  */
5658
101k
    if (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ||
5659
101k
        pdev->color_info.num_components == 1) {
5660
        /*
5661
        * Note:  We do not allow the SeparationOrder device parameter for
5662
        * additive devices.  Thus we always have 1 colorant for DeviceGray
5663
        * and 3 colorants for DeviceRGB.
5664
        */
5665
101k
        if (valid_blend_cs) {
5666
0
            *blend_cs_state = temp_cs_state;
5667
0
            switch (blend_profile->num_comps) {
5668
0
            case 1:
5669
0
                return PDF14_DeviceGray;
5670
0
            case 3:
5671
0
                return PDF14_DeviceRGB;
5672
0
            case 4:
5673
0
                return PDF14_DeviceCMYK;
5674
0
            }
5675
0
        }
5676
101k
        if (pdev->color_info.num_components == 1)
5677
0
            return PDF14_DeviceGray;
5678
101k
        else
5679
101k
            return PDF14_DeviceRGB;
5680
101k
    } else {
5681
        /*
5682
         * Check if the device is CMYK only or CMYK plus spot colors. Note
5683
         * the CMYK plus spot colors will not support the blend color space
5684
         */
5685
0
        int i, output_comp_num, num_cmyk_used = 0, num_cmyk = 0;
5686
#if CUSTOM_BLENDING_MODE == ALWAYS_USE_CUSTOM_BLENDING
5687
        return PDF14_DeviceCustom;
5688
#endif
5689
        /*
5690
         * Count the number of CMYK process components supported by the output
5691
         * device.
5692
         */
5693
0
        for (i = 0; i < 4; i++) {
5694
0
            const char * pcomp_name = (const char *)DeviceCMYKComponents[i];
5695
5696
0
            output_comp_num = dev_proc(pdev, get_color_comp_index)
5697
0
                (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE_OP);
5698
0
            if (output_comp_num >= 0) {
5699
0
                num_cmyk++;
5700
0
                if (output_comp_num != GX_DEVICE_COLOR_MAX_COMPONENTS)
5701
0
                    num_cmyk_used++;
5702
0
            }
5703
0
        }
5704
        /*
5705
         * Check if the device supports only CMYK.  Otherewise we assume that
5706
         * the output device supports spot colors.  Note:  This algorithm can
5707
         * be fooled if the SeparationOrder device parameter is being used by
5708
         * the output device device to only select CMYK.
5709
         */
5710
0
        if (num_cmyk_used == 4 && pdev->color_info.num_components == 4
5711
0
            && pdev->color_info.max_components == 4) {
5712
0
            if (valid_blend_cs) {
5713
0
                *blend_cs_state = temp_cs_state;
5714
0
                switch (blend_profile->num_comps) {
5715
0
                case 1:
5716
0
                    return PDF14_DeviceGray;
5717
0
                case 3:
5718
0
                    return PDF14_DeviceRGB;
5719
0
                case 4:
5720
0
                    return PDF14_DeviceCMYK;
5721
0
                }
5722
0
            }
5723
0
            return PDF14_DeviceCMYK;
5724
0
        }
5725
        /*
5726
         * Check if we should use the 'custom' PDF 1.4 compositor device.
5727
         * This device is only needed for those devices which do not support
5728
         * a basic CMYK process color model.
5729
         */
5730
0
#if CUSTOM_BLENDING_MODE == AUTO_USE_CUSTOM_BLENDING
5731
0
        if (num_cmyk != 4)
5732
0
            return PDF14_DeviceCustom;
5733
0
#endif
5734
        /*
5735
         * Otherewise we use a CMYK plus spot colors for blending.
5736
         */
5737
0
        if (valid_blend_cs)
5738
0
            *blend_cs_state = temp_cs_state;
5739
0
        return PDF14_DeviceCMYKspot;
5740
0
    }
5741
101k
}
5742
5743
/*
5744
 * the PDF 1.4 transparency spec says that color space for blending
5745
 * operations can be based upon either a color space specified in the
5746
 * group or a default value based upon the output device.  We are
5747
 * currently only using a color space based upon the device.
5748
 */
5749
static  int
5750
get_pdf14_device_proto(gx_device       *dev,
5751
                       pdf14_device    *pdevproto,
5752
                       gs_gstate       *pgs,
5753
                 const gs_pdf14trans_t *pdf14pct,
5754
                       bool             use_pdf14_accum)
5755
44.6k
{
5756
44.6k
    pdf14_blend_cs_t blend_cs_state;
5757
44.6k
    pdf14_default_colorspace_t dev_cs =
5758
44.6k
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
5759
44.6k
                                                 &blend_cs_state);
5760
44.6k
    bool deep = device_is_deep(dev);
5761
44.6k
    int num_spots = pdf14pct->params.num_spot_colors;
5762
5763
    /* overprint overide */
5764
44.6k
    if (pdf14pct->params.overprint_sim_push &&
5765
44.6k
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
5766
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
5767
0
            dev_cs = PDF14_DeviceCMYKspot;
5768
0
            num_spots = pdf14pct->params.num_spot_colors_int;
5769
0
        } else
5770
0
            dev_cs = PDF14_DeviceCMYK;
5771
0
    }
5772
5773
44.6k
    switch (dev_cs) {
5774
0
        case PDF14_DeviceGray:
5775
0
            *pdevproto = gs_pdf14_Gray_device;
5776
0
            pdevproto->color_info.max_components = 1;
5777
0
            pdevproto->color_info.num_components =
5778
0
                                    pdevproto->color_info.max_components;
5779
0
            pdevproto->color_info.depth = 8<<deep;
5780
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
5781
0
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
5782
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
5783
0
            pdevproto->sep_device = false;
5784
0
            break;
5785
44.6k
        case PDF14_DeviceRGB:
5786
44.6k
            *pdevproto = gs_pdf14_RGB_device;
5787
44.6k
            pdevproto->color_info.depth = 24<<deep;
5788
44.6k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
5789
44.6k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
5790
44.6k
            pdevproto->sep_device = false;
5791
44.6k
            break;
5792
0
        case PDF14_DeviceCMYK:
5793
0
            *pdevproto = gs_pdf14_CMYK_device;
5794
0
            pdevproto->color_info.depth = 32<<deep;
5795
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
5796
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
5797
0
            pdevproto->sep_device = false;
5798
0
            break;
5799
0
        case PDF14_DeviceCMYKspot:
5800
0
            *pdevproto = gs_pdf14_CMYKspot_device;
5801
            /* Need to figure out how we want to handle the device profile
5802
               for this case */
5803
            /*
5804
             * The number of components for the PDF14 device is the sum
5805
             * of the process components and the number of spot colors
5806
             * for the page.
5807
             */
5808
0
            if (num_spots >= 0) {
5809
0
                pdevproto->color_info.num_components =
5810
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
5811
0
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
5812
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
5813
0
                pdevproto->color_info.depth =
5814
0
                                    pdevproto->color_info.num_components * (8<<deep);
5815
0
                pdevproto->sep_device = true;
5816
0
            }
5817
0
            break;
5818
0
        case PDF14_DeviceCustom:
5819
            /*
5820
             * We are using the output device's process color model.  The
5821
             * color_info for the PDF 1.4 compositing device needs to match
5822
             * the output device.
5823
             */
5824
0
            *pdevproto = gs_pdf14_custom_device;
5825
0
            pdevproto->color_info = dev->color_info;
5826
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
5827
0
            pdevproto->color_info.depth =
5828
0
                       pdevproto->color_info.num_components * (8<<deep);
5829
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
5830
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
5831
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
5832
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
5833
0
            break;
5834
0
        default:      /* Should not occur */
5835
0
            return_error(gs_error_rangecheck);
5836
44.6k
    }
5837
44.6k
    pdevproto->initialize_device_procs((gx_device *)pdevproto);
5838
44.6k
    pdevproto->blend_cs_state = blend_cs_state;
5839
44.6k
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
5840
44.6k
    return 0;
5841
44.6k
}
5842
5843
/* When playing back the clist, we need to know if the buffer device is compatible */
5844
/* with the pdf14 compositor that was used when writing the clist. Colorspace and  */
5845
/* depth are critical since these must match when reading back colors.             */
5846
bool
5847
pdf14_ok_to_optimize(gx_device *dev)
5848
56.5k
{
5849
56.5k
    pdf14_blend_cs_t blend_cs_state;
5850
56.5k
    pdf14_default_colorspace_t pdf14_cs =
5851
56.5k
        pdf14_determine_default_blend_cs(dev, false, &blend_cs_state);
5852
56.5k
    gsicc_colorbuffer_t dev_icc_cs;
5853
56.5k
    bool ok = false;
5854
56.5k
    int tag_depth = device_encodes_tags(dev) ? 8 : 0;
5855
56.5k
    cmm_dev_profile_t *dev_profile;
5856
56.5k
    int code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5857
56.5k
    bool deep = device_is_deep(dev);
5858
5859
56.5k
    if (code < 0)
5860
0
        return false;
5861
5862
56.5k
    check_device_compatible_encoding(dev);
5863
5864
56.5k
    if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN_STANDARD)
5865
56.5k
        return false;
5866
5867
0
    dev_icc_cs = dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->data_cs;
5868
    /* If the outputprofile is not "standard" then colors converted to device color */
5869
    /* during clist writing won't match the colors written for the pdf14 clist dev  */
5870
0
    if (!(dev_icc_cs == gsGRAY || dev_icc_cs == gsRGB || dev_icc_cs == gsCMYK))
5871
0
        return false;                           /* can't handle funky output profiles */
5872
5873
0
    switch (pdf14_cs) {
5874
0
        case PDF14_DeviceGray:
5875
0
            ok = dev->color_info.max_gray == (deep ? 65535 : 255) && dev->color_info.depth == (8<<deep) + tag_depth;
5876
0
            break;
5877
0
        case PDF14_DeviceRGB:
5878
0
            ok = dev->color_info.max_color == (deep ? 65535: 255) && dev->color_info.depth == (24<<deep) + tag_depth;
5879
0
            break;
5880
0
        case PDF14_DeviceCMYK:
5881
0
            ok = dev->color_info.max_color == (deep ? 65535 : 255) && dev->color_info.depth == (32<<deep) + tag_depth;
5882
0
            break;
5883
0
        case PDF14_DeviceCMYKspot:
5884
0
            ok = false;     /* punt for this case */
5885
0
            break;
5886
0
        case PDF14_DeviceCustom:
5887
            /*
5888
             * We are using the output device's process color model.  The
5889
             * color_info for the PDF 1.4 compositing device needs to match
5890
             * the output device, but it may not have been contone.
5891
             */
5892
0
            ok = dev->color_info.depth == dev->color_info.num_components * (8<<deep) + tag_depth;
5893
0
            break;
5894
0
        default:      /* Should not occur */
5895
0
            ok = false;
5896
0
    }
5897
0
    return ok;
5898
0
}
5899
5900
/*
5901
 * Recreate the PDF 1.4 compositor device.  Once created, the PDF 1.4
5902
 * compositor device is never removed.  (We do not have a remove compositor
5903
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
5904
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
5905
 * again.
5906
 */
5907
static  int
5908
pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs,
5909
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
5910
0
{
5911
0
    pdf14_device * pdev = (pdf14_device *)dev;
5912
0
    gx_device * target = pdev->target;
5913
0
    pdf14_device dev_proto;
5914
0
    bool has_tags = device_encodes_tags(dev);
5915
0
    int code;
5916
0
    bool deep = device_is_deep(dev);
5917
5918
0
    if_debug0m('v', dev->memory, "[v]pdf14_recreate_device\n");
5919
5920
    /*
5921
     * We will not use the entire prototype device but we will set the
5922
     * color related info and the device procs to match the prototype.
5923
     */
5924
0
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
5925
0
                                  pdf14pct, false);
5926
0
    if (code < 0)
5927
0
        return code;
5928
0
    pdev->color_info = dev_proto.color_info;
5929
0
    pdev->pad = target->pad;
5930
0
    pdev->log2_align_mod = target->log2_align_mod;
5931
5932
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && !target->is_planar)
5933
0
        pdev->is_planar = true;
5934
0
    else
5935
0
        pdev->is_planar = target->is_planar;
5936
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
5937
5938
0
    pdev->procs = dev_proto.procs;
5939
0
    if (deep) {
5940
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
5941
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
5942
0
    }
5943
0
    if (has_tags) {
5944
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
5945
0
        pdev->color_info.comp_shift[pdev->color_info.num_components] = pdev->color_info.depth;
5946
0
        pdev->color_info.depth += 8;
5947
0
    }
5948
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
5949
0
    gx_device_fill_in_procs((gx_device *)pdev);
5950
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
5951
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
5952
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
5953
0
    check_device_separable(dev);
5954
0
    return dev_proc(pdev, open_device)(dev);
5955
0
}
5956
5957
/*
5958
 * Implement the various operations that can be specified via the PDF 1.4
5959
 * create compositor request.
5960
 */
5961
static  int
5962
gx_update_pdf14_compositor(gx_device * pdev, gs_gstate * pgs,
5963
    const gs_pdf14trans_t * pdf14pct, gs_memory_t * mem )
5964
1.56M
{
5965
1.56M
    pdf14_device *p14dev = (pdf14_device *)pdev;
5966
1.56M
    gs_pdf14trans_params_t params = pdf14pct->params;
5967
1.56M
    int code = 0;
5968
5969
1.56M
    params.idle = pdf14pct->idle;
5970
1.56M
    switch (params.pdf14_op) {
5971
0
        default:      /* Should not occur. */
5972
0
            break;
5973
0
        case PDF14_PUSH_DEVICE:
5974
0
            if (!(params.is_pattern)) {
5975
0
                p14dev->blend_mode = 0;
5976
0
                p14dev->opacity = p14dev->shape = 0.0;
5977
0
                pdf14_recreate_device(mem, pgs, pdev, pdf14pct);
5978
0
            }
5979
0
            break;
5980
0
        case PDF14_ABORT_DEVICE:
5981
            /* Something has gone very wrong.  Let transparency device clean up
5982
               what ever it has allocated and then we are shutting it down */
5983
0
            code = gx_abort_trans_device(pgs, pdev);
5984
0
            if (p14dev->free_devicen) {
5985
0
                devn_free_params(pdev);
5986
0
            }
5987
0
            pdf14_disable_device(pdev);
5988
0
            pdf14_close(pdev);
5989
0
            break;
5990
43.9k
        case PDF14_POP_DEVICE:
5991
43.9k
            if (!(params.is_pattern)) {
5992
43.9k
                if_debug0m('v', pdev->memory,
5993
43.9k
                           "[v]gx_update_pdf14_compositor(PDF14_POP_DEVICE)\n");
5994
43.9k
                pgs->get_cmap_procs = p14dev->save_get_cmap_procs;
5995
43.9k
                gx_set_cmap_procs(pgs, p14dev->target);
5996
                /* Send image out raster data to output device */
5997
43.9k
                {
5998
                    /* Make a copy so we can change the ROP */
5999
43.9k
                    gs_gstate new_pgs = *pgs;
6000
6001
                    /* We don't use the gs_gstate log_op since this is for the */
6002
                    /* clist playback. Putting the image (band in the case of the */
6003
                    /* clist) only needs to use the default ROP to copy the data  */
6004
43.9k
                    new_pgs.log_op = rop3_default;
6005
43.9k
                    code = p14dev->pdf14_procs->put_image(pdev, &new_pgs, p14dev->target);
6006
43.9k
                }
6007
                /* Before we disable the device release any deviceN structures.
6008
                    free_devicen is set if the pdf14 device had inherited its
6009
                    deviceN parameters from the target clist device.  In this
6010
                    case they should not be freed */
6011
43.9k
                if (p14dev->free_devicen) {
6012
43.9k
                    devn_free_params(pdev);
6013
43.9k
                }
6014
43.9k
                pdf14_disable_device(pdev);
6015
43.9k
                pdf14_close(pdev);
6016
43.9k
            }
6017
43.9k
            break;
6018
27.5k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
6019
160k
        case PDF14_BEGIN_TRANS_GROUP:
6020
160k
            if (p14dev->smask_constructed || p14dev->depth_within_smask)
6021
17.4k
                p14dev->depth_within_smask++;
6022
160k
            p14dev->smask_constructed = 0;
6023
160k
            code = gx_begin_transparency_group(pgs, pdev, &params);
6024
160k
            break;
6025
157k
        case PDF14_END_TRANS_GROUP:
6026
157k
            code = gx_end_transparency_group(pgs, pdev);
6027
157k
            if (p14dev->depth_within_smask)
6028
17.4k
                p14dev->depth_within_smask--;
6029
157k
            break;
6030
0
        case PDF14_BEGIN_TRANS_TEXT_GROUP:
6031
0
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
6032
0
                p14dev->text_group = PDF14_TEXTGROUP_MISSING_ET;
6033
0
                emprintf(p14dev->memory, "Warning: Text group pushed but no ET found\n");
6034
0
            } else
6035
0
                p14dev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6036
0
            break;
6037
3.25k
        case PDF14_END_TRANS_TEXT_GROUP:
6038
3.25k
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED)
6039
3.25k
                code = gx_end_transparency_group(pgs, pdev);
6040
3.25k
            p14dev->text_group = PDF14_TEXTGROUP_NO_BT; /* Hit ET */
6041
3.25k
            break;
6042
287k
        case PDF14_BEGIN_TRANS_MASK:
6043
287k
            code = gx_begin_transparency_mask(pgs, pdev, &params);
6044
287k
            if (code >= 0 && params.subtype != TRANSPARENCY_MASK_None)
6045
22.9k
                p14dev->in_smask_construction++;
6046
287k
            break;
6047
22.9k
        case PDF14_END_TRANS_MASK:
6048
22.9k
            code = gx_end_transparency_mask(pgs, pdev, &params);
6049
22.9k
            if (code >= 0) {
6050
22.9k
                p14dev->in_smask_construction--;
6051
22.9k
                if (p14dev->in_smask_construction < 0)
6052
0
                    p14dev->in_smask_construction = 0;
6053
22.9k
                if (p14dev->in_smask_construction == 0)
6054
22.9k
                    p14dev->smask_constructed = 1;
6055
22.9k
            }
6056
22.9k
            break;
6057
617k
        case PDF14_SET_BLEND_PARAMS:
6058
617k
            pdf14_set_params(pgs, pdev, &pdf14pct->params);
6059
617k
            break;
6060
0
        case PDF14_PUSH_TRANS_STATE:
6061
0
            code = gx_push_transparency_state(pgs, pdev);
6062
0
            break;
6063
267k
        case PDF14_POP_TRANS_STATE:
6064
267k
            code = gx_pop_transparency_state(pgs, pdev);
6065
267k
            break;
6066
582
        case PDF14_PUSH_SMASK_COLOR:
6067
582
            code = pdf14_increment_smask_color(pgs, pdev);
6068
582
            break;
6069
582
        case PDF14_POP_SMASK_COLOR:
6070
582
            code = pdf14_decrement_smask_color(pgs, pdev);
6071
582
            break;
6072
1.56M
    }
6073
1.56M
    return code;
6074
1.56M
}
6075
6076
/*
6077
 * The PDF 1.4 compositor is never removed.  (We do not have a 'remove
6078
 * compositor' method.  However the compositor is disabled when we are not
6079
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
6080
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
6081
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
6082
 * to the target.
6083
 */
6084
static  int
6085
pdf14_forward_composite(gx_device * dev, gx_device * * pcdev,
6086
        const gs_composite_t * pct, gs_gstate * pgs,
6087
        gs_memory_t * mem, gx_device *cdev)
6088
0
{
6089
0
    pdf14_device *pdev = (pdf14_device *)dev;
6090
0
    gx_device * tdev = pdev->target;
6091
0
    int code;
6092
6093
0
    *pcdev = dev;
6094
0
    if (gs_is_pdf14trans_compositor(pct)) {
6095
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6096
6097
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
6098
0
            return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6099
0
        return 0;
6100
0
    }
6101
0
    code = dev_proc(tdev, composite)(tdev, pcdev, pct, pgs, mem, cdev);
6102
0
    if (code == 1) {
6103
        /* We have created a new compositor that wrapped tdev. This means
6104
         * that our target should be updated to point to that. */
6105
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
6106
0
        code = 0; /* We have not created a new compositor that wrapped dev. */
6107
0
    }
6108
0
    return code;
6109
0
}
6110
6111
/*
6112
 * The PDF 1.4 compositor can be handled directly, so just set *pcdev = dev
6113
 * and return. Since the gs_pdf14_device only supports the high-level routines
6114
 * of the interface, don't bother trying to handle any other compositor.
6115
 */
6116
static int
6117
pdf14_composite(gx_device * dev, gx_device * * pcdev,
6118
        const gs_composite_t * pct, gs_gstate * pgs,
6119
        gs_memory_t * mem, gx_device *cdev)
6120
1.56M
{
6121
1.56M
    pdf14_device *p14dev = (pdf14_device *)dev;
6122
1.56M
    if (gs_is_pdf14trans_compositor(pct)) {
6123
1.56M
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6124
1.56M
        *pcdev = dev;
6125
        /* cdev, may be the clist reader device which may contain information that
6126
           we will need related to the ICC color spaces that define transparency
6127
           groups.  We want this propogated through all the pdf14 functions.  Store
6128
           a pointer to it in the pdf14 device */
6129
1.56M
        p14dev->pclist_device = cdev;
6130
1.56M
        return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6131
1.56M
    } else if (gs_is_overprint_compositor(pct)) {
6132
                /* If we had an overprint compositer action, then the
6133
                   color components that were drawn should be updated.
6134
                   The overprint compositor logic and its interactions
6135
                   with the clist is a little odd as it passes uninitialized
6136
                   values around a fair amount.  Hence the forced assignement here.
6137
                   See gx_spot_colors_set_overprint in gscspace for issues... */
6138
3.56k
                const gs_overprint_t * op_pct = (const gs_overprint_t *) pct;
6139
3.56k
                gx_color_index drawn_comps;
6140
6141
3.56k
                p14dev->op_state = op_pct->params.op_state;
6142
6143
6144
3.56k
                if (p14dev->op_state == PDF14_OP_STATE_NONE) {
6145
3.56k
                    if (op_pct->params.retain_any_comps) {
6146
0
                        drawn_comps = op_pct->params.drawn_comps;
6147
3.56k
                    } else {
6148
                        /* Draw everything. If this parameter was not set, clist does
6149
                           not fill it in.  */
6150
3.56k
                        drawn_comps = ((gx_color_index)1 << (p14dev->color_info.num_components)) - (gx_color_index)1;
6151
3.56k
                    }
6152
6153
3.56k
                    if (op_pct->params.is_fill_color) {
6154
3.56k
                        p14dev->effective_overprint_mode = op_pct->params.effective_opm;
6155
3.56k
                        p14dev->drawn_comps_fill = drawn_comps;
6156
3.56k
                    } else {
6157
0
                        p14dev->stroke_effective_op_mode = op_pct->params.effective_opm;
6158
0
                        p14dev->drawn_comps_stroke = drawn_comps;
6159
0
                    }
6160
6161
3.56k
                }
6162
3.56k
                *pcdev = dev;
6163
3.56k
                return 0;
6164
3.56k
    } else
6165
0
        return gx_no_composite(dev, pcdev, pct, pgs, mem, cdev);
6166
1.56M
}
6167
6168
static int
6169
pdf14_push_text_group(gx_device *dev, gs_gstate *pgs,
6170
                      gs_blend_mode_t blend_mode, float opacity,
6171
                      float shape, bool is_clist)
6172
227
{
6173
227
    int code;
6174
227
    gs_transparency_group_params_t params = { 0 };
6175
227
    gs_rect bbox = { 0 }; /* Bounding box is set by parent */
6176
227
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
6177
227
    float alpha = pgs->fillconstantalpha;
6178
6179
    /* Push a non-isolated knock-out group making sure the opacity and blend
6180
       mode are correct */
6181
227
    params.Isolated = false;
6182
227
    params.Knockout = true;
6183
227
    params.page_group = false;
6184
227
    params.text_group = PDF14_TEXTGROUP_BT_PUSHED;
6185
227
    params.group_opacity = 1.0;
6186
227
    params.group_shape = 1.0;
6187
6188
227
    gs_setfillconstantalpha(pgs, 1.0);
6189
227
    gs_setblendmode(pgs, BLEND_MODE_Normal);
6190
6191
227
    if (is_clist) {
6192
227
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6193
227
        if (code < 0)
6194
0
            return code;
6195
227
    }
6196
6197
227
    code = gs_begin_transparency_group(pgs, &params, &bbox, PDF14_BEGIN_TRANS_GROUP);
6198
227
    gs_setfillconstantalpha(pgs, alpha);
6199
227
    gs_setblendmode(pgs, blend_mode);
6200
227
    if (code < 0)
6201
0
        return code;
6202
6203
227
    if (is_clist) {
6204
227
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6205
227
    }
6206
227
    return code;
6207
227
}
6208
6209
static  int
6210
pdf14_text_begin(gx_device * dev, gs_gstate * pgs,
6211
                 const gs_text_params_t * text, gs_font * font,
6212
                 const gx_clip_path * pcpath,
6213
                 gs_text_enum_t ** ppenum)
6214
0
{
6215
0
    int code;
6216
0
    gs_text_enum_t *penum;
6217
0
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
6218
0
    float opacity = pgs->fillconstantalpha;
6219
0
    float shape = 1.0;
6220
0
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
6221
0
    pdf14_device *pdev = (pdf14_device*)dev;
6222
0
    bool draw = !(text->operation & TEXT_DO_NONE);
6223
0
    uint text_mode = gs_currenttextrenderingmode(pgs);
6224
0
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
6225
0
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
6226
6227
0
    code = pdf14_initialize_ctx(dev, dev->color_info.num_components,
6228
0
        dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, (const gs_gstate*) pgs);
6229
0
    if (code < 0)
6230
0
        return code;
6231
6232
0
    if_debug0m('v', pgs->memory, "[v]pdf14_text_begin\n");
6233
0
    pdf14_set_marking_params(dev, pgs);
6234
0
    code = gx_default_text_begin(dev, pgs, text, font, pcpath, &penum);
6235
0
    if (code < 0)
6236
0
        return code;
6237
6238
    /* We may need to push a non-isolated transparency group if the following
6239
       is true.
6240
       1) We are not currently in one that we pushed for text and we are in
6241
          a BT/ET pair.  This is determined by looking at the pdf14 text_group.
6242
       2) The blend mode is not Normal or the opacity is not 1.0
6243
       3) Text knockout is set to true
6244
       4) We are actually doing a text drawing
6245
6246
       Special note:  If text-knockout is set to false while we are within a
6247
       BT ET pair, we should pop the group.  I need to create a test file for
6248
       this case.  */
6249
6250
       /* Catch case where we already pushed a group and are trying to push another one.
6251
       In that case, we will pop the current one first, as we don't want to be left
6252
       with it. Note that if we have a BT and no other BTs or ETs then this issue
6253
       will not be caught until we do the put_image and notice that the stack is not
6254
       empty. */
6255
0
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
6256
0
        code = gs_end_transparency_group(pgs);
6257
0
        if (code < 0)
6258
0
            return code;
6259
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6260
0
    }
6261
6262
0
    if (gs_currenttextknockout(pgs) && (blend_issue ||
6263
0
         (pgs->fillconstantalpha != 1.0 && text_fill) ||
6264
0
         (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
6265
0
         text_mode != 3 && /* don't bother with invisible text */
6266
0
         pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED)
6267
0
        if (draw) {
6268
0
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape,
6269
0
                false);
6270
0
        }
6271
0
    *ppenum = (gs_text_enum_t *)penum;
6272
0
    return code;
6273
0
}
6274
6275
static  int
6276
pdf14_initialize_device(gx_device *new_dev)
6277
44.6k
{
6278
44.6k
    pdf14_device *pdev = (pdf14_device*)new_dev;
6279
6280
44.6k
    pdev->ctx = NULL;
6281
44.6k
    pdev->color_model_stack = NULL;
6282
44.6k
    pdev->smaskcolor = NULL;
6283
6284
44.6k
    return 0;
6285
44.6k
}
6286
6287
/*
6288
 * Implement copy_mono by filling lots of small rectangles.
6289
 */
6290
static int
6291
pdf14_copy_mono(gx_device * dev,
6292
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
6293
        int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
6294
1.07M
{
6295
1.07M
    const byte *sptr;
6296
1.07M
    const byte *line;
6297
1.07M
    int sbit, first_bit;
6298
1.07M
    int code, sbyte, bit, count;
6299
1.07M
    int run_length, startx, current_bit, bit_value;
6300
1.07M
    gx_color_index current_color;
6301
6302
1.07M
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
6303
1.07M
    line = base + (sourcex >> 3);
6304
1.07M
    sbit = sourcex & 7;
6305
1.07M
    first_bit = 7 - sbit;
6306
6307
    /* Loop through the height of the specified area. */
6308
8.18M
    while (h-- > 0) {
6309
        /* Set up for the start of each line of the area. */
6310
7.11M
        sptr = line;
6311
7.11M
        sbyte = *sptr++;
6312
7.11M
        bit = first_bit;
6313
7.11M
        count = w;
6314
7.11M
        run_length = 0;
6315
7.11M
        startx = x;
6316
7.11M
        current_bit = 0;
6317
7.11M
        current_color = zero;
6318
6319
        /* Loop across each pixel of a line. */
6320
84.5M
        do {
6321
84.5M
            bit_value = (sbyte >> bit) & 1;
6322
84.5M
            if (bit_value == current_bit) {
6323
                /* The value did not change, simply increment our run length */
6324
68.1M
                run_length++;
6325
68.1M
            } else {
6326
                /* The value changed, fill the current rectangle. */
6327
16.4M
                if (run_length != 0) {
6328
16.2M
                    if (current_color != gx_no_color_index) {
6329
6.57M
                        code = (*dev_proc(dev, fill_rectangle))
6330
6.57M
                                (dev, startx, y, run_length, 1, current_color);
6331
6.57M
                        if (code < 0)
6332
0
                            return code;
6333
6.57M
                    }
6334
16.2M
                    startx += run_length;
6335
16.2M
                }
6336
16.4M
                run_length = 1;
6337
16.4M
                current_color = bit_value ? one : zero;
6338
16.4M
                current_bit = bit_value;
6339
16.4M
            }
6340
            /* Move to the next input bit. */
6341
84.5M
            if (bit == 0) {
6342
7.94M
                bit = 7;
6343
7.94M
                sbyte = *sptr++;
6344
7.94M
            }
6345
76.6M
            else
6346
76.6M
                bit--;
6347
84.5M
        } while (--count > 0);
6348
        /* Fill the last rectangle in the line. */
6349
7.11M
        if (run_length != 0 && current_color != gx_no_color_index) {
6350
3.26M
            code = (*dev_proc(dev, fill_rectangle))
6351
3.26M
                        (dev, startx, y, run_length, 1, current_color);
6352
3.26M
            if (code < 0)
6353
0
                return code;
6354
3.26M
        }
6355
        /* Move to the next line */
6356
7.11M
        line += sraster;
6357
7.11M
        y++;
6358
7.11M
    }
6359
1.07M
    return 0;
6360
1.07M
}
6361
6362
/* Added to avoid having to go back and forth between fixed and int
6363
   in some of the internal methods used for dealing with tiling
6364
   and devn colors */
6365
static int
6366
pdf14_fill_rectangle_devn(gx_device *dev, int x, int y, int w, int h,
6367
    const gx_drawing_color *pdcolor)
6368
0
{
6369
0
    pdf14_device *pdev = (pdf14_device *)dev;
6370
0
    pdf14_buf *buf;
6371
0
    int code;
6372
6373
0
    fit_fill_xywh(dev, x, y, w, h);
6374
0
    if (w <= 0 || h <= 0)
6375
0
        return 0;
6376
6377
0
    code = pdf14_initialize_ctx(dev, dev->color_info.num_components,
6378
0
        dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, NULL);
6379
0
    if (code < 0)
6380
0
        return code;
6381
0
    buf = pdev->ctx->stack;
6382
6383
0
    if (buf->knockout)
6384
0
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
6385
0
            true);
6386
0
    else
6387
0
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
6388
0
}
6389
6390
/* Step through and do rect fills with the devn colors as
6391
   we hit each transition in the bitmap. It is possible
6392
   that one of the colors is not devn, but is pure and
6393
   is set to gx_no_color_index. This type of mix happens
6394
   for example from tile_clip_fill_rectangle_hl_color */
6395
static int
6396
pdf14_copy_mono_devn(gx_device *dev,
6397
    const byte *base, int sourcex, int sraster,
6398
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6399
    const gx_drawing_color *pdcolor1)
6400
0
{
6401
0
    const byte *sptr;
6402
0
    const byte *line;
6403
0
    int sbit, first_bit;
6404
0
    int code, sbyte, bit, count;
6405
0
    int run_length, startx, current_bit, bit_value;
6406
0
    const gx_drawing_color *current_color;
6407
6408
0
    if ((x | y) < 0) {
6409
0
        if (x < 0) {
6410
0
            w += x;
6411
0
            sourcex -= x;
6412
0
            x = 0;
6413
0
        }
6414
0
        if (y < 0) {
6415
0
            h += y;
6416
0
            base -= (int)(y * sraster);
6417
0
            y = 0;
6418
0
        }
6419
0
    }
6420
0
    if (w > (dev)->width - x)
6421
0
        w = (dev)->width - x;
6422
0
    if (h > (dev)->height - y)
6423
0
        h = (dev)->height - y;
6424
0
    if (w <= 0 || h <= 0)
6425
0
        return 0;
6426
6427
0
    line = base + (sourcex >> 3);
6428
0
    sbit = sourcex & 7;
6429
0
    first_bit = 7 - sbit;
6430
6431
    /* Loop through the height of the specified area. */
6432
0
    while (h-- > 0) {
6433
        /* Set up for the start of each line of the area. */
6434
0
        sptr = line;
6435
0
        sbyte = *sptr++;
6436
0
        bit = first_bit;
6437
0
        count = w;
6438
0
        run_length = 0;
6439
0
        startx = x;
6440
0
        current_bit = 0;
6441
0
        current_color = pdcolor0;
6442
6443
        /* Loop across each pixel of a line. */
6444
0
        do {
6445
0
            bit_value = (sbyte >> bit) & 1;
6446
0
            if (bit_value == current_bit) {
6447
                /* The value did not change, simply increment our run length */
6448
0
                run_length++;
6449
0
            } else {
6450
                /* The value changed, fill the current rectangle. */
6451
0
                if (run_length != 0) {
6452
0
                    if (current_color->type != gx_dc_type_pure &&
6453
0
                        current_color->colors.pure != gx_no_color_index) {
6454
0
                        code = pdf14_fill_rectangle_devn(dev, startx, y,
6455
0
                            run_length, 1, current_color);
6456
0
                        if (code < 0)
6457
0
                            return code;
6458
0
                    }
6459
0
                    startx += run_length;
6460
0
                }
6461
0
                run_length = 1;
6462
0
                current_color = bit_value ? pdcolor1 : pdcolor0;
6463
0
                current_bit = bit_value;
6464
0
            }
6465
6466
            /* Move to the next input bit. */
6467
0
            if (bit == 0) {
6468
0
                bit = 7;
6469
0
                sbyte = *sptr++;
6470
0
            } else
6471
0
                bit--;
6472
0
        } while (--count > 0);
6473
6474
        /* Fill the last rectangle in the line. */
6475
0
        if (run_length != 0 && current_color->type != gx_dc_type_pure &&
6476
0
            current_color->colors.pure != gx_no_color_index) {
6477
0
            code = pdf14_fill_rectangle_devn(dev, startx, y,
6478
0
                run_length, 1, current_color);
6479
0
            if (code < 0)
6480
0
                return code;
6481
0
        }
6482
        /* Move to the next line */
6483
0
        line += sraster;
6484
0
        y++;
6485
0
    }
6486
0
    return 0;
6487
0
}
6488
6489
/* Step through the tiles doing essentially copy_mono but with devn colors */
6490
static int
6491
pdf14_impl_strip_tile_rectangle_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6492
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6493
    const gx_drawing_color *pdcolor1, int px, int py)
6494
0
{   /* Fill the rectangle in chunks. */
6495
0
    int width = tiles->size.x;
6496
0
    int height = tiles->size.y;
6497
0
    int raster = tiles->raster;
6498
0
    int rwidth = tiles->rep_width;
6499
0
    int rheight = tiles->rep_height;
6500
0
    int shift = tiles->shift;
6501
6502
0
    if (rwidth == 0 || rheight == 0)
6503
0
        return_error(gs_error_unregistered);
6504
0
    fit_fill_xy(dev, x, y, w, h);
6505
6506
0
     {
6507
0
        int xoff = (shift == 0 ? px :
6508
0
                px + (y + py) / rheight * tiles->rep_shift);
6509
0
        int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */
6510
0
            (x + xoff) & (rwidth - 1) :
6511
0
            (x + xoff) % rwidth);
6512
0
        int ry = ((rheight & (rheight - 1)) == 0 ? /* power of 2 */
6513
0
            (y + py) & (rheight - 1) :
6514
0
            (y + py) % rheight);
6515
0
        int icw = width - irx;
6516
0
        int ch = height - ry;
6517
0
        byte *row = tiles->data + ry * raster;
6518
0
        int code = 0;
6519
6520
0
        if (ch >= h) {      /* Shallow operation */
6521
0
            if (icw >= w) { /* Just one (partial) tile to transfer. */
6522
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster, x, y,
6523
0
                    w, h, pdcolor0, pdcolor1);
6524
0
                if (code < 0)
6525
0
                    return_error(code);
6526
0
            } else {
6527
0
                int ex = x + w;
6528
0
                int fex = ex - width;
6529
0
                int cx = x + icw;
6530
6531
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6532
0
                    x, y, icw, h, pdcolor0, pdcolor1);
6533
0
                if (code < 0)
6534
0
                    return_error(code);
6535
6536
0
                while (cx <= fex) {
6537
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6538
0
                        width, h, pdcolor0, pdcolor1);
6539
0
                    if (code < 0)
6540
0
                        return_error(code);
6541
0
                    cx += width;
6542
0
                }
6543
0
                if (cx < ex) {
6544
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6545
0
                        ex - cx, h, pdcolor0, pdcolor1);
6546
0
                    if (code < 0)
6547
0
                        return_error(code);
6548
0
                }
6549
0
            }
6550
0
        } else if (icw >= w && shift == 0) {
6551
            /* Narrow operation, no shift */
6552
0
            int ey = y + h;
6553
0
            int fey = ey - height;
6554
0
            int cy = y + ch;
6555
6556
0
            code = pdf14_copy_mono_devn(dev, row, irx, raster,
6557
0
                x, y, w, ch, pdcolor0, pdcolor1);
6558
0
            if (code < 0)
6559
0
                return_error(code);
6560
0
            row = tiles->data;
6561
0
            do {
6562
0
                ch = (cy > fey ? ey - cy : height);
6563
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6564
0
                    x, cy, w, ch, pdcolor0, pdcolor1);
6565
0
                if (code < 0)
6566
0
                    return_error(code);
6567
0
            } while ((cy += ch) < ey);
6568
0
        } else {
6569
            /* Full operation.  If shift != 0, some scan lines */
6570
            /* may be narrow.  We could test shift == 0 in advance */
6571
            /* and use a slightly faster loop, but right now */
6572
            /* we don't bother. */
6573
0
            int ex = x + w, ey = y + h;
6574
0
            int fex = ex - width, fey = ey - height;
6575
0
            int cx, cy;
6576
6577
0
            for (cy = y;;) {
6578
0
                if (icw >= w) {
6579
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6580
0
                        x, cy, w, ch, pdcolor0, pdcolor1);
6581
0
                    if (code < 0)
6582
0
                        return_error(code);
6583
0
                } else {
6584
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6585
0
                        x, cy, icw, ch, pdcolor0, pdcolor1);
6586
0
                    if (code < 0)
6587
0
                        return_error(code);
6588
0
                    cx = x + icw;
6589
0
                    while (cx <= fex) {
6590
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6591
0
                            cx, cy, width, ch, pdcolor0, pdcolor1);
6592
0
                        if (code < 0)
6593
0
                            return_error(code);
6594
0
                        cx += width;
6595
0
                    }
6596
0
                    if (cx < ex) {
6597
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6598
0
                            cx, cy, ex - cx, ch, pdcolor0, pdcolor1);
6599
0
                        if (code < 0)
6600
0
                            return_error(code);
6601
0
                    }
6602
0
                }
6603
0
                if ((cy += ch) >= ey)
6604
0
                    break;
6605
0
                ch = (cy > fey ? ey - cy : height);
6606
0
                if ((irx += shift) >= rwidth)
6607
0
                    irx -= rwidth;
6608
0
                icw = width - irx;
6609
0
                row = tiles->data;
6610
0
            }
6611
0
        }
6612
0
    }
6613
0
    return 0;
6614
0
}
6615
6616
/* pdf14 device supports devn */
6617
static int
6618
pdf14_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6619
    int x, int y, int w, int h,
6620
    const gx_drawing_color *pdcolor0,
6621
    const gx_drawing_color *pdcolor1, int px, int py)
6622
0
{
6623
0
    pdf14_device *pdev = (pdf14_device *)dev;
6624
0
    pdf14_buf *buf;
6625
0
    int num_comp;
6626
0
    int k;
6627
0
    bool same = false;
6628
0
    int code;
6629
6630
0
    code = pdf14_initialize_ctx(dev, dev->color_info.num_components,
6631
0
        dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, NULL);
6632
0
    if (code < 0)
6633
0
        return code;
6634
0
    buf = pdev->ctx->stack;
6635
0
    num_comp = buf->n_chan - 1;
6636
6637
    /* if color0 is identical to color1, do rect fill */
6638
0
    if (pdcolor0->type == gx_dc_type_devn && pdcolor1->type == gx_dc_type_devn) {
6639
0
        same = true;
6640
0
        for (k = 0; k < num_comp; k++) {
6641
0
            if (pdcolor0->colors.devn.values[k] != pdcolor1->colors.devn.values[k]) {
6642
0
                same = false;
6643
0
                break;
6644
0
            }
6645
0
        }
6646
0
    }
6647
6648
0
    if (same) {
6649
0
        code = pdf14_fill_rectangle_devn(dev, x, y, w, h, pdcolor0);
6650
0
    } else {
6651
        /* Go through the tile stepping using code stolen from
6652
           gx_default_strip_tile_rectangle and call the rect fills
6653
           using code stolen from pdf14_copy_mono but using devn
6654
           colors */
6655
0
        code = pdf14_impl_strip_tile_rectangle_devn(dev, tiles,
6656
0
            x, y, w, h, pdcolor0, pdcolor1, px, py);
6657
0
    }
6658
0
    return code;
6659
0
}
6660
6661
/* Used in a few odd cases where the target device is planar and we have
6662
   a planar tile (pattern) and we are copying it into place here */
6663
static int
6664
pdf14_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
6665
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
6666
0
{
6667
0
    pdf14_device *pdev = (pdf14_device *)dev;
6668
#if RAW_DUMP
6669
    pdf14_ctx *ctx = pdev->ctx;
6670
#endif
6671
0
    pdf14_buf *buf = pdev->ctx->stack;
6672
0
    int xo = x;
6673
0
    int yo = y;
6674
0
    pdf14_buf fake_tos;
6675
0
    int deep = pdev->ctx->deep;
6676
6677
0
    fit_fill_xywh(dev, x, y, w, h);
6678
0
    if (w <= 0 || h <= 0)
6679
0
        return 0;
6680
6681
0
    fake_tos.deep = deep;
6682
0
    fake_tos.alpha = (uint16_t)(0xffff * pdev->alpha + 0.5);
6683
0
    fake_tos.backdrop = NULL;
6684
0
    fake_tos.blend_mode = pdev->blend_mode;
6685
0
    fake_tos.color_space = buf->color_space;
6686
0
    fake_tos.data = (byte *)data + ((data_x - (x - xo))<<deep) - (y - yo) * raster; /* Nasty, cast away of const */
6687
0
    fake_tos.dirty.p.x = x;
6688
0
    fake_tos.dirty.p.y = y;
6689
0
    fake_tos.dirty.q.x = x + w;
6690
0
    fake_tos.dirty.q.y = y + h;
6691
0
    fake_tos.has_alpha_g = 0;
6692
0
    fake_tos.has_shape = 0;
6693
0
    fake_tos.has_tags = 0;
6694
0
    fake_tos.idle = false;
6695
0
    fake_tos.isolated = false;
6696
0
    fake_tos.knockout = false;
6697
0
    fake_tos.mask_id = 0;
6698
0
    fake_tos.mask_stack = NULL;
6699
0
    fake_tos.matte = NULL;
6700
0
    fake_tos.matte_num_comps = 0;
6701
0
    fake_tos.memory = dev->memory;
6702
0
    fake_tos.n_chan = dev->color_info.num_components;
6703
0
    fake_tos.n_planes = dev->color_info.num_components;
6704
0
    fake_tos.num_spots = 0;
6705
0
    fake_tos.group_color_info = NULL;
6706
0
    fake_tos.planestride = raster * plane_height;
6707
0
    fake_tos.rect.p.x = x;
6708
0
    fake_tos.rect.p.y = y;
6709
0
    fake_tos.rect.q.x = x + w;
6710
0
    fake_tos.rect.q.y = y + h;
6711
0
    fake_tos.rowstride = raster;
6712
0
    fake_tos.saved = NULL;
6713
0
    fake_tos.shape = 0xffff;
6714
0
    fake_tos.SMask_SubType = TRANSPARENCY_MASK_Alpha;
6715
0
    fake_tos.transfer_fn = NULL;
6716
0
    pdf14_compose_alphaless_group(&fake_tos, buf, x, x+w, y, y+h,
6717
0
                                  pdev->ctx->memory, dev);
6718
0
    return 0;
6719
0
}
6720
6721
static int
6722
pdf14_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
6723
    const gs_gstate *pgs, const gx_drawing_color *pdcolor,
6724
    const gx_clip_path *pcpath)
6725
0
{
6726
0
    pdf14_device *pdev = (pdf14_device *)dev;
6727
0
    pdf14_buf* buf;
6728
0
    int code;
6729
0
    int x = fixed2int(rect->p.x);
6730
0
    int y = fixed2int(rect->p.y);
6731
0
    int w = fixed2int(rect->q.x) - x;
6732
0
    int h = fixed2int(rect->q.y) - y;
6733
6734
0
    fit_fill_xywh(dev, x, y, w, h);
6735
0
    if (w <= 0 || h <= 0)
6736
0
        return 0;
6737
6738
0
    code = pdf14_initialize_ctx(dev, dev->color_info.num_components,
6739
0
        dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, pgs);
6740
0
    if (code < 0)
6741
0
        return code;
6742
0
    buf = pdev->ctx->stack;
6743
6744
0
    if (buf->knockout)
6745
0
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
6746
0
                                                   true);
6747
0
    else
6748
0
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
6749
0
}
6750
6751
static  int
6752
pdf14_fill_rectangle(gx_device * dev,
6753
                    int x, int y, int w, int h, gx_color_index color)
6754
21.2M
{
6755
21.2M
    pdf14_device *pdev = (pdf14_device *)dev;
6756
21.2M
    pdf14_buf *buf;
6757
21.2M
    int code;
6758
6759
21.2M
    fit_fill_xywh(dev, x, y, w, h);
6760
21.2M
    if (w <= 0 || h <= 0)
6761
335k
        return 0;
6762
6763
20.9M
    code = pdf14_initialize_ctx(dev, dev->color_info.num_components,
6764
20.9M
            dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, NULL);
6765
20.9M
    if (code < 0)
6766
0
        return code;
6767
6768
20.9M
    buf = pdev->ctx->stack;
6769
6770
20.9M
    if (buf->knockout)
6771
204k
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, NULL,
6772
204k
                                                   false);
6773
20.7M
    else
6774
20.7M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, color, NULL, false);
6775
20.9M
}
6776
6777
static int
6778
pdf14_compute_group_device_int_rect(const gs_matrix *ctm,
6779
                                    const gs_rect *pbbox, gs_int_rect *rect)
6780
188k
{
6781
188k
    gs_rect dev_bbox;
6782
188k
    int code;
6783
6784
188k
    code = gs_bbox_transform(pbbox, ctm, &dev_bbox);
6785
188k
    if (code < 0)
6786
0
        return code;
6787
188k
    rect->p.x = (int)floor(dev_bbox.p.x);
6788
188k
    rect->p.y = (int)floor(dev_bbox.p.y);
6789
188k
    rect->q.x = (int)ceil(dev_bbox.q.x);
6790
188k
    rect->q.y = (int)ceil(dev_bbox.q.y);
6791
188k
    return 0;
6792
188k
}
6793
6794
static  int
6795
compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
6796
                              const gs_rect *pbbox, gs_gstate *pgs)
6797
184k
{
6798
184k
    int code = pdf14_compute_group_device_int_rect(&ctm_only(pgs), pbbox, rect);
6799
6800
184k
    if (code < 0)
6801
0
        return code;
6802
184k
    rect_intersect(*rect, pdev->ctx->rect);
6803
    /* Make sure the rectangle is not anomalous (q < p) -- see gsrect.h */
6804
184k
    if (rect->q.x < rect->p.x)
6805
7.90k
        rect->q.x = rect->p.x;
6806
184k
    if (rect->q.y < rect->p.y)
6807
12.4k
        rect->q.y = rect->p.y;
6808
184k
    return 0;
6809
184k
}
6810
6811
static  int
6812
pdf14_begin_transparency_group(gx_device* dev,
6813
    const gs_transparency_group_params_t* ptgp,
6814
    const gs_rect* pbbox,
6815
    gs_gstate* pgs, gs_memory_t* mem)
6816
164k
{
6817
164k
    pdf14_device* pdev = (pdf14_device*)dev;
6818
164k
    float alpha = ptgp->group_opacity * ptgp->group_shape;
6819
164k
    gs_int_rect rect;
6820
164k
    int code;
6821
164k
    bool isolated = ptgp->Isolated;
6822
164k
    gs_transparency_color_t group_color_type;
6823
164k
    cmm_profile_t* group_profile;
6824
164k
    cmm_profile_t* tos_profile;
6825
164k
    gsicc_rendering_param_t render_cond;
6826
164k
    cmm_dev_profile_t* dev_profile;
6827
164k
    bool cm_back_drop = false;
6828
164k
    bool new_icc = false;
6829
164k
    pdf14_group_color_t* group_color_info;
6830
6831
164k
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
6832
164k
    if (code < 0)
6833
0
        return code;
6834
164k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &tos_profile, &render_cond);
6835
6836
164k
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
6837
3.52k
        pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* For immediate mode and clist reading */
6838
3.52k
    }
6839
6840
164k
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED)
6841
3.52k
        rect = pdev->ctx->rect; /* Use parent group for text_group. */
6842
161k
    else
6843
161k
        code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
6844
6845
164k
    if (code < 0)
6846
0
        return code;
6847
164k
    if_debug5m('v', pdev->memory,
6848
164k
        "[v]pdf14_begin_transparency_group, I = %d, K = %d, alpha = %g, bm = %d page_group = %d\n",
6849
164k
        ptgp->Isolated, ptgp->Knockout, (double)alpha, pgs->blend_mode, ptgp->page_group);
6850
6851
    /* If the group color is unknown then use the current device profile. */
6852
164k
    if (ptgp->group_color_type == UNKNOWN) {
6853
126k
        group_color_type = ICC;
6854
126k
        group_profile = tos_profile;
6855
126k
    }
6856
37.8k
    else {
6857
37.8k
        group_color_type = ptgp->group_color_type;
6858
37.8k
        group_profile = ptgp->iccprofile;
6859
37.8k
    }
6860
6861
    /* We have to handle case where the profile is in the clist */
6862
164k
    if (group_profile == NULL && pdev->pclist_device != NULL) {
6863
        /* Get the serialized data from the clist. */
6864
37.8k
        gx_device_clist_reader* pcrdev = (gx_device_clist_reader*)(pdev->pclist_device);
6865
37.8k
        group_profile = gsicc_read_serial_icc((gx_device*)pcrdev, ptgp->icc_hashcode);
6866
37.8k
        if (group_profile == NULL)
6867
0
            return gs_throw(gs_error_unknownerror, "ICC data not found in clist");
6868
        /* Keep a pointer to the clist device */
6869
37.8k
        group_profile->dev = (gx_device*)pcrdev;
6870
37.8k
        new_icc = true;
6871
37.8k
    }
6872
164k
    if (group_profile != NULL) {
6873
        /* If we have a non-isolated group and the color space is different,
6874
            we will need to CM the backdrop. */
6875
164k
        if (!gsicc_profiles_equal(group_profile, tos_profile)) {
6876
3.65k
            cm_back_drop = true;
6877
3.65k
        }
6878
164k
    }
6879
6880
    /* Always create the base color group information as it is only through
6881
       groups that we can have a color space change.  This will survive
6882
       the life of the context. */
6883
164k
    if (pdev->ctx->base_color == NULL) {
6884
30.1k
        pdev->ctx->base_color = pdf14_make_base_group_color(dev);
6885
30.1k
    }
6886
6887
    /* If this is not the page group and we don't yet have a group, we need
6888
       to create a buffer for the whole page so that we can handle stuff drawn
6889
       outside this current group (e.g. two non inclusive groups drawn independently) */
6890
164k
    if (pdev->ctx->stack == NULL && !ptgp->page_group) {
6891
684
        code = pdf14_initialize_ctx(dev, dev->color_info.num_components,
6892
684
            dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, NULL);
6893
684
        if (code < 0)
6894
0
            return code;
6895
684
        pdev->ctx->stack->isolated = true;
6896
684
    }
6897
6898
164k
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptgp->icc_hashcode,
6899
164k
        group_profile, false);
6900
164k
    if (group_color_info == NULL)
6901
0
        return gs_error_VMerror;
6902
164k
    if_debug0m('v', dev->memory, "[v]Transparency group color space update\n");
6903
6904
164k
    code = pdf14_push_transparency_group(pdev->ctx, &rect, isolated, ptgp->Knockout,
6905
164k
                                        (uint16_t)floor (65535 * alpha + 0.5),
6906
164k
                                        (uint16_t)floor(65535 * ptgp->group_shape + 0.5),
6907
164k
                                        (uint16_t)floor(65535 * ptgp->group_opacity + 0.5),
6908
164k
                                        pgs->blend_mode, ptgp->idle,
6909
164k
                                         ptgp->mask_id, pdev->color_info.num_components,
6910
164k
                                         cm_back_drop, ptgp->shade_group,
6911
164k
                                         group_profile, tos_profile, group_color_info, pgs, dev);
6912
164k
    if (new_icc)
6913
37.8k
        gsicc_adjust_profile_rc(group_profile, -1, "pdf14_begin_transparency_group");
6914
164k
    return code;
6915
164k
}
6916
6917
static void
6918
pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color)
6919
164k
{
6920
164k
    pdf14_device* pdev = (pdf14_device*)dev;
6921
6922
164k
    if (group_color != NULL &&
6923
164k
        !(group_color->group_color_mapping_procs == NULL &&
6924
164k
            group_color->group_color_comp_index == NULL)) {
6925
164k
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
6926
164k
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
6927
164k
        pdev->color_info.polarity = group_color->polarity;
6928
164k
        pdev->color_info.num_components = group_color->num_components;
6929
164k
        pdev->blend_procs = group_color->blend_procs;
6930
164k
        pdev->ctx->additive = group_color->isadditive;
6931
164k
        pdev->pdf14_procs = group_color->unpack_procs;
6932
164k
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
6933
164k
        pdev->color_info.depth = group_color->depth;
6934
164k
        pdev->color_info.max_color = group_color->max_color;
6935
164k
        pdev->color_info.max_gray = group_color->max_gray;
6936
164k
        memcpy(&(pdev->color_info.comp_bits), &(group_color->comp_bits),
6937
164k
            GX_DEVICE_COLOR_MAX_COMPONENTS);
6938
164k
        memcpy(&(pdev->color_info.comp_shift), &(group_color->comp_shift),
6939
164k
            GX_DEVICE_COLOR_MAX_COMPONENTS);
6940
164k
        if (group_color->icc_profile != NULL) {
6941
            /* make sure to decrement the device profile.  If it was allocated
6942
               with the push then it will be freed. */
6943
164k
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
6944
164k
                                    -1, "pdf14_pop_color_model");
6945
164k
            pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
6946
164k
                                    group_color->icc_profile;
6947
6948
164k
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
6949
164k
                                    1, "pdf14_pop_color_model");
6950
164k
        }
6951
164k
    }
6952
164k
}
6953
6954
static  int
6955
pdf14_end_transparency_group(gx_device* dev, gs_gstate* pgs)
6956
164k
{
6957
164k
    pdf14_device* pdev = (pdf14_device*)dev;
6958
164k
    int code;
6959
164k
    cmm_profile_t* group_profile;
6960
164k
    gsicc_rendering_param_t render_cond;
6961
164k
    cmm_dev_profile_t* dev_profile;
6962
6963
164k
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
6964
164k
    if (code < 0)
6965
0
        return code;
6966
6967
164k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
6968
164k
        &render_cond);
6969
164k
    if_debug0m('v', dev->memory, "[v]pdf14_end_transparency_group\n");
6970
6971
164k
    code = pdf14_pop_transparency_group(pgs, pdev->ctx, pdev->blend_procs,
6972
164k
        pdev->color_info.num_components, group_profile, (gx_device*)pdev);
6973
164k
    if (code < 0)
6974
0
        return code;
6975
#ifdef DEBUG
6976
    pdf14_debug_mask_stack_state(pdev->ctx);
6977
#endif
6978
    /* If this group is the base group, then restore the color model
6979
       of the device at this time.  Note that during the actual device pop
6980
       we will need to use the profile of the buffer not the pdf14 device
6981
       as the source color space */
6982
164k
    if (pdev->ctx->stack->group_popped) {
6983
27.5k
        pdf14_pop_color_model(dev, pdev->ctx->base_color);
6984
137k
    } else {
6985
137k
        pdf14_pop_color_model(dev, pdev->ctx->stack->group_color_info);
6986
137k
    }
6987
6988
164k
    return code;
6989
164k
}
6990
6991
static pdf14_group_color_t*
6992
pdf14_push_color_model(gx_device *dev, gs_transparency_color_t group_color_type,
6993
                        int64_t icc_hashcode, cmm_profile_t *iccprofile,
6994
                        bool is_mask)
6995
187k
{
6996
187k
    pdf14_device *pdevproto = NULL;
6997
187k
    pdf14_device *pdev = (pdf14_device *)dev;
6998
187k
    const pdf14_procs_t *new_14procs = NULL;
6999
187k
    pdf14_group_color_t *group_color;
7000
187k
    gx_color_polarity_t new_polarity;
7001
187k
    uchar new_num_comps;
7002
187k
    bool new_additive;
7003
187k
    gx_device_clist_reader *pcrdev;
7004
187k
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7005
187k
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7006
187k
    int k;
7007
187k
    bool has_tags = device_encodes_tags(dev);
7008
187k
    bool deep = pdev->ctx->deep;
7009
7010
187k
    if_debug0m('v', dev->memory, "[v]pdf14_push_color_model\n");
7011
7012
187k
    group_color = gs_alloc_struct(dev->memory->stable_memory,
7013
187k
                               pdf14_group_color_t, &st_pdf14_clr,
7014
187k
                               "pdf14_push_color_model");
7015
187k
    if (group_color == NULL)
7016
0
        return NULL;
7017
7018
187k
    memset(group_color, 0, sizeof(pdf14_group_color_t));
7019
7020
187k
    switch (group_color_type) {
7021
0
        case GRAY_SCALE:
7022
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7023
0
            new_num_comps = 1;
7024
0
            pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7025
0
            new_additive = true;
7026
0
            new_14procs = &gray_pdf14_procs;
7027
0
            comp_bits[0] = 8<<deep;
7028
0
            comp_shift[0] = 0;
7029
0
            break;
7030
0
        case DEVICE_RGB:
7031
0
        case CIE_XYZ:
7032
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7033
0
            new_num_comps = 3;
7034
0
            pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7035
0
            new_additive = true;
7036
0
            new_14procs = &rgb_pdf14_procs;
7037
0
            for (k = 0; k < 3; k++) {
7038
0
                comp_bits[k] = 8<<deep;
7039
0
                comp_shift[k] = (2 - k) * (8<<deep);
7040
0
            }
7041
0
            break;
7042
0
        case DEVICE_CMYK:
7043
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7044
0
            new_num_comps = 4;
7045
0
            pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7046
0
            new_additive = false;
7047
            /* This is needed due to the mismatched compressed encode decode
7048
                between the device procs and the pdf14 procs */
7049
0
            if (dev->color_info.num_components > 4){
7050
0
                new_14procs = &cmykspot_pdf14_procs;
7051
0
            } else {
7052
0
                new_14procs = &cmyk_pdf14_procs;
7053
0
            }
7054
0
            for (k = 0; k < 4; k++) {
7055
0
                comp_bits[k] = 8<<deep;
7056
0
                comp_shift[k] = (3 - k) * (8<<deep);
7057
0
            }
7058
0
            break;
7059
187k
        case ICC:
7060
            /* If we are coming from the clist reader, then we need to get
7061
                the ICC data now  */
7062
187k
            if (iccprofile == NULL && pdev->pclist_device != NULL) {
7063
                /* Get the serialized data from the clist.  Not the whole
7064
                    profile. */
7065
22.3k
                pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
7066
22.3k
                iccprofile = gsicc_read_serial_icc((gx_device *) pcrdev,
7067
22.3k
                                                    icc_hashcode);
7068
22.3k
                if (iccprofile == NULL)
7069
0
                    return NULL;
7070
                /* Keep a pointer to the clist device */
7071
22.3k
                iccprofile->dev = (gx_device *) pcrdev;
7072
165k
            } else {
7073
                /* Go ahead and rc increment right now.  This way when
7074
                    we pop, we will make sure to decrement and avoid a
7075
                    leak for the above profile that we just created.  This
7076
                    goes with the assignment to the device's profile.
7077
                    Note that we still do the increment for the group_color
7078
                    assignment below. */
7079
165k
                if (iccprofile == NULL)
7080
0
                    return NULL;
7081
165k
                gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7082
165k
            }
7083
187k
            new_num_comps = iccprofile->num_comps;
7084
187k
            if (new_num_comps == 4) {
7085
118k
                new_additive = false;
7086
118k
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7087
118k
            } else {
7088
69.4k
                new_additive = true;
7089
69.4k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7090
69.4k
            }
7091
187k
            switch (new_num_comps) {
7092
22.9k
                case 1:
7093
22.9k
                    if (pdev->sep_device && !is_mask) {
7094
0
                        pdevproto = (pdf14_device *)&gs_pdf14_Grayspot_device;
7095
0
                        new_14procs = &grayspot_pdf14_procs;
7096
22.9k
                    } else {
7097
22.9k
                        pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7098
22.9k
                        new_14procs = &gray_pdf14_procs;
7099
22.9k
                    }
7100
22.9k
                    comp_bits[0] = 8<<deep;
7101
22.9k
                    comp_shift[0] = 0;
7102
22.9k
                    break;
7103
46.4k
                case 3:
7104
46.4k
                    if (pdev->sep_device) {
7105
0
                        pdevproto = (pdf14_device *)&gs_pdf14_RGBspot_device;
7106
0
                        new_14procs = &rgbspot_pdf14_procs;
7107
0
                    }
7108
46.4k
                    else {
7109
46.4k
                        pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7110
46.4k
                        new_14procs = &rgb_pdf14_procs;
7111
46.4k
                    }
7112
185k
                    for (k = 0; k < 3; k++) {
7113
139k
                        comp_bits[k] = 8<<deep;
7114
139k
                        comp_shift[k] = (2 - k) * (8<<deep);
7115
139k
                    }
7116
46.4k
                    break;
7117
118k
                case 4:
7118
118k
                    if (pdev->sep_device) {
7119
0
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYKspot_device;
7120
0
                        new_14procs = &cmykspot_pdf14_procs;
7121
118k
                    } else {
7122
118k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7123
118k
                        new_14procs = &cmyk_pdf14_procs;
7124
118k
                    }
7125
590k
                    for (k = 0; k < 4; k++) {
7126
472k
                        comp_bits[k] = 8<<deep;
7127
472k
                        comp_shift[k] = (3 - k) * (8<<deep);
7128
472k
                    }
7129
118k
                    break;
7130
0
                default:
7131
0
                    return NULL;
7132
0
                    break;
7133
187k
            }
7134
187k
            break;
7135
187k
        default:
7136
0
            return NULL;
7137
0
            break;
7138
187k
    }
7139
7140
187k
    if (group_color_type == ICC && iccprofile != NULL) {
7141
187k
        group_color->icc_profile = iccprofile;
7142
187k
        gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7143
187k
    }
7144
7145
    /* If we are a sep device and this is not a softmask, ensure we maintain the
7146
       spot colorants and know how to index into them */
7147
187k
    if (pdev->sep_device && !is_mask) {
7148
0
        int num_spots = dev->color_info.num_components -
7149
0
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps;
7150
7151
0
        if (num_spots > 0) {
7152
0
            new_num_comps += num_spots;
7153
0
            for (k = 0; k < new_num_comps; k++) {
7154
0
                comp_bits[k] = 8<<deep;
7155
0
                comp_shift[k] = (new_num_comps - k - 1) * (8<<deep);
7156
0
            }
7157
0
        }
7158
0
    }
7159
7160
    /* Set device values now and store settings in group_color.  Then they
7161
       are available when we pop the previous group */
7162
187k
    if_debug2m('v', pdev->memory,
7163
187k
                "[v]pdf14_push_color_model, num_components_old = %d num_components_new = %d\n",
7164
187k
                pdev->color_info.num_components,new_num_comps);
7165
187k
    {
7166
187k
        gx_device local_device;
7167
7168
187k
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7169
187k
        local_device.initialize_device_procs((gx_device *)&local_device);
7170
187k
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7171
187k
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7172
187k
    }
7173
187k
    group_color->blend_procs = pdev->blend_procs = pdevproto->blend_procs;
7174
187k
    group_color->polarity = pdev->color_info.polarity = new_polarity;
7175
187k
    group_color->num_components = pdev->color_info.num_components = new_num_comps;
7176
187k
    group_color->isadditive = pdev->ctx->additive = new_additive;
7177
187k
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7178
187k
    group_color->unpack_procs = pdev->pdf14_procs = new_14procs;
7179
187k
    pdev->color_info.depth = new_num_comps * (8<<deep);
7180
187k
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7181
187k
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7182
187k
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7183
187k
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7184
187k
    if (has_tags) {
7185
0
        pdev->color_info.comp_shift[pdev->color_info.num_components] = pdev->color_info.depth;
7186
0
        pdev->color_info.depth += 8;
7187
0
    }
7188
187k
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
7189
187k
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
7190
187k
    group_color->depth = pdev->color_info.depth;
7191
187k
    group_color->decode = dev_proc(pdev, decode_color);
7192
187k
    group_color->encode = dev_proc(pdev, encode_color);
7193
187k
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
7194
187k
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
7195
187k
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
7196
187k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7197
187k
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
7198
187k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7199
187k
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
7200
7201
    /* If the CS was ICC based, we need to update the device ICC profile
7202
        in the ICC manager, since that is the profile that is used for the
7203
        PDF14 device */
7204
187k
    if (group_color_type == ICC && iccprofile != NULL) {
7205
        /* iccprofile was incremented above if we had not just created it.
7206
           When we do the pop we will decrement and if we just created it, it
7207
           will be destroyed */
7208
187k
        gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_push_color_model");
7209
187k
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = iccprofile;
7210
187k
    }
7211
187k
    return group_color;
7212
187k
}
7213
7214
static int
7215
pdf14_clist_push_color_model(gx_device *dev, gx_device* cdev, gs_gstate *pgs,
7216
                             const gs_pdf14trans_t *pdf14pct, gs_memory_t* mem,
7217
                             bool is_mask)
7218
3.89k
{
7219
3.89k
    pdf14_device* pdev = (pdf14_device*)dev;
7220
3.89k
    pdf14_group_color_t* new_group_color;
7221
3.89k
    gsicc_rendering_param_t render_cond;
7222
3.89k
    cmm_dev_profile_t* dev_profile;
7223
3.89k
    pdf14_device* pdevproto;
7224
3.89k
    gx_device_clist_writer* cldev = (gx_device_clist_writer*)pdev->pclist_device;
7225
3.89k
    const pdf14_procs_t* new_14procs;
7226
3.89k
    bool update_color_info;
7227
3.89k
    gx_color_polarity_t new_polarity;
7228
3.89k
    int new_num_comps;
7229
3.89k
    bool new_additive = false;
7230
3.89k
    byte new_depth;
7231
3.89k
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7232
3.89k
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7233
3.89k
    int k;
7234
3.89k
    bool has_tags = device_encodes_tags(dev);
7235
3.89k
    bool deep = device_is_deep(dev);
7236
3.89k
    gs_transparency_color_t group_color_type = pdf14pct->params.group_color_type;
7237
3.89k
    cmm_profile_t *new_profile = pdf14pct->params.iccprofile;
7238
3.89k
    cmm_profile_t *old_profile = NULL;
7239
7240
3.89k
    dev_proc(dev, get_profile)(dev, &dev_profile);
7241
3.89k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &old_profile,
7242
3.89k
        &render_cond);
7243
3.89k
    if_debug0m('v', dev->memory, "[v]pdf14_clist_push_color_model\n");
7244
7245
    /* Allocate a new one */
7246
3.89k
    new_group_color = gs_alloc_struct(dev->memory->stable_memory, pdf14_group_color_t,
7247
3.89k
        &st_pdf14_clr, "pdf14_clist_push_color_model");
7248
7249
3.89k
    if (new_group_color == NULL)
7250
0
        return_error(gs_error_VMerror);
7251
7252
    /* Link to old one */
7253
3.89k
    new_group_color->previous = pdev->color_model_stack;
7254
7255
    /* Reassign new one to dev */
7256
3.89k
    pdev->color_model_stack = new_group_color;
7257
7258
    /* Initialize with values */
7259
3.89k
    new_group_color->get_cmap_procs = pgs->get_cmap_procs;
7260
3.89k
    new_group_color->group_color_mapping_procs =
7261
3.89k
        dev_proc(pdev, get_color_mapping_procs);
7262
3.89k
    new_group_color->group_color_comp_index =
7263
3.89k
        dev_proc(pdev, get_color_comp_index);
7264
3.89k
    new_group_color->blend_procs = pdev->blend_procs;
7265
3.89k
    new_group_color->polarity = pdev->color_info.polarity;
7266
3.89k
    new_group_color->num_components = pdev->color_info.num_components;
7267
3.89k
    new_group_color->unpack_procs = pdev->pdf14_procs;
7268
3.89k
    new_group_color->depth = pdev->color_info.depth;
7269
3.89k
    new_group_color->max_color = pdev->color_info.max_color;
7270
3.89k
    new_group_color->max_gray = pdev->color_info.max_gray;
7271
3.89k
    new_group_color->decode = dev_proc(pdev, decode_color);
7272
3.89k
    new_group_color->encode = dev_proc(pdev, encode_color);
7273
3.89k
    memcpy(&(new_group_color->comp_bits), &(pdev->color_info.comp_bits),
7274
3.89k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7275
3.89k
    memcpy(&(new_group_color->comp_shift), &(pdev->color_info.comp_shift),
7276
3.89k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7277
7278
3.89k
    if (new_profile == NULL)
7279
2.29k
        new_group_color->icc_profile = NULL;
7280
7281
    /* isadditive is only used in ctx */
7282
3.89k
    if (pdev->ctx) {
7283
0
        new_group_color->isadditive = pdev->ctx->additive;
7284
0
    }
7285
7286
3.89k
    memset(comp_bits, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7287
3.89k
    memset(comp_shift, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7288
7289
3.89k
    if (group_color_type == ICC && new_profile == NULL)
7290
0
        return gs_throw(gs_error_undefinedresult, "Missing ICC data");
7291
3.89k
    if_debug0m('v', cldev->memory, "[v]pdf14_clist_push_color_model\n");
7292
    /* Check if we need to alter the device procs at this stage.  Many of the procs
7293
       are based upon the color space of the device.  We want to remain in the
7294
       color space defined by the color space of the soft mask or transparency
7295
       group as opposed to the device color space. Later, when we pop the softmask
7296
       we will collapse it to a single band and then compose with it to the device
7297
       color space (or the parent layer space).  In the case where we pop an
7298
       isolated transparency group, we will do the blending in the proper color
7299
       space and then transform the data when we pop the group.  Remember that only
7300
       isolated groups can have color spaces that are different than their parent. */
7301
3.89k
    update_color_info = false;
7302
3.89k
    switch (group_color_type) {
7303
0
    case GRAY_SCALE:
7304
0
        if (pdev->color_info.num_components != 1) {
7305
0
            update_color_info = true;
7306
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7307
0
            new_num_comps = 1;
7308
0
            pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7309
0
            new_additive = true;
7310
0
            new_14procs = &gray_pdf14_procs;
7311
0
            new_depth = 8 << deep;
7312
0
            comp_bits[0] = 8 << deep;
7313
0
            comp_shift[0] = 0;
7314
0
        }
7315
0
        break;
7316
0
    case DEVICE_RGB:
7317
0
    case CIE_XYZ:
7318
0
        if (pdev->color_info.num_components != 3) {
7319
0
            update_color_info = true;
7320
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7321
0
            new_num_comps = 3;
7322
0
            pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7323
0
            new_additive = true;
7324
0
            new_14procs = &rgb_pdf14_procs;
7325
0
            new_depth = 24 << deep;
7326
0
            for (k = 0; k < 3; k++) {
7327
0
                comp_bits[k] = 8 << deep;
7328
0
                comp_shift[k] = (2 - k) * (8 << deep);
7329
0
            }
7330
0
        }
7331
0
        break;
7332
0
    case DEVICE_CMYK:
7333
0
        if (pdev->color_info.num_components != 4) {
7334
0
            update_color_info = true;
7335
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7336
0
            new_num_comps = 4;
7337
0
            pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7338
0
            new_additive = false;
7339
            /* This is needed due to the mismatched compressed encode decode
7340
               between the device procs and the pdf14 procs */
7341
0
            if (dev->color_info.num_components > 4) {
7342
0
                new_14procs = &cmykspot_pdf14_procs;
7343
0
            }
7344
0
            else {
7345
0
                new_14procs = &cmyk_pdf14_procs;
7346
0
            }
7347
0
            new_depth = 32 << deep;
7348
0
            for (k = 0; k < 4; k++) {
7349
0
                comp_bits[k] = 8 << deep;
7350
0
                comp_shift[k] = (3 - k) * (8 << deep);
7351
0
            }
7352
0
        }
7353
0
        break;
7354
1.60k
    case ICC:
7355
        /* Check if the profile is different. */
7356
1.60k
        if (!gsicc_profiles_equal(old_profile, new_profile)) {
7357
1.37k
            update_color_info = true;
7358
1.37k
            new_num_comps = new_profile->num_comps;
7359
1.37k
            new_depth = new_profile->num_comps * (8 << deep);
7360
1.37k
            switch (new_num_comps) {
7361
1.33k
            case 1:
7362
1.33k
                if (pdev->sep_device && !is_mask) {
7363
0
                    pdevproto = (pdf14_device*)&gs_pdf14_Grayspot_device;
7364
0
                    new_14procs = &grayspot_pdf14_procs;
7365
0
                }
7366
1.33k
                else {
7367
1.33k
                    pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7368
1.33k
                    new_14procs = &gray_pdf14_procs;
7369
1.33k
                }
7370
1.33k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7371
1.33k
                new_additive = true;
7372
1.33k
                comp_bits[0] = 8 << deep;
7373
1.33k
                comp_shift[0] = 0;
7374
1.33k
                break;
7375
3
            case 3:
7376
3
                if (pdev->sep_device) {
7377
0
                    pdevproto = (pdf14_device*)&gs_pdf14_RGBspot_device;
7378
0
                    new_14procs = &rgbspot_pdf14_procs;
7379
0
                }
7380
3
                else {
7381
3
                    pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7382
3
                    new_14procs = &rgb_pdf14_procs;
7383
3
                }
7384
3
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7385
3
                new_additive = true;
7386
12
                for (k = 0; k < 3; k++) {
7387
9
                    comp_bits[k] = 8 << deep;
7388
9
                    comp_shift[k] = (2 - k) * (8 << deep);
7389
9
                }
7390
3
                break;
7391
45
            case 4:
7392
45
                if (pdev->sep_device) {
7393
0
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYKspot_device;
7394
0
                    new_14procs = &cmykspot_pdf14_procs;
7395
0
                }
7396
45
                else {
7397
45
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7398
45
                    new_14procs = &cmyk_pdf14_procs;
7399
45
                }
7400
45
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7401
45
                new_additive = false;
7402
225
                for (k = 0; k < 4; k++) {
7403
180
                    comp_bits[k] = 8 << deep;
7404
180
                    comp_shift[k] = (3 - k) * (8 << deep);
7405
180
                }
7406
45
                break;
7407
0
            default:
7408
0
                return gs_throw(gs_error_undefinedresult,
7409
1.37k
                    "ICC Number of colorants illegal");
7410
1.37k
            }
7411
1.37k
        }
7412
1.60k
        break;
7413
2.29k
    case UNKNOWN:
7414
2.29k
        return 0;
7415
0
        break;
7416
0
    default:
7417
0
        return_error(gs_error_rangecheck);
7418
0
        break;
7419
3.89k
    }
7420
7421
1.60k
    if (!update_color_info) {
7422
        /* Profile not updated */
7423
223
        new_group_color->icc_profile = NULL;
7424
223
        if_debug0m('v', pdev->memory, "[v]procs not updated\n");
7425
223
        return 0;
7426
223
    }
7427
7428
1.37k
    if (pdev->sep_device && !is_mask) {
7429
0
        int num_spots;
7430
7431
0
        if (old_profile == NULL)
7432
0
            return_error(gs_error_undefined);
7433
7434
0
        num_spots = pdev->color_info.num_components - old_profile->num_comps;
7435
7436
0
        if (num_spots > 0) {
7437
0
            new_num_comps += num_spots;
7438
0
            for (k = 0; k < new_num_comps; k++) {
7439
0
                comp_bits[k] = 8 << deep;
7440
0
                comp_shift[k] = (new_num_comps - k - 1) * (8 << deep);
7441
0
            }
7442
0
            new_depth = (8 << deep) * new_num_comps;
7443
0
        }
7444
0
    }
7445
1.37k
    if (has_tags) {
7446
0
        new_depth += 8;
7447
0
    }
7448
1.37k
    if_debug2m('v', pdev->memory,
7449
1.37k
        "[v]pdf14_clist_push_color_model, num_components_old = %d num_components_new = %d\n",
7450
1.37k
        pdev->color_info.num_components, new_num_comps);
7451
    /* Set new information in the device */
7452
1.37k
    {
7453
1.37k
        gx_device local_device;
7454
7455
1.37k
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7456
1.37k
        local_device.initialize_device_procs((gx_device *)&local_device);
7457
1.37k
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7458
1.37k
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7459
1.37k
    }
7460
1.37k
    pdev->blend_procs = pdevproto->blend_procs;
7461
1.37k
    pdev->color_info.polarity = new_polarity;
7462
1.37k
    pdev->color_info.num_components = new_num_comps;
7463
1.37k
    pdev->color_info.max_color = deep ? 65535 : 255;
7464
1.37k
    pdev->color_info.max_gray = deep ? 65535 : 255;
7465
1.37k
    pdev->pdf14_procs = new_14procs;
7466
1.37k
    pdev->color_info.depth = new_depth;
7467
1.37k
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7468
1.37k
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7469
1.37k
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7470
1.37k
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7471
1.37k
    pdev->color_info.comp_shift[new_num_comps] = new_depth - 8; /* in case we has_tags is set */
7472
1.37k
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7473
7474
    /* If we have a compressed color codec, and we are doing a soft mask
7475
       push operation then go ahead and update the color encode and
7476
       decode for the pdf14 device to not used compressed color
7477
       encoding while in the soft mask.  We will just check for gray
7478
       and compressed.  Note that we probably don't have_tags if we
7479
       are dealing with compressed color.  But is is possible so
7480
       we add it in to catch for future use. */
7481
1.37k
    cldev->clist_color_info.depth = pdev->color_info.depth;
7482
1.37k
    cldev->clist_color_info.polarity = pdev->color_info.polarity;
7483
1.37k
    cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7484
1.37k
    cldev->clist_color_info.num_components = pdev->color_info.num_components;
7485
1.37k
    cldev->clist_color_info.max_color = pdev->color_info.max_color;
7486
1.37k
    cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7487
    /* For the ICC profiles, we want to update the ICC profile for the
7488
       device.  We store the original in group_color.
7489
       That will be stored in the clist and restored during the reading phase. */
7490
1.37k
    if (group_color_type == ICC) {
7491
1.37k
        gsicc_adjust_profile_rc(new_profile, 1, "pdf14_clist_push_color_model");
7492
1.37k
        new_group_color->icc_profile =
7493
1.37k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
7494
1.37k
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = new_profile;
7495
1.37k
    }
7496
1.37k
    if (pdev->ctx) {
7497
0
        pdev->ctx->additive = new_additive;
7498
0
    }
7499
1.37k
    return 1;  /* Lets us detect that we did do an update */
7500
1.37k
}
7501
7502
static int
7503
pdf14_clist_pop_color_model(gx_device *dev, gs_gstate *pgs)
7504
3.87k
{
7505
7506
3.87k
    pdf14_device *pdev = (pdf14_device *)dev;
7507
3.87k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7508
3.87k
    gx_device_clist_writer * cldev = (gx_device_clist_writer *)pdev->pclist_device;
7509
7510
3.87k
    if (group_color == NULL)
7511
0
        return_error(gs_error_Fatal);  /* Unmatched group pop */
7512
7513
3.87k
    if_debug0m('v', pdev->memory, "[v]pdf14_clist_pop_color_model\n");
7514
    /* The color procs are always pushed.  Simply restore them. */
7515
3.87k
    if (group_color->group_color_mapping_procs == NULL &&
7516
3.87k
        group_color->group_color_comp_index == NULL) {
7517
0
        if_debug0m('v', dev->memory, "[v]pdf14_clist_pop_color_model ERROR \n");
7518
3.87k
    } else {
7519
3.87k
        if_debug2m('v', pdev->memory,
7520
3.87k
                   "[v]pdf14_clist_pop_color_model, num_components_old = %d num_components_new = %d\n",
7521
3.87k
                   pdev->color_info.num_components,group_color->num_components);
7522
3.87k
        pgs->get_cmap_procs = group_color->get_cmap_procs;
7523
3.87k
        gx_set_cmap_procs(pgs, dev);
7524
3.87k
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7525
3.87k
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7526
3.87k
        pdev->color_info.polarity = group_color->polarity;
7527
3.87k
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7528
3.87k
        pdev->color_info.depth = group_color->depth;
7529
3.87k
        pdev->color_info.num_components = group_color->num_components;
7530
3.87k
        pdev->blend_procs = group_color->blend_procs;
7531
3.87k
        pdev->pdf14_procs = group_color->unpack_procs;
7532
3.87k
        pdev->color_info.max_color = group_color->max_color;
7533
3.87k
        pdev->color_info.max_gray = group_color->max_gray;
7534
3.87k
        set_dev_proc(pdev, encode_color, group_color->encode);
7535
3.87k
        set_dev_proc(pdev, decode_color, group_color->decode);
7536
3.87k
        memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
7537
3.87k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7538
3.87k
        memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
7539
3.87k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7540
7541
        /* clist writer fill rect has no access to gs_gstate */
7542
        /* and it forwards the target device.  this information */
7543
        /* is passed along to use in this case */
7544
3.87k
        cldev->clist_color_info.depth = pdev->color_info.depth;
7545
3.87k
        cldev->clist_color_info.polarity = pdev->color_info.polarity;
7546
3.87k
        cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7547
3.87k
        cldev->clist_color_info.num_components = pdev->color_info.num_components;
7548
3.87k
        cldev->clist_color_info.max_color = pdev->color_info.max_color;
7549
3.87k
        cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7550
3.87k
        memcpy(&(cldev->clist_color_info.comp_bits),&(group_color->comp_bits),
7551
3.87k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7552
3.87k
        memcpy(&(cldev->clist_color_info.comp_shift),&(group_color->comp_shift),
7553
3.87k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7554
3.87k
        if (pdev->ctx){
7555
0
            pdev->ctx->additive = group_color->isadditive;
7556
0
        }
7557
       /* The device profile must be restored. */
7558
3.87k
        if (group_color->icc_profile != NULL) {
7559
1.37k
            gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7560
1.37k
                                    -1, "pdf14_clist_pop_color_model");
7561
1.37k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
7562
1.37k
        }
7563
3.87k
        if_debug0m('v', dev->memory, "[v]procs updated\n");
7564
3.87k
    }
7565
3.87k
   pdf14_pop_group_color(dev, pgs);
7566
3.87k
    return 0;
7567
3.87k
}
7568
7569
/* When a transparency group is popped, the parent colorprocs must be restored.
7570
   Since the color mapping procs are all based upon the device, we must have a
7571
   nested list based upon the transparency group color space.  This nesting
7572
   must be outside the nested ctx structures to allow the nesting for the
7573
   clist writer */
7574
static void
7575
pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs)
7576
3.89k
{
7577
3.89k
    pdf14_device *pdev = (pdf14_device *)dev;
7578
3.89k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7579
7580
3.89k
    if_debug0m('v', dev->memory, "[v]pdf14_pop_group_color\n");
7581
7582
    /* Update the link */
7583
3.89k
    pdev->color_model_stack = group_color->previous;
7584
7585
    /* Free the old one */
7586
3.89k
    gs_free_object(dev->memory->stable_memory, group_color, "pdf14_clr_free");
7587
3.89k
}
7588
7589
static  int
7590
pdf14_begin_transparency_mask(gx_device *dev,
7591
                              const gx_transparency_mask_params_t *ptmp,
7592
                              const gs_rect *pbbox,
7593
                              gs_gstate *pgs, gs_memory_t *mem)
7594
287k
{
7595
287k
    pdf14_device *pdev = (pdf14_device *)dev;
7596
287k
    uint16_t bg_alpha = 0;   /* By default the background alpha (area outside mask) is zero */
7597
287k
    byte *transfer_fn;
7598
287k
    gs_int_rect rect;
7599
287k
    int code;
7600
287k
    int group_color_numcomps;
7601
287k
    gs_transparency_color_t group_color_type;
7602
287k
    bool deep = device_is_deep(dev);
7603
287k
    pdf14_group_color_t* group_color_info;
7604
7605
287k
    code = pdf14_initialize_ctx(dev, dev->color_info.num_components,
7606
287k
        dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, (const gs_gstate*)pgs);
7607
287k
    if (code < 0)
7608
0
        return code;
7609
7610
287k
    if (ptmp->subtype == TRANSPARENCY_MASK_None) {
7611
264k
        pdf14_ctx *ctx = pdev->ctx;
7612
7613
        /* free up any maskbuf on the current tos */
7614
264k
        if (ctx->mask_stack) {
7615
25.6k
            if (ctx->mask_stack->rc_mask->mask_buf != NULL ) {
7616
13.8k
                pdf14_buf_free(ctx->mask_stack->rc_mask->mask_buf);
7617
13.8k
                ctx->mask_stack->rc_mask->mask_buf = NULL;
7618
13.8k
            }
7619
25.6k
        }
7620
264k
        return 0;
7621
264k
    }
7622
22.9k
    transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, (256+deep)<<deep,
7623
22.9k
                                         "pdf14_begin_transparency_mask");
7624
22.9k
    if (transfer_fn == NULL)
7625
0
        return_error(gs_error_VMerror);
7626
22.9k
    code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7627
22.9k
    if (code < 0)
7628
0
        return code;
7629
    /* If we have background components the background alpha may be nonzero */
7630
22.9k
    if (ptmp->Background_components)
7631
9.09k
        bg_alpha = (int)(65535 * ptmp->GrayBackground + 0.5);
7632
22.9k
    if_debug1m('v', dev->memory,
7633
22.9k
               "pdf14_begin_transparency_mask, bg_alpha = %d\n", bg_alpha);
7634
22.9k
    memcpy(transfer_fn, ptmp->transfer_fn, (256+deep)<<deep);
7635
   /* If the group color is unknown, then we must use the previous group color
7636
       space or the device process color space */
7637
22.9k
    if (ptmp->group_color_type == UNKNOWN){
7638
0
        if (pdev->ctx->stack){
7639
            /* Use previous group color space */
7640
0
            group_color_numcomps = pdev->ctx->stack->n_chan-1;  /* Remove alpha */
7641
0
        } else {
7642
            /* Use process color space */
7643
0
            group_color_numcomps = pdev->color_info.num_components;
7644
0
        }
7645
0
        switch (group_color_numcomps) {
7646
0
            case 1:
7647
0
                group_color_type = GRAY_SCALE;
7648
0
                break;
7649
0
            case 3:
7650
0
                group_color_type = DEVICE_RGB;
7651
0
                break;
7652
0
            case 4:
7653
0
                group_color_type = DEVICE_CMYK;
7654
0
            break;
7655
0
            default:
7656
                /* We can end up here if we are in a deviceN color space and
7657
                   we have a sep output device */
7658
0
                group_color_type = DEVICEN;
7659
0
            break;
7660
0
         }
7661
22.9k
    } else {
7662
22.9k
        group_color_type = ptmp->group_color_type;
7663
22.9k
        group_color_numcomps = ptmp->group_color_numcomps;
7664
22.9k
    }
7665
7666
22.9k
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptmp->icc_hashcode,
7667
22.9k
                                               ptmp->iccprofile, true);
7668
22.9k
    if (group_color_info == NULL)
7669
0
        return gs_error_VMerror;
7670
7671
    /* Note that the soft mask always follows the group color requirements even
7672
       when we have a separable device */
7673
22.9k
    code = pdf14_push_transparency_mask(pdev->ctx, &rect, bg_alpha,
7674
22.9k
                                        transfer_fn, ptmp->function_is_identity,
7675
22.9k
                                        ptmp->idle, ptmp->replacing,
7676
22.9k
                                        ptmp->mask_id, ptmp->subtype,
7677
22.9k
                                        group_color_numcomps,
7678
22.9k
                                        ptmp->Background_components,
7679
22.9k
                                        ptmp->Background,
7680
22.9k
                                        ptmp->Matte_components,
7681
22.9k
                                        ptmp->Matte,
7682
22.9k
                                        ptmp->GrayBackground,
7683
22.9k
                                        group_color_info);
7684
22.9k
    if (code < 0)
7685
0
        return code;
7686
7687
22.9k
    return 0;
7688
22.9k
}
7689
7690
static  int
7691
pdf14_end_transparency_mask(gx_device *dev, gs_gstate *pgs)
7692
22.9k
{
7693
22.9k
    pdf14_device *pdev = (pdf14_device *)dev;
7694
22.9k
    pdf14_group_color_t *group_color;
7695
22.9k
    int ok;
7696
7697
22.9k
    if_debug0m('v', dev->memory, "pdf14_end_transparency_mask\n");
7698
22.9k
    ok = pdf14_pop_transparency_mask(pdev->ctx, pgs, dev);
7699
#ifdef DEBUG
7700
    pdf14_debug_mask_stack_state(pdev->ctx);
7701
#endif
7702
7703
    /* May need to reset some color stuff related
7704
     * to a mismatch between the Smask color space
7705
     * and the Smask blending space */
7706
22.9k
    if (pdev->ctx->stack != NULL ) {
7707
22.9k
        group_color = pdev->ctx->stack->group_color_info;
7708
22.9k
        if (!(group_color->group_color_mapping_procs == NULL &&
7709
22.9k
            group_color->group_color_comp_index == NULL)) {
7710
22.9k
            pgs->get_cmap_procs = group_color->get_cmap_procs;
7711
22.9k
            gx_set_cmap_procs(pgs, dev);
7712
22.9k
            set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7713
22.9k
            set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7714
22.9k
            pdev->color_info.polarity = group_color->polarity;
7715
22.9k
            pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7716
22.9k
            pdev->color_info.num_components = group_color->num_components;
7717
22.9k
            pdev->color_info.depth = group_color->depth;
7718
22.9k
            pdev->blend_procs = group_color->blend_procs;
7719
22.9k
            pdev->ctx->additive = group_color->isadditive;
7720
22.9k
            pdev->pdf14_procs = group_color->unpack_procs;
7721
22.9k
            pdev->color_info.max_color = group_color->max_color;
7722
22.9k
            pdev->color_info.max_gray = group_color->max_gray;
7723
22.9k
            set_dev_proc(pdev, encode_color, group_color->encode);
7724
22.9k
            set_dev_proc(pdev, decode_color, group_color->decode);
7725
22.9k
            memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
7726
22.9k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
7727
22.9k
            memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
7728
22.9k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
7729
            /* Take care of the ICC profile */
7730
22.9k
            if (group_color->icc_profile != NULL) {
7731
22.9k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7732
22.9k
                                        -1, "pdf14_end_transparency_mask");
7733
22.9k
                dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
7734
22.9k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7735
22.9k
                                         1, "pdf14_end_transparency_mask");
7736
22.9k
            }
7737
22.9k
        }
7738
22.9k
    }
7739
22.9k
    return ok;
7740
22.9k
}
7741
7742
static  int
7743
do_mark_fill_rectangle_ko_simple(gx_device *dev, int x, int y, int w, int h,
7744
                                 gx_color_index color,
7745
                                 const gx_device_color *pdc, bool devn)
7746
204k
{
7747
204k
    pdf14_device *pdev = (pdf14_device *)dev;
7748
204k
    pdf14_buf *buf = pdev->ctx->stack;
7749
204k
    gs_blend_mode_t blend_mode = pdev->blend_mode;
7750
204k
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
7751
204k
        blend_mode == BLEND_MODE_Compatible ||
7752
204k
        blend_mode == BLEND_MODE_CompatibleOverprint;
7753
204k
    int i, j, k;
7754
204k
    byte *bline, *bg_ptr, *line, *dst_ptr;
7755
204k
    byte src[PDF14_MAX_PLANES];
7756
204k
    byte dst[PDF14_MAX_PLANES] = { 0 };
7757
204k
    byte dst2[PDF14_MAX_PLANES] = { 0 };
7758
204k
    int rowstride = buf->rowstride;
7759
204k
    int planestride = buf->planestride;
7760
204k
    int num_chan = buf->n_chan;
7761
204k
    int num_comp = num_chan - 1;
7762
204k
    int shape_off = num_chan * planestride;
7763
204k
    bool has_shape = buf->has_shape;
7764
204k
    bool has_alpha_g = buf->has_alpha_g;
7765
204k
    int alpha_g_off = shape_off + (has_shape ? planestride : 0);
7766
204k
    int tag_off = shape_off + (has_alpha_g ? planestride : 0) +
7767
204k
                              (has_shape ? planestride : 0);
7768
204k
    bool has_tags = buf->has_tags;
7769
204k
    bool additive = pdev->ctx->additive;
7770
204k
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
7771
204k
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
7772
204k
    int shift = 8;
7773
204k
    byte shape = 0; /* Quiet compiler. */
7774
204k
    byte src_alpha;
7775
204k
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
7776
204k
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
7777
161k
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
7778
204k
    gx_color_index comps;
7779
204k
    bool has_backdrop = buf->backdrop != NULL;
7780
7781
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
7782
       subtractive) and we are doing overprint with drawn_comps == 0
7783
       then this is a no-operation */
7784
204k
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
7785
0
        return 0;
7786
7787
204k
    if (buf->data == NULL)
7788
0
        return 0;
7789
#if 0
7790
    if (sizeof(color) <= sizeof(ulong))
7791
        if_debug6m('v', dev->memory,
7792
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %lx, nc %d,\n",
7793
                   x, y, w, h, (ulong)color, num_chan);
7794
    else
7795
        if_debug7m('v', dev->memory,
7796
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
7797
                   x, y, w, h,
7798
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
7799
                   num_chan);
7800
#endif
7801
    /*
7802
     * Unpack the gx_color_index values.  Complement the components for subtractive
7803
     * color spaces.
7804
     */
7805
204k
    if (devn) {
7806
0
        if (has_tags) {
7807
0
            curr_tag = pdc->tag;
7808
0
        }
7809
0
        if (additive) {
7810
0
            for (j = 0; j < num_comp; j++) {
7811
0
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
7812
0
            }
7813
0
        } else {
7814
0
            for (j = 0; j < num_comp; j++) {
7815
0
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
7816
0
            }
7817
0
        }
7818
204k
    } else {
7819
204k
        if (has_tags) {
7820
0
            curr_tag = (color >> (num_comp * 8)) & 0xff;
7821
0
        }
7822
204k
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
7823
204k
    }
7824
7825
204k
    if (!has_tags)
7826
204k
        tag_off = 0;
7827
7828
204k
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
7829
204k
    if (has_shape) {
7830
0
        shape = (byte)floor (255 * pdev->shape + 0.5);
7831
204k
    } else {
7832
204k
        shape_off = 0;
7833
204k
    }
7834
7835
204k
    if (!has_alpha_g)
7836
0
        alpha_g_off = 0;
7837
204k
    src_alpha = 255 - src_alpha;
7838
204k
    shape = 255 - shape;
7839
7840
    /* Fit the mark into the bounds of the buffer */
7841
204k
    if (x < buf->rect.p.x) {
7842
0
        w += x - buf->rect.p.x;
7843
0
        x = buf->rect.p.x;
7844
0
    }
7845
204k
    if (y < buf->rect.p.y) {
7846
0
      h += y - buf->rect.p.y;
7847
0
      y = buf->rect.p.y;
7848
0
    }
7849
204k
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
7850
204k
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
7851
    /* Update the dirty rectangle with the mark. */
7852
204k
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
7853
204k
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
7854
204k
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
7855
204k
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
7856
7857
    /* composite with backdrop only. */
7858
204k
    if (has_backdrop)
7859
204k
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
7860
0
    else
7861
0
        bline = NULL;
7862
7863
204k
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
7864
7865
452k
    for (j = 0; j < h; ++j) {
7866
247k
        bg_ptr = bline;
7867
247k
        dst_ptr = line;
7868
1.59M
        for (i = 0; i < w; ++i) {
7869
            /* Complement the components for subtractive color spaces */
7870
1.34M
            if (has_backdrop) {
7871
1.34M
                if (additive) {
7872
6.73M
                    for (k = 0; k < num_chan; ++k)
7873
5.39M
                        dst[k] = bg_ptr[k * planestride];
7874
1.34M
                } else {
7875
0
                    for (k = 0; k < num_comp; ++k)
7876
0
                        dst2[k] = dst[k] = 255 - bg_ptr[k * planestride];
7877
0
                }
7878
1.34M
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
7879
1.34M
            }
7880
1.34M
            if (buf->isolated || !has_backdrop) {
7881
0
                art_pdf_knockoutisolated_group_8(dst, src, num_comp);
7882
1.34M
            } else {
7883
1.34M
                art_pdf_composite_knockout_8(dst, src, num_comp,
7884
1.34M
                                            blend_mode, pdev->blend_procs, pdev);
7885
1.34M
            }
7886
            /* Complement the results for subtractive color spaces */
7887
1.34M
            if (additive) {
7888
1.34M
                if (!overprint) {
7889
6.73M
                    for (k = 0; k < num_chan; ++k)
7890
5.39M
                        dst_ptr[k * planestride] = dst[k];
7891
1.34M
                } else {
7892
                    /* Hybrid additive with subtractive spots */
7893
                    /* We may have to do the compatible overprint blending */
7894
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
7895
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
7896
0
                            blend_mode, pdev->blend_procs, pdev);
7897
0
                    }
7898
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
7899
0
                        if ((comps & 0x1) != 0) {
7900
0
                            dst_ptr[k * planestride] = dst[k];
7901
0
                        } else {
7902
                            /* Compatible overprint blend result. */
7903
0
                            dst_ptr[k * planestride] = dst2[k];
7904
0
                        }
7905
0
                    }
7906
0
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
7907
0
                }
7908
1.34M
            } else {
7909
0
                if (overprint) {
7910
                    /* We may have to do the compatible overprint blending */
7911
0
                    if (!buf->isolated && drawn_comps != (( (size_t) 1 << (size_t) dev->color_info.num_components)-(size_t) 1)) {
7912
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
7913
0
                            blend_mode, pdev->blend_procs, pdev);
7914
0
                    }
7915
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
7916
0
                        if ((comps & 0x1) != 0) {
7917
0
                            dst_ptr[k * planestride] = 255 - dst[k];
7918
0
                        } else {
7919
                            /* Compatible overprint blend result. */
7920
0
                            dst_ptr[k * planestride] = 255 - dst2[k];
7921
0
                        }
7922
0
                    }
7923
0
                } else {
7924
0
                    for (k = 0; k < num_comp; ++k)
7925
0
                        dst_ptr[k * planestride] = 255 - dst[k];
7926
0
                }
7927
0
                dst_ptr[num_comp * planestride] = dst[num_comp];
7928
0
            }
7929
1.34M
            if (tag_off) {
7930
                /* If src alpha is 100% then set to curr_tag, else or */
7931
                /* other than Normal BM, we always OR */
7932
0
                if (src[num_comp] == 255 && tag_blend) {
7933
0
                    dst_ptr[tag_off] = curr_tag;
7934
0
                } else {
7935
0
                    dst_ptr[tag_off] |= curr_tag;
7936
0
                }
7937
0
            }
7938
            /* Knockout group alpha and shape too */
7939
1.34M
            if (alpha_g_off)
7940
1.34M
                dst_ptr[alpha_g_off] = 255 - src_alpha;
7941
1.34M
            if (shape_off)
7942
0
                dst_ptr[shape_off] = 255 - shape;
7943
1.34M
            ++dst_ptr;
7944
1.34M
            if (has_backdrop)
7945
1.34M
                ++bg_ptr;
7946
1.34M
        }
7947
247k
        bline += rowstride;
7948
247k
        line += rowstride;
7949
247k
    }
7950
#if 0
7951
/* #if RAW_DUMP */
7952
    /* Dump the current buffer to see what we have. */
7953
    dump_raw_buffer(pdev->ctx->memory,
7954
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
7955
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
7956
                    pdev->ctx->stack->n_planes,
7957
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
7958
                    "Draw_Rect_KO", pdev->ctx->stack->data,
7959
                    pdev->ctx->stack->deep);
7960
    global_index++;
7961
#endif
7962
204k
    return 0;
7963
204k
}
7964
7965
static  int
7966
do_mark_fill_rectangle_ko_simple16(gx_device *dev, int x, int y, int w, int h,
7967
                                   gx_color_index color,
7968
                                   const gx_device_color *pdc, bool devn)
7969
0
{
7970
0
    pdf14_device *pdev = (pdf14_device *)dev;
7971
0
    pdf14_buf *buf = pdev->ctx->stack;
7972
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
7973
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
7974
0
        blend_mode == BLEND_MODE_Compatible ||
7975
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
7976
0
    int i, j, k;
7977
0
    uint16_t *bline, *bg_ptr, *line, *dst_ptr;
7978
0
    uint16_t src[PDF14_MAX_PLANES];
7979
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
7980
0
    uint16_t dst2[PDF14_MAX_PLANES] = { 0 };
7981
0
    int rowstride = buf->rowstride;
7982
0
    int planestride = buf->planestride;
7983
0
    int num_chan = buf->n_chan;
7984
0
    int num_comp = num_chan - 1;
7985
0
    int shape_off = num_chan * planestride;
7986
0
    bool has_shape = buf->has_shape;
7987
0
    bool has_alpha_g = buf->has_alpha_g;
7988
0
    int alpha_g_off = shape_off + (has_shape ? planestride : 0);
7989
0
    int tag_off = shape_off + (has_alpha_g ? planestride : 0) +
7990
0
                              (has_shape ? planestride : 0);
7991
0
    bool has_tags = buf->has_tags;
7992
0
    bool additive = pdev->ctx->additive;
7993
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
7994
0
    uint16_t shape = 0; /* Quiet compiler. */
7995
0
    uint16_t src_alpha;
7996
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
7997
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
7998
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
7999
0
    gx_color_index comps;
8000
0
    bool has_backdrop = buf->backdrop != NULL;
8001
8002
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8003
       subtractive) and we are doing overprint with drawn_comps == 0
8004
       then this is a no-operation */
8005
0
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8006
0
        return 0;
8007
8008
0
    if (buf->data == NULL)
8009
0
        return 0;
8010
#if 0
8011
    if (sizeof(color) <= sizeof(ulong))
8012
        if_debug6m('v', dev->memory,
8013
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %lx, nc %d,\n",
8014
                   x, y, w, h, (ulong)color, num_chan);
8015
    else
8016
        if_debug7m('v', dev->memory,
8017
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8018
                   x, y, w, h,
8019
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8020
                   num_chan);
8021
#endif
8022
    /*
8023
     * Unpack the gx_color_index values.  Complement the components for subtractive
8024
     * color spaces.
8025
     */
8026
0
    if (devn) {
8027
0
        if (has_tags) {
8028
0
            curr_tag = pdc->tag;
8029
0
        }
8030
0
        if (additive) {
8031
0
            for (j = 0; j < num_comp; j++) {
8032
0
                src[j] = pdc->colors.devn.values[j];
8033
0
            }
8034
0
        } else {
8035
0
            for (j = 0; j < num_comp; j++) {
8036
0
                src[j] = 65535 - pdc->colors.devn.values[j];
8037
0
            }
8038
0
        }
8039
0
    } else {
8040
0
        if (has_tags) {
8041
0
            curr_tag = (color >> (num_comp * 16)) & 0xff;
8042
0
        }
8043
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
8044
0
    }
8045
8046
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
8047
0
    if (has_shape) {
8048
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
8049
0
    } else {
8050
0
        shape_off = 0;
8051
0
    }
8052
8053
0
    if (!has_tags) {
8054
0
        tag_off = 0;
8055
0
    }
8056
8057
0
    if (!has_alpha_g)
8058
0
        alpha_g_off = 0;
8059
0
    src_alpha = 65535 - src_alpha;
8060
0
    shape = 65535 - shape;
8061
8062
    /* Fit the mark into the bounds of the buffer */
8063
0
    if (x < buf->rect.p.x) {
8064
0
        w += x - buf->rect.p.x;
8065
0
        x = buf->rect.p.x;
8066
0
    }
8067
0
    if (y < buf->rect.p.y) {
8068
0
      h += y - buf->rect.p.y;
8069
0
      y = buf->rect.p.y;
8070
0
    }
8071
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8072
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8073
    /* Update the dirty rectangle with the mark. */
8074
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8075
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8076
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8077
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8078
8079
8080
    /* composite with backdrop only. */
8081
0
    if (has_backdrop)
8082
0
        bline = (uint16_t*)(void*)(buf->backdrop + (x - buf->rect.p.x) * 2 + (y - buf->rect.p.y) * rowstride);
8083
0
    else
8084
0
        bline = NULL;
8085
8086
0
    line = (uint16_t *)(void *)(buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride);
8087
0
    planestride >>= 1;
8088
0
    rowstride >>= 1;
8089
0
    alpha_g_off >>= 1;
8090
0
    shape_off >>= 1;
8091
0
    tag_off >>= 1;
8092
8093
0
    for (j = 0; j < h; ++j) {
8094
0
        bg_ptr = bline;
8095
0
        dst_ptr = line;
8096
0
        for (i = 0; i < w; ++i) {
8097
            /* Complement the components for subtractive color spaces */
8098
0
            if (has_backdrop) {
8099
0
                if (additive) {
8100
0
                    for (k = 0; k < num_chan; ++k)
8101
0
                        dst[k] = bg_ptr[k * planestride];
8102
0
                } else {
8103
0
                    for (k = 0; k < num_comp; ++k)
8104
0
                        dst2[k] = dst[k] = 65535 - bg_ptr[k * planestride];
8105
0
                }
8106
0
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8107
0
            }
8108
0
            if (buf->isolated || !has_backdrop) {
8109
0
                art_pdf_knockoutisolated_group_16(dst, src, num_comp);
8110
0
            } else {
8111
0
                art_pdf_composite_knockout_16(dst, src, num_comp,
8112
0
                                              blend_mode, pdev->blend_procs, pdev);
8113
0
            }
8114
            /* Complement the results for subtractive color spaces */
8115
0
            if (additive) {
8116
0
                if (!overprint) {
8117
0
                    for (k = 0; k < num_chan; ++k)
8118
0
                        dst_ptr[k * planestride] = dst[k];
8119
0
                } else {
8120
                    /* Hybrid additive with subtractive spots */
8121
                    /* We may have to do the compatible overprint blending */
8122
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8123
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8124
0
                            blend_mode, pdev->blend_procs, pdev);
8125
0
                    }
8126
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8127
0
                        if ((comps & 0x1) != 0) {
8128
0
                            dst_ptr[k * planestride] = dst[k];
8129
0
                        } else {
8130
                            /* Compatible overprint blend result. */
8131
0
                            dst_ptr[k * planestride] = dst2[k];
8132
0
                        }
8133
0
                    }
8134
0
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8135
0
                }
8136
0
            } else {
8137
0
                if (overprint) {
8138
                    /* We may have to do the compatible overprint blending */
8139
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8140
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8141
0
                            blend_mode, pdev->blend_procs, pdev);
8142
0
                    }
8143
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8144
0
                        if ((comps & 0x1) != 0) {
8145
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
8146
0
                        } else {
8147
                            /* Compatible overprint blend result. */
8148
0
                            dst_ptr[k * planestride] = 65535 - dst2[k];
8149
0
                        }
8150
0
                    }
8151
0
                } else {
8152
0
                    for (k = 0; k < num_comp; ++k)
8153
0
                        dst_ptr[k * planestride] = 65535 - dst[k];
8154
0
                }
8155
0
                dst_ptr[num_comp * planestride] = dst[num_comp];
8156
0
            }
8157
0
            if (tag_off) {
8158
                /* FIXME: As we are knocking out, possibly, we should be
8159
                 * always overwriting tag values here? */
8160
                /* If src alpha is 100% then set to curr_tag, else or */
8161
                /* other than Normal BM, we always OR */
8162
0
                if (src[num_comp] == 65535 && tag_blend) {
8163
0
                    dst_ptr[tag_off] = curr_tag;
8164
0
                } else {
8165
0
                    dst_ptr[tag_off] |= curr_tag;
8166
0
                }
8167
0
            }
8168
            /* Knockout group alpha and shape too */
8169
0
            if (alpha_g_off)
8170
0
                dst_ptr[alpha_g_off] = 65535 - src_alpha;
8171
0
            if (shape_off)
8172
0
                dst_ptr[shape_off] = 65535 - shape;
8173
0
            ++dst_ptr;
8174
0
            if (has_backdrop)
8175
0
                ++bg_ptr;
8176
0
        }
8177
0
        bline += rowstride;
8178
0
        line += rowstride;
8179
0
    }
8180
#if 0
8181
/* #if RAW_DUMP */
8182
    /* Dump the current buffer to see what we have. */
8183
    dump_raw_buffer(pdev->ctx->memory,
8184
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8185
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8186
                    pdev->ctx->stack->n_planes,
8187
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8188
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8189
                    pdev->ctx->stack->deep);
8190
    global_index++;
8191
#endif
8192
0
    return 0;
8193
0
}
8194
8195
static  int
8196
pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, int w, int h,
8197
                                    gx_color_index color,
8198
                                    const gx_device_color *pdc, bool devn)
8199
204k
{
8200
204k
    pdf14_device *pdev = (pdf14_device *)dev;
8201
204k
    pdf14_buf *buf = pdev->ctx->stack;
8202
8203
204k
    if (buf->deep)
8204
0
        return do_mark_fill_rectangle_ko_simple16(dev, x, y, w, h, color, pdc, devn);
8205
204k
    else
8206
204k
        return do_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, pdc, devn);
8207
204k
}
8208
8209
/**
8210
 * Here we have logic to override the cmap_procs with versions that
8211
 * do not apply the transfer function. These copies should track the
8212
 * versions in gxcmap.c.
8213
 **/
8214
static  cmap_proc_gray(pdf14_cmap_gray_direct);
8215
static  cmap_proc_rgb(pdf14_cmap_rgb_direct);
8216
static  cmap_proc_cmyk(pdf14_cmap_cmyk_direct);
8217
static  cmap_proc_separation(pdf14_cmap_separation_direct);
8218
static  cmap_proc_devicen(pdf14_cmap_devicen_direct);
8219
static  cmap_proc_is_halftoned(pdf14_cmap_is_halftoned);
8220
8221
static  const gx_color_map_procs pdf14_cmap_many = {
8222
     pdf14_cmap_gray_direct,
8223
     pdf14_cmap_rgb_direct,
8224
     pdf14_cmap_cmyk_direct,
8225
     pdf14_cmap_separation_direct,
8226
     pdf14_cmap_devicen_direct,
8227
     pdf14_cmap_is_halftoned
8228
    };
8229
8230
/**
8231
 * Note: copied from gxcmap.c because it's inlined.
8232
 **/
8233
static  inline void
8234
map_components_to_colorants(const frac * pcc,
8235
                            const gs_devicen_color_map * pcolor_component_map,
8236
                            frac * plist)
8237
215k
{
8238
215k
    int i = pcolor_component_map->num_colorants - 1;
8239
215k
    int pos;
8240
8241
    /* Clear all output colorants first */
8242
1.07M
    for (; i >= 0; i--) {
8243
861k
        plist[i] = frac_0;
8244
861k
    }
8245
    /* Map color components into output list */
8246
435k
    for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
8247
220k
        pos = pcolor_component_map->color_map[i];
8248
220k
        if (pos >= 0)
8249
220k
            plist[pos] = pcc[i];
8250
220k
    }
8251
215k
}
8252
8253
/* See Section 7.6.4 of PDF 1.7 spec */
8254
static inline bool
8255
pdf14_state_opaque(gx_device *pdev, const gs_gstate *pgs)
8256
2.40M
{
8257
2.40M
    if (pgs->fillconstantalpha != 1.0 ||
8258
2.40M
        pgs->strokeconstantalpha != 1.0 ||
8259
2.40M
        !(pgs->blend_mode == BLEND_MODE_Normal ||
8260
2.40M
          pgs->blend_mode == BLEND_MODE_CompatibleOverprint))
8261
1.90k
        return 0;
8262
8263
    /* We can only be opaque if we're not in an SMask. */
8264
2.40M
    return dev_proc(pdev, dev_spec_op)(pdev,
8265
2.40M
                                       gxdso_in_smask,
8266
2.40M
                                       NULL, 0) != 1;
8267
2.40M
}
8268
8269
static  void
8270
pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs,
8271
                       gx_device * dev, gs_color_select_t select)
8272
418k
{
8273
418k
    int i,ncomps;
8274
418k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8275
418k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8276
418k
    gx_color_index color;
8277
418k
    gx_device *trans_device;
8278
418k
    const gx_device *map_dev;
8279
418k
    const gx_cm_color_map_procs *procs;
8280
8281
    /* If trans device is set, we need to use its procs. */
8282
418k
    if (pgs->trans_device != NULL) {
8283
14.2k
        trans_device = pgs->trans_device;
8284
404k
    } else {
8285
404k
        trans_device = dev;
8286
404k
    }
8287
418k
    ncomps = trans_device->color_info.num_components;
8288
8289
    /* map to the color model */
8290
418k
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8291
418k
    procs->map_gray(map_dev, gray, cm_comps);
8292
8293
418k
    if (pdf14_state_opaque(trans_device, pgs)) {
8294
0
        for (i = 0; i < ncomps; i++)
8295
0
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8296
418k
    } else {
8297
837k
        for (i = 0; i < ncomps; i++)
8298
418k
            cv[i] = frac2cv(cm_comps[i]);
8299
418k
    }
8300
8301
    /* If output device supports devn, we need to make sure we send it the
8302
       proper color type.  We now support Gray + spots as devn colors */
8303
418k
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8304
0
        for (i = 0; i < ncomps; i++)
8305
0
            pdc->colors.devn.values[i] = cv[i];
8306
0
        pdc->type = gx_dc_type_devn;
8307
418k
    } else {
8308
        /* encode as a color index */
8309
418k
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8310
        /* check if the encoding was successful; we presume failure is rare */
8311
418k
        if (color != gx_no_color_index)
8312
418k
            color_set_pure(pdc, color);
8313
418k
    }
8314
418k
}
8315
8316
static  void
8317
pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
8318
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
8319
358k
{
8320
358k
    int i,ncomps;
8321
358k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8322
358k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8323
358k
    gx_color_index color;
8324
358k
    gx_device *trans_device;
8325
358k
    const gx_device *map_dev;
8326
358k
    const gx_cm_color_map_procs *procs;
8327
8328
    /* If trans device is set, we need to use its procs. */
8329
358k
    if (pgs->trans_device != NULL){
8330
221k
        trans_device = pgs->trans_device;
8331
221k
    } else {
8332
136k
        trans_device = dev;
8333
136k
    }
8334
358k
    ncomps = trans_device->color_info.num_components;
8335
    /* map to the color model */
8336
358k
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8337
358k
    procs->map_rgb(map_dev, pgs, r, g, b, cm_comps);
8338
8339
358k
    if (pdf14_state_opaque(trans_device, pgs)) {
8340
1.39M
        for (i = 0; i < ncomps; i++)
8341
1.04M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8342
348k
    } else {
8343
36.6k
        for (i = 0; i < ncomps; i++)
8344
27.1k
            cv[i] = frac2cv(cm_comps[i]);
8345
9.55k
    }
8346
8347
    /* If output device supports devn, we need to make sure we send it the
8348
       proper color type.  We now support RGB + spots as devn colors */
8349
358k
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8350
0
        for (i = 0; i < ncomps; i++)
8351
0
            pdc->colors.devn.values[i] = cv[i];
8352
0
        pdc->type = gx_dc_type_devn;
8353
358k
    } else {
8354
        /* encode as a color index */
8355
358k
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8356
        /* check if the encoding was successful; we presume failure is rare */
8357
358k
        if (color != gx_no_color_index)
8358
358k
            color_set_pure(pdc, color);
8359
358k
    }
8360
358k
}
8361
8362
static  void
8363
pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc,
8364
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select,
8365
     const gs_color_space *pcs)
8366
1.63M
{
8367
1.63M
    int i, ncomps;
8368
1.63M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8369
1.63M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8370
1.63M
    gx_color_index color;
8371
1.63M
    gx_device *trans_device;
8372
1.63M
    const gx_device *map_dev;
8373
1.63M
    const gx_cm_color_map_procs *procs;
8374
8375
8376
    /* If trans device is set, we need to use its procs. */
8377
1.63M
    if (pgs->trans_device != NULL){
8378
1.62M
        trans_device = pgs->trans_device;
8379
1.62M
    } else {
8380
5.96k
        trans_device = dev;
8381
5.96k
    }
8382
1.63M
    ncomps = trans_device->color_info.num_components;
8383
8384
    /* Map to the color model. Transfer function is only used
8385
       if we are drawing with an opaque color. */
8386
1.63M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8387
1.63M
    procs->map_cmyk(map_dev, c, m, y, k, cm_comps);
8388
8389
1.63M
    if (pdf14_state_opaque(trans_device, pgs)) {
8390
8.13M
        for (i = 0; i < ncomps; i++)
8391
6.50M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8392
1.62M
    } else {
8393
19.5k
        for (i = 0; i < ncomps; i++)
8394
15.6k
            cv[i] = frac2cv(cm_comps[i]);
8395
3.90k
    }
8396
8397
    /* if output device supports devn, we need to make sure we send it the
8398
       proper color type */
8399
1.63M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8400
0
        for (i = 0; i < ncomps; i++)
8401
0
            pdc->colors.devn.values[i] = cv[i];
8402
0
        pdc->type = gx_dc_type_devn;
8403
1.63M
    } else {
8404
        /* encode as a color index */
8405
1.63M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8406
        /* check if the encoding was successful; we presume failure is rare */
8407
1.63M
        if (color != gx_no_color_index)
8408
1.63M
            color_set_pure(pdc, color);
8409
1.63M
    }
8410
1.63M
}
8411
8412
static int
8413
pdf14_get_num_spots(gx_device * dev)
8414
215k
{
8415
215k
    cmm_dev_profile_t *dev_profile;
8416
215k
    cmm_profile_t *icc_profile;
8417
215k
    gsicc_rendering_param_t render_cond;
8418
8419
215k
    dev_proc(dev, get_profile)(dev, &dev_profile);
8420
215k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
8421
215k
        &render_cond);
8422
215k
    return dev->color_info.num_components - icc_profile->num_comps;
8423
215k
}
8424
8425
static  void
8426
pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs,
8427
                 gx_device * dev, gs_color_select_t select, const gs_color_space *pcs)
8428
0
{
8429
0
    int i, ncomps = dev->color_info.num_components;
8430
0
    int num_spots = pdf14_get_num_spots(dev);
8431
0
    bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
8432
0
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8433
0
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8434
0
    gx_color_index color;
8435
8436
0
    if (pgs->color_component_map.sep_type == SEP_ALL) {
8437
0
        frac comp_value = all;
8438
8439
        /*
8440
         * Invert the photometric interpretation for additive
8441
         * color spaces because separations are always subtractive.
8442
         */
8443
0
        if (additive)
8444
0
            comp_value = frac_1 - comp_value;
8445
        /* Use the "all" value for all components */
8446
0
        i = pgs->color_component_map.num_colorants - 1;
8447
0
        for (; i >= 0; i--)
8448
0
            cm_comps[i] = comp_value;
8449
0
    } else {
8450
0
        frac comp_value[GX_DEVICE_COLOR_MAX_COMPONENTS];
8451
8452
        /* map to the color model */
8453
0
        for (i = pgs->color_component_map.num_components - 1; i >= 0; i--)
8454
0
            comp_value[i] = all;
8455
0
        map_components_to_colorants(comp_value, &(pgs->color_component_map), cm_comps);
8456
0
    }
8457
    /* apply the transfer function(s); convert to color values */
8458
0
    if (additive) {
8459
0
        for (i = 0; i < ncomps; i++)
8460
0
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8461
        /* We are in an additive mode (blend space) and drawing with a sep color
8462
        into a sep device.  Make sure we are drawing "white" with the process
8463
        colorants, but only if we are not in an ALL case */
8464
0
        if (pgs->color_component_map.sep_type != SEP_ALL)
8465
0
            for (i = 0; i < ncomps - num_spots; i++)
8466
0
                cv[i] = gx_max_color_value;
8467
0
    } else
8468
0
        for (i = 0; i < ncomps; i++)
8469
0
            cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8470
8471
8472
    /* if output device supports devn, we need to make sure we send it the
8473
       proper color type */
8474
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)) {
8475
0
        for (i = 0; i < ncomps; i++)
8476
0
            pdc->colors.devn.values[i] = cv[i];
8477
0
        pdc->type = gx_dc_type_devn;
8478
0
    } else {
8479
        /* encode as a color index */
8480
0
        color = dev_proc(dev, encode_color)(dev, cv);
8481
        /* check if the encoding was successful; we presume failure is rare */
8482
0
        if (color != gx_no_color_index)
8483
0
            color_set_pure(pdc, color);
8484
0
    }
8485
0
}
8486
8487
static  void
8488
pdf14_cmap_devicen_direct(const frac * pcc,
8489
    gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
8490
    gs_color_select_t select, const gs_color_space *pcs)
8491
215k
{
8492
215k
    int i, ncomps = dev->color_info.num_components;
8493
215k
    int num_spots = pdf14_get_num_spots(dev);
8494
215k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8495
215k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8496
215k
    gx_color_index color;
8497
215k
    gx_device *trans_device;
8498
8499
     /*  We may be coming from the clist writer which often forwards us the
8500
         target device. If this occurs we actually need to get to the color
8501
         space defined by the transparency group and we use the operators
8502
         defined by the transparency device to do the job.
8503
       */
8504
215k
    if (pgs->trans_device != NULL){
8505
215k
        trans_device = pgs->trans_device;
8506
215k
    } else {
8507
0
        trans_device = dev;
8508
0
    }
8509
215k
    ncomps = trans_device->color_info.num_components;
8510
    /* map to the color model */
8511
215k
    map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps);;
8512
    /* apply the transfer function(s); convert to color values */
8513
215k
    if (trans_device->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
8514
0
        for (i = 0; i < ncomps; i++)
8515
0
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8516
        /* We are in an additive mode (blend space) and drawing with a sep color
8517
        into a sep device.  Make sure we are drawing "white" with the process
8518
        colorants */
8519
0
        for (i = 0; i < ncomps - num_spots; i++)
8520
0
            cv[i] = gx_max_color_value;
8521
0
    } else
8522
1.07M
        for (i = 0; i < ncomps; i++)
8523
861k
            cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8524
    /* if output device supports devn, we need to make sure we send it the
8525
       proper color type */
8526
215k
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8527
0
        for (i = 0; i < ncomps; i++)
8528
0
            pdc->colors.devn.values[i] = cv[i];
8529
0
        pdc->type = gx_dc_type_devn;
8530
215k
    } else {
8531
    /* encode as a color index */
8532
215k
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8533
        /* check if the encoding was successful; we presume failure is rare */
8534
215k
        if (color != gx_no_color_index)
8535
215k
            color_set_pure(pdc, color);
8536
215k
    }
8537
215k
}
8538
8539
static  bool
8540
pdf14_cmap_is_halftoned(const gs_gstate * pgs, gx_device * dev)
8541
0
{
8542
0
    return false;
8543
0
}
8544
8545
static  const gx_color_map_procs *
8546
pdf14_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev)
8547
72.4k
{
8548
    /* The pdf14 marking device itself is always continuous tone. */
8549
72.4k
    return &pdf14_cmap_many;
8550
72.4k
}
8551
8552
static int
8553
pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op,
8554
                  void *data, int size)
8555
5.92M
{
8556
5.92M
    pdf14_device * p14dev = (pdf14_device *)pdev;
8557
8558
5.92M
    if (dev_spec_op == gxdso_supports_pattern_transparency)
8559
709
        return 1;
8560
5.92M
    if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path)
8561
5.95k
        return 1;
8562
5.92M
    if (dev_spec_op == gxdso_is_pdf14_device) {
8563
0
        if (data != NULL && size == sizeof(gx_device *))
8564
0
            *(gx_device **)data = pdev;
8565
0
        return 1;
8566
0
    }
8567
5.92M
    if (dev_spec_op == gxdso_device_child) {
8568
0
        pdf14_device *dev = (pdf14_device *)pdev;
8569
0
        gxdso_device_child_request *d = (gxdso_device_child_request *)data;
8570
0
        if (d->target == pdev) {
8571
0
            d->target = dev->target;
8572
0
            return 1;
8573
0
        }
8574
0
    }
8575
5.92M
    if (dev_spec_op == gxdso_supports_devn
8576
5.92M
     || dev_spec_op == gxdso_skip_icc_component_validation) {
8577
2.59M
        cmm_dev_profile_t *dev_profile;
8578
2.59M
        int code;
8579
2.59M
        code = dev_proc(pdev, get_profile)((gx_device*) pdev, &dev_profile);
8580
2.59M
        if (code == 0) {
8581
2.59M
            return dev_profile->supports_devn;
8582
2.59M
        } else {
8583
0
            return 0;
8584
0
        }
8585
2.59M
    }
8586
3.32M
    if (dev_spec_op == gxdso_pdf14_sep_device) {
8587
36
        pdf14_device* dev = (pdf14_device*)pdev;
8588
8589
36
        if (strcmp(dev->dname, "pdf14cmykspot") == 0 ||
8590
36
            strcmp(dev->dname, "pdf14clistcmykspot") == 0)
8591
0
            return 1;
8592
36
        return 0;
8593
36
    }
8594
3.32M
    if (dev_spec_op == gxdso_is_encoding_direct)
8595
154k
        return 1;
8596
8597
    /* We don't want to pass on these spec_ops either, because the child might respond
8598
     * with an inappropriate response when the PDF14 device is active. For example; the
8599
     * JPEG passthrough will give utterly wrong results if we pass that to a device which
8600
     * supports JPEG passthrough, because the pdf14 device needs to render the image.
8601
     */
8602
3.17M
    if (dev_spec_op == gxdso_in_pattern_accumulator)
8603
13.0k
        return 0;
8604
3.15M
    if (dev_spec_op == gxdso_copy_color_is_fast)
8605
98.7k
        return 0;
8606
3.06M
    if(dev_spec_op == gxdso_pattern_handles_clip_path)
8607
5.86k
        return 0;
8608
3.05M
    if(dev_spec_op == gxdso_supports_hlcolor)
8609
0
        return 0;
8610
3.05M
    if(dev_spec_op == gxdso_pattern_can_accum)
8611
716
        return 0;
8612
3.05M
    if(dev_spec_op == gxdso_JPEG_passthrough_query)
8613
69
        return 0;
8614
3.05M
    if (dev_spec_op == gxdso_overprint_active) {
8615
222k
        if (p14dev->pclist_device != NULL) {
8616
220k
            return dev_proc(p14dev->pclist_device, dev_spec_op)(p14dev->pclist_device, dev_spec_op, data, size);
8617
220k
        } else {
8618
1.28k
            return p14dev->overprint || p14dev->stroke_overprint;
8619
1.28k
        }
8620
222k
    }
8621
2.83M
    if (dev_spec_op == gxdso_in_smask_construction)
8622
211k
        return p14dev->in_smask_construction > 0;
8623
2.62M
    if (dev_spec_op == gxdso_in_smask)
8624
2.57M
        return p14dev->in_smask_construction > 0 || p14dev->depth_within_smask;
8625
43.1k
    if (dev_spec_op == gxdso_device_insert_child) {
8626
0
        gx_device *tdev = p14dev->target;
8627
0
        p14dev->target = (gx_device *)data;
8628
0
        rc_increment(p14dev->target);
8629
0
        rc_decrement_only(tdev, "pdf14_dev_spec_op");
8630
0
        return 0;
8631
0
    }
8632
43.1k
    if (dev_spec_op == gxdso_interpolate_threshold)
8633
702
        return p14dev->interpolate_threshold;
8634
8635
42.4k
    if (dev_spec_op == gxdso_overprintsim_state) {
8636
702
        unsigned char *data_uchar = (unsigned char *) data;
8637
702
        data_uchar[0] = (unsigned char) p14dev->overprint_sim;
8638
702
        if (p14dev->ctx != NULL)
8639
0
            data_uchar[1] = (unsigned char)p14dev->ctx->num_spots; /* pdf14 page device */
8640
702
        else
8641
702
            data_uchar[1] = (unsigned char)p14dev->devn_params.page_spot_colors;  /* pdf14 clist device */
8642
702
        return 1;
8643
702
    }
8644
8645
41.7k
    return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
8646
42.4k
}
8647
8648
/* Needed to set color monitoring in the target device's profile */
8649
int
8650
gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring)
8651
0
{
8652
0
    pdf14_device * p14dev = (pdf14_device *)pdev;
8653
0
    gx_device *targ = p14dev->target;
8654
0
    cmm_dev_profile_t *dev_profile;
8655
0
    int code = dev_proc(targ, get_profile)((gx_device*) targ, &dev_profile);
8656
8657
0
    if (code == 0)
8658
0
        dev_profile->pageneutralcolor = monitoring;
8659
0
    return code;
8660
0
}
8661
8662
static int
8663
gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
8664
        gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct)
8665
44.6k
{
8666
44.6k
    pdf14_device dev_proto;
8667
44.6k
    pdf14_device * p14dev;
8668
44.6k
    int code;
8669
44.6k
    bool has_tags;
8670
44.6k
    cmm_profile_t *icc_profile;
8671
44.6k
    gsicc_rendering_param_t render_cond;
8672
44.6k
    cmm_dev_profile_t *dev_profile;
8673
44.6k
    uchar k;
8674
44.6k
    int max_bitmap;
8675
44.6k
    bool use_pdf14_accum = false;
8676
44.6k
    bool deep;
8677
8678
    /* Guard against later seg faults, this should not be possible */
8679
44.6k
    if (target == NULL)
8680
0
        return gs_throw_code(gs_error_Fatal);
8681
8682
44.6k
    has_tags = device_encodes_tags(target);
8683
44.6k
    deep = device_is_deep(target);
8684
44.6k
    max_bitmap = target->space_params.MaxBitmap == 0 ? MAX_BITMAP :
8685
44.6k
                                 target->space_params.MaxBitmap;
8686
    /* If the device is not a printer class device, it won't support saved-pages */
8687
    /* and so we may need to make a clist device in order to prevent very large  */
8688
    /* or high resolution pages from having allocation problems.                 */
8689
    /* We use MaxBitmap to decide when a clist is needed.*/
8690
44.6k
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_saved_pages, NULL, 0) <= 0 &&
8691
44.6k
        gx_device_is_pattern_clist(target) == 0 &&
8692
44.6k
        gx_device_is_pattern_accum(target) == 0 &&
8693
44.6k
        gs_device_is_memory(target) == 0) {
8694
8695
0
        uint32_t pdf14_trans_buffer_size =
8696
0
              (ESTIMATED_PDF14_ROW_SPACE(max(1, target->width),
8697
0
                                         target->color_info.num_components,
8698
0
                                         deep ? 16 : 8) >> 3);
8699
8700
0
        if (target->height < max_ulong / pdf14_trans_buffer_size)
8701
0
                pdf14_trans_buffer_size *= target->height;
8702
0
        else
8703
0
                max_bitmap = 0;     /* Force decision to clist */
8704
0
        if (pdf14_trans_buffer_size > max_bitmap)
8705
0
            use_pdf14_accum = true;
8706
0
    }
8707
44.6k
    code = dev_proc(target, get_profile)(target,  &dev_profile);
8708
44.6k
    if (code < 0)
8709
0
        return code;
8710
44.6k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
8711
44.6k
                          &render_cond);
8712
44.6k
    if_debug0m('v', mem, "[v]gs_pdf14_device_push\n");
8713
8714
44.6k
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
8715
44.6k
                                  pdf14pct, use_pdf14_accum);
8716
44.6k
    if (code < 0)
8717
0
        return code;
8718
44.6k
    code = gs_copydevice((gx_device **) &p14dev,
8719
44.6k
                         (const gx_device *) &dev_proto, mem);
8720
44.6k
    if (code < 0)
8721
0
        return code;
8722
8723
44.6k
    gs_pdf14_device_copy_params((gx_device *)p14dev, target);
8724
44.6k
    gx_device_set_target((gx_device_forward *)p14dev, target);
8725
44.6k
    p14dev->pad = target->pad;
8726
44.6k
    p14dev->log2_align_mod = target->log2_align_mod;
8727
44.6k
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && !target->is_planar)
8728
0
        p14dev->is_planar = true;
8729
44.6k
    else
8730
44.6k
        p14dev->is_planar = target->is_planar;
8731
44.6k
    p14dev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
8732
8733
44.6k
    p14dev->alpha = 1.0;
8734
44.6k
    p14dev->shape = 1.0;
8735
44.6k
    p14dev->opacity = 1.0;
8736
44.6k
    p14dev->fillconstantalpha = 1.0;
8737
44.6k
    p14dev->strokeconstantalpha = 1.0;
8738
8739
    /* Simulated overprint case.  We have to use CMYK-based profile.  Also if the target
8740
       profile is NCLR, we are going to use a pdf14 device that is CMYK based and
8741
       do the mapping to the NCLR profile when the put_image occurs */
8742
44.6k
    if ((p14dev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
8743
44.6k
        icc_profile->data_cs == gsNCHANNEL) {
8744
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "gs_pdf14_device_push");
8745
0
        gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8746
0
            -1, "gs_pdf14_device_push");
8747
0
        p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
8748
44.6k
    } else {
8749
        /* If the target profile was CIELAB (and we are not using a blend CS),
8750
           then overide with default RGB for proper blending.  During put_image
8751
           we will convert from RGB to CIELAB.  Need to check that we have a
8752
           default profile, which will not be the case if we are coming from the clist reader */
8753
44.6k
        if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab)
8754
44.6k
            && pgs->icc_manager->default_rgb != NULL &&
8755
44.6k
            p14dev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
8756
0
            p14dev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
8757
0
            gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "gs_pdf14_device_push");
8758
0
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8759
0
                -1, "gs_pdf14_device_push");
8760
0
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_rgb;
8761
0
        }
8762
44.6k
    }
8763
8764
44.6k
    if (pdf14pct->params.overprint_sim_push &&
8765
44.6k
        pdf14pct->params.num_spot_colors_int > 0) {
8766
0
        p14dev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
8767
0
        p14dev->procs.ret_devn_params = pdf14_ret_devn_params;
8768
0
        p14dev->op_pequiv_cmyk_colors.all_color_info_valid = false;
8769
0
        p14dev->target_support_devn = p14dev->icc_struct->supports_devn;
8770
0
        p14dev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
8771
0
    }
8772
8773
    /* The number of color planes should not exceed that of the target.
8774
       Unless we are using a blend CS */
8775
44.6k
    if (!(p14dev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || p14dev->overprint_sim)) {
8776
44.6k
        if (p14dev->color_info.num_components > target->color_info.num_components)
8777
0
            p14dev->color_info.num_components = target->color_info.num_components;
8778
44.6k
        if (p14dev->color_info.max_components > target->color_info.max_components)
8779
0
            p14dev->color_info.max_components = target->color_info.max_components;
8780
44.6k
    }
8781
44.6k
    p14dev->color_info.depth = p14dev->color_info.num_components * (8<<deep);
8782
    /* If we have a tag device then go ahead and do a special encoder
8783
       decoder for the pdf14 device to make sure we maintain this
8784
       information in the encoded color information.  We could use
8785
       the target device's methods but the PDF14 device has to maintain
8786
       8 bit color always and we could run into other issues if the number
8787
       of colorants became large.  If we need to do compressed color with
8788
       tags that will be a special project at that time */
8789
44.6k
    if (deep) {
8790
0
        set_dev_proc(p14dev, encode_color, pdf14_encode_color16);
8791
0
        set_dev_proc(p14dev, decode_color, pdf14_decode_color16);
8792
0
    }
8793
44.6k
    if (has_tags) {
8794
0
        set_dev_proc(p14dev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
8795
0
        p14dev->color_info.comp_shift[p14dev->color_info.num_components] = p14dev->color_info.depth;
8796
0
        p14dev->color_info.depth += 8;
8797
0
    }
8798
    /* if the device has separations already defined (by SeparationOrderNames) */
8799
    /* we need to copy them (allocating new names) so the colorants are in the */
8800
    /* same order as the target device.                                        */
8801
44.6k
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0)) {
8802
0
        code = devn_copy_params(target, (gx_device *)p14dev);
8803
0
        if (code < 0)
8804
0
            return code;
8805
0
    }
8806
    /* by definition pdf14_encode _is_ standard */
8807
44.6k
    p14dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
8808
44.6k
    gx_device_fill_in_procs((gx_device *)p14dev);
8809
44.6k
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
8810
44.6k
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
8811
44.6k
    gx_set_cmap_procs(pgs, (gx_device *)p14dev);
8812
8813
    /* Components shift, etc have to be based upon 8 (or 16) bit */
8814
178k
    for (k = 0; k < p14dev->color_info.num_components; k++) {
8815
134k
        p14dev->color_info.comp_bits[k] = 8<<deep;
8816
134k
        p14dev->color_info.comp_shift[k] =
8817
134k
                            (p14dev->color_info.num_components - 1 - k) * (8<<deep);
8818
134k
    }
8819
44.6k
    if (use_pdf14_accum) {
8820
        /* we will disable this device later, but we don't want to allocate large buffers */
8821
0
        p14dev->width = 1;
8822
0
        p14dev->height = 1;
8823
0
    }
8824
8825
44.6k
    p14dev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
8826
44.6k
    code = dev_proc((gx_device *) p14dev, open_device) ((gx_device *) p14dev);
8827
44.6k
    *pdev = (gx_device *) p14dev;
8828
44.6k
    pdf14_set_marking_params((gx_device *)p14dev, pgs);
8829
44.6k
    p14dev->color_model_stack = NULL;
8830
8831
    /* In case we have alphabits set */
8832
44.6k
    p14dev->color_info.anti_alias = target->color_info.anti_alias;
8833
8834
44.6k
    if (pdf14pct->params.is_pattern) {
8835
702
        code = pdf14_initialize_ctx((gx_device*)p14dev,
8836
702
            p14dev->color_info.num_components,
8837
702
            p14dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, (const gs_gstate*) pgs);
8838
702
        if (code < 0)
8839
0
            return code;
8840
702
    }
8841
8842
    /* We should never go into this when using a blend color space */
8843
44.6k
    if (use_pdf14_accum) {
8844
0
        const gx_device_pdf14_accum *accum_proto = NULL;
8845
0
        gx_device *new_target = NULL;
8846
0
        gx_device_color pdcolor;
8847
0
        frac pconc_white = frac_1;
8848
0
        bool UsePlanarBuffer = false;
8849
8850
0
        if_debug0m('v', mem, "[v]gs_pdf14_device_push: Inserting clist device.\n");
8851
8852
        /* get the prototype for the accumulator device based on colorspace */
8853
0
        switch (target->color_info.max_components) {  /* use max_components in case is devn device */
8854
0
            case 1:
8855
0
                accum_proto = &pdf14_accum_Gray;
8856
0
                break;
8857
0
            case 3:
8858
0
                accum_proto = &pdf14_accum_RGB;
8859
0
                break;
8860
0
            case 4:
8861
0
                accum_proto = &pdf14_accum_CMYK;
8862
0
                break;
8863
0
            default:
8864
0
                accum_proto = &pdf14_accum_CMYKspot;
8865
0
                UsePlanarBuffer = true;
8866
0
        }
8867
0
        if (accum_proto == NULL ||
8868
0
            (code = gs_copydevice(&new_target, (gx_device *)accum_proto, mem->stable_memory)) < 0)
8869
0
            goto no_clist_accum;
8870
8871
0
        ((gx_device_pdf14_accum *)new_target)->save_p14dev = (gx_device *)p14dev;  /* non-clist p14dev */
8872
        /* Fill in values from the target device before opening */
8873
0
        new_target->color_info = p14dev->color_info;
8874
0
        ((gx_device_pdf14_accum *)new_target)->devn_params = p14dev->devn_params;
8875
0
        new_target->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
8876
0
        set_linear_color_bits_mask_shift(new_target);
8877
0
        gs_pdf14_device_copy_params(new_target, target);
8878
0
        ((gx_device_pdf14_accum *)new_target)->page_uses_transparency = true;
8879
0
        gx_device_fill_in_procs(new_target);
8880
8881
0
        memcpy(&(new_target->space_params), &(target->space_params), sizeof(gdev_space_params));
8882
0
        max_bitmap = max(target->space_params.MaxBitmap, target->space_params.BufferSpace);
8883
0
        ((gx_device_pdf14_accum *)new_target)->space_params.BufferSpace = max_bitmap;
8884
8885
0
        new_target->PageHandlerPushed = true;
8886
0
        new_target->ObjectHandlerPushed = true;
8887
        /* if the device has separations already defined (by SeparationOrderNames) */
8888
        /* we need to copy them (allocating new names) so the colorants are in the */
8889
        /* same order as the target device.                                        */
8890
0
        if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0)) {
8891
0
            code = devn_copy_params(target, (gx_device *)pdev);
8892
0
            if (code < 0)
8893
0
                return code;
8894
0
        }
8895
        /* UsePlanarBuffer is true in case this is CMYKspot */
8896
0
        if ((code = gdev_prn_open_planar(new_target, UsePlanarBuffer)) < 0 ||
8897
0
             !PRINTER_IS_CLIST((gx_device_printer *)new_target)) {
8898
0
            gs_free_object(mem->stable_memory, new_target, "pdf14-accum");
8899
0
            goto no_clist_accum;
8900
0
        }
8901
        /* Do the initial fillpage into the pdf14-accum device we just created */
8902
0
        dev_proc(new_target, set_graphics_type_tag)((gx_device *)new_target, GS_UNTOUCHED_TAG);
8903
0
        if ((code = gx_remap_concrete_DGray(gs_currentcolorspace_inline((gs_gstate *)pgs),
8904
0
                                            &pconc_white,
8905
0
                                            &pdcolor, pgs, new_target, gs_color_select_all,
8906
0
                                            dev_profile)) < 0)
8907
0
            goto no_clist_accum;
8908
8909
0
        (*dev_proc(new_target, fillpage))(new_target, pgs, &pdcolor);
8910
0
        code = clist_composite(new_target, pdev, (gs_composite_t *)pdf14pct, pgs, mem, NULL);
8911
0
        if (code < 0)
8912
0
            goto no_clist_accum;
8913
8914
0
        pdf14_disable_device((gx_device *)p14dev);           /* make the non-clist device forward */
8915
0
        pdf14_close((gx_device *)p14dev);                    /* and free up the little memory it had */
8916
0
    }
8917
44.6k
    return code;
8918
8919
0
no_clist_accum:
8920
        /* FIXME: We allocated a really small p14dev, but that won't work */
8921
0
    return gs_throw_code(gs_error_Fatal); /* punt for now */
8922
44.6k
}
8923
8924
/*
8925
 * In a modest violation of good coding practice, the gs_composite_common
8926
 * fields are "known" to be simple (contain no pointers to garbage
8927
 * collected memory), and we also know the gs_pdf14trans_params_t structure
8928
 * to be simple, so we just create a trivial structure descriptor for the
8929
 * entire gs_pdf14trans_s structure.
8930
 */
8931
#define private_st_gs_pdf14trans_t()\
8932
  gs_private_st_ptrs2(st_pdf14trans, gs_pdf14trans_t, "gs_pdf14trans_t",\
8933
      st_pdf14trans_enum_ptrs, st_pdf14trans_reloc_ptrs, params.transfer_function, params.iccprofile)
8934
8935
/* GC descriptor for gs_pdf14trans_t */
8936
private_st_gs_pdf14trans_t();
8937
8938
/*
8939
 * Check for equality of two PDF 1.4 transparency compositor objects.
8940
 *
8941
 * We are currently always indicating that PDF 1.4 transparency compositors are
8942
 * equal.  Two transparency compositors may have teh same data but still
8943
 * represent separate actions.  (E.g. two PDF14_BEGIN_TRANS_GROUP compositor
8944
 * operations in a row mean that we are creating a group inside of a group.
8945
 */
8946
static  bool
8947
c_pdf14trans_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
8948
0
{
8949
0
    return false;
8950
0
}
8951
8952
#ifdef DEBUG
8953
static const char * pdf14_opcode_names[] = PDF14_OPCODE_NAMES;
8954
#endif
8955
8956
#define put_value(dp, value)\
8957
353k
    BEGIN\
8958
353k
        memcpy(dp, &value, sizeof(value));\
8959
353k
        dp += sizeof(value);\
8960
353k
    END
8961
8962
static inline int
8963
c_pdf14trans_write_ctm(byte **ppbuf, const gs_pdf14trans_params_t *pparams)
8964
35.4k
{
8965
    /* Note: We can't skip writing CTM if it is equal to pgs->ctm,
8966
       because clist writer may skip this command for some bands.
8967
       For a better result we need individual CTM for each band.
8968
     */
8969
35.4k
    byte *pbuf = *ppbuf;
8970
35.4k
    int len, code;
8971
8972
35.4k
    len = cmd_write_ctm_return_length_nodevice(&pparams->ctm);
8973
35.4k
    pbuf--; /* For cmd_write_ctm. */
8974
35.4k
    code = cmd_write_ctm(&pparams->ctm, pbuf, len);
8975
35.4k
    if (code < 0)
8976
0
        return code;
8977
35.4k
    pbuf += len + 1;
8978
35.4k
    *ppbuf = pbuf;
8979
35.4k
    return 0;
8980
35.4k
}
8981
8982
/*
8983
 * Convert a PDF 1.4 transparency compositor to string form for use by the command
8984
 * list device. This is also where we update the pdf14_needed. When set the clist
8985
 * painting procs will update the trans_bbox state for bands that are affected.
8986
*/
8987
static  int
8988
c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
8989
                   gx_device_clist_writer *cdev)
8990
103k
{
8991
103k
    const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
8992
103k
    int need, avail = *psize;
8993
103k
    byte buf[MAX_CLIST_TRANSPARENCY_BUFFER_SIZE]; /* Must be large enough
8994
        to fit the data written below. We don't implement a dynamic check for
8995
        the buffer owerflow, assuming that the consistency is verified in the
8996
        coding phase. See the definition of MAX_CLIST_TRANSPARENCY_BUFFER_SIZE. */
8997
103k
    byte * pbuf = buf;
8998
103k
    int opcode = pparams->pdf14_op;
8999
103k
    int mask_size = 0;
9000
103k
    uint mask_id = 0;
9001
103k
    int code;
9002
103k
    bool found_icc;
9003
103k
    int64_t hashcode = 0;
9004
103k
    cmm_profile_t *icc_profile;
9005
103k
    gsicc_rendering_param_t render_cond;
9006
103k
    cmm_dev_profile_t *dev_profile;
9007
    /* We maintain and update working copies until we actually write the clist */
9008
103k
    int pdf14_needed = cdev->pdf14_needed;
9009
103k
    int trans_group_level = cdev->pdf14_trans_group_level;
9010
103k
    int smask_level = cdev->pdf14_smask_level;
9011
103k
    bool deep = device_is_deep((gx_device *)cdev);
9012
9013
103k
    code = dev_proc((gx_device *) cdev, get_profile)((gx_device *) cdev,
9014
103k
                                                     &dev_profile);
9015
103k
    if (code < 0)
9016
0
        return code;
9017
103k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9018
103k
                          &render_cond);
9019
103k
    *pbuf++ = opcode;     /* 1 byte */
9020
103k
    if (trans_group_level < 0 && opcode != PDF14_PUSH_DEVICE)
9021
0
        return_error(gs_error_unregistered);  /* prevent spurious transparency ops (Bug 702327) */
9022
9023
103k
    switch (opcode) {
9024
0
        default:      /* Should not occur. */
9025
0
            break;
9026
534
        case PDF14_PUSH_DEVICE:
9027
534
            trans_group_level = 0;
9028
534
            cdev->pdf14_smask_level = 0;
9029
534
            cdev->page_pdf14_needed = false;
9030
534
            put_value(pbuf, pparams->num_spot_colors);
9031
534
            put_value(pbuf, pparams->num_spot_colors_int);
9032
534
            put_value(pbuf, pparams->overprint_sim_push);
9033
534
            put_value(pbuf, pparams->is_pattern);
9034
9035
            /* If we happen to be going to a color space like CIELAB then
9036
               we are going to do our blending in default RGB and convert
9037
               to CIELAB at the end.  To do this, we need to store the
9038
               default RGB profile in the clist so that we can grab it
9039
               later on during the clist read back and put image command */
9040
534
            if (icc_profile->data_cs == gsCIELAB || icc_profile->islab) {
9041
                /* Get the default RGB profile.  Set the device hash code
9042
                   so that we can extract it during the put_image operation. */
9043
0
                cdev->trans_dev_icc_hash = gsicc_get_hash(pparams->iccprofile);
9044
0
                found_icc =
9045
0
                    clist_icc_searchtable(cdev, gsicc_get_hash(pparams->iccprofile));
9046
0
                if (!found_icc) {
9047
                    /* Add it to the table */
9048
0
                    clist_icc_addentry(cdev, gsicc_get_hash(pparams->iccprofile),
9049
0
                                       pparams->iccprofile);
9050
0
                }
9051
0
            }
9052
534
            break;
9053
530
        case PDF14_POP_DEVICE:
9054
530
            pdf14_needed = false;   /* reset pdf14_needed */
9055
530
            trans_group_level = -1;   /* reset so we need to PUSH_DEVICE next */
9056
530
            smask_level = 0;
9057
530
            put_value(pbuf, pparams->is_pattern);
9058
530
            break;
9059
17.9k
        case PDF14_END_TRANS_GROUP:
9060
18.2k
        case PDF14_END_TRANS_TEXT_GROUP:
9061
18.2k
            trans_group_level--;  /* if now at page level, pdf14_needed will be updated */
9062
18.2k
            if (smask_level == 0 && trans_group_level == 0)
9063
1.46k
                pdf14_needed = cdev->page_pdf14_needed;
9064
18.2k
            break;      /* No data */
9065
356
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9066
18.3k
        case PDF14_BEGIN_TRANS_GROUP:
9067
18.3k
            pdf14_needed = true;   /* the compositor will be needed while reading */
9068
18.3k
            trans_group_level++;
9069
18.3k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9070
18.3k
            if (code < 0)
9071
0
                return code;
9072
18.3k
            *pbuf++ = (pparams->Isolated & 1) + ((pparams->Knockout & 1) << 1);
9073
18.3k
            *pbuf++ = pparams->blend_mode;
9074
18.3k
            *pbuf++ = pparams->group_color_type;
9075
18.3k
            *pbuf++ = pparams->page_group;
9076
18.3k
            put_value(pbuf, pparams->group_color_numcomps);
9077
18.3k
            put_value(pbuf, pparams->opacity);
9078
18.3k
            put_value(pbuf, pparams->shape);
9079
18.3k
            put_value(pbuf, pparams->bbox);
9080
18.3k
            put_value(pbuf, pparams->shade_group);
9081
18.3k
            put_value(pbuf, pparams->text_group);
9082
18.3k
            mask_id = pparams->mask_id;
9083
18.3k
            put_value(pbuf, mask_id);
9084
            /* Color space information maybe ICC based
9085
               in this case we need to store the ICC
9086
               profile or the ID if it is cached already */
9087
18.3k
            if (pparams->group_color_type == ICC) {
9088
                /* Check if it is already in the ICC clist table */
9089
964
                hashcode = gsicc_get_hash(pparams->iccprofile);
9090
964
                found_icc = clist_icc_searchtable(cdev, hashcode);
9091
964
                if (!found_icc) {
9092
                    /* Add it to the table */
9093
197
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9094
197
                    put_value(pbuf, hashcode);
9095
767
                } else {
9096
                    /* It will be in the clist. Just write out the hashcode */
9097
767
                    put_value(pbuf, hashcode);
9098
767
                }
9099
17.3k
            } else {
9100
17.3k
                put_value(pbuf, hashcode);
9101
17.3k
            }
9102
18.3k
            break;
9103
17.1k
        case PDF14_BEGIN_TRANS_MASK:
9104
17.1k
            if (pparams->subtype != TRANSPARENCY_MASK_None) {
9105
14.5k
                pdf14_needed = true;   /* the compositor will be needed while reading */
9106
14.5k
                smask_level++;
9107
14.5k
            }
9108
17.1k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9109
17.1k
            if (code < 0)
9110
0
                return code;
9111
17.1k
            put_value(pbuf, pparams->subtype);
9112
17.1k
            *pbuf++ = pparams->group_color_type;
9113
17.1k
            put_value(pbuf, pparams->group_color_numcomps);
9114
17.1k
            *pbuf++ = pparams->replacing;
9115
17.1k
            *pbuf++ = (pparams->function_is_identity) | (deep<<1);
9116
17.1k
            *pbuf++ = pparams->Background_components;
9117
17.1k
            *pbuf++ = pparams->Matte_components;
9118
17.1k
            put_value(pbuf, pparams->bbox);
9119
17.1k
            mask_id = pparams->mask_id;
9120
17.1k
            put_value(pbuf, mask_id);
9121
17.1k
            if (pparams->Background_components) {
9122
190
                const int l = sizeof(pparams->Background[0]) * pparams->Background_components;
9123
9124
190
                memcpy(pbuf, pparams->Background, l);
9125
190
                pbuf += l;
9126
190
                memcpy(pbuf, &pparams->GrayBackground, sizeof(pparams->GrayBackground));
9127
190
                pbuf += sizeof(pparams->GrayBackground);
9128
190
            }
9129
17.1k
            if (pparams->Matte_components) {
9130
0
                const int m = sizeof(pparams->Matte[0]) * pparams->Matte_components;
9131
9132
0
                memcpy(pbuf, pparams->Matte, m);
9133
0
                pbuf += m;
9134
0
            }
9135
17.1k
            if (!pparams->function_is_identity)
9136
4
                mask_size = (256+deep)<<deep;
9137
            /* Color space information may be ICC based
9138
               in this case we need to store the ICC
9139
               profile or the ID if it is cached already */
9140
17.1k
            if (pparams->group_color_type == ICC) {
9141
                /* Check if it is already in the ICC clist table */
9142
14.5k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9143
14.5k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9144
14.5k
                if (!found_icc) {
9145
                    /* Add it to the table */
9146
142
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9147
142
                    put_value(pbuf, hashcode);
9148
14.3k
                } else {
9149
                    /* It will be in the clist. Just write out the hashcode */
9150
14.3k
                    put_value(pbuf, hashcode);
9151
14.3k
                }
9152
14.5k
            } else {
9153
2.61k
                put_value(pbuf, hashcode);
9154
2.61k
            }
9155
17.1k
            break;
9156
14.5k
        case PDF14_END_TRANS_MASK:
9157
14.5k
            smask_level--;
9158
14.5k
            if (smask_level == 0 && trans_group_level == 0)
9159
1.05k
                pdf14_needed = cdev->page_pdf14_needed;
9160
14.5k
            break;
9161
31.1k
        case PDF14_SET_BLEND_PARAMS:
9162
31.1k
            if (pparams->blend_mode != BLEND_MODE_Normal || pparams->opacity != 1.0 ||
9163
31.1k
                pparams->shape != 1.0)
9164
31.1k
                pdf14_needed = true;    /* the compositor will be needed while reading */
9165
0
            else if (smask_level == 0 && trans_group_level == 0)
9166
0
                pdf14_needed = false;   /* At page level, set back to false */
9167
31.1k
            if (smask_level == 0 && trans_group_level == 0)
9168
5.12k
                cdev->page_pdf14_needed = pdf14_needed;         /* save for after popping to page level */
9169
            /* Changed is now two bytes due to overprint stroke fill. Write as int */
9170
31.1k
            put_value(pbuf, pparams->changed);
9171
31.1k
            if (pparams->changed & PDF14_SET_BLEND_MODE)
9172
54
                *pbuf++ = pparams->blend_mode;
9173
31.1k
            if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
9174
534
                *pbuf++ = pparams->text_knockout;
9175
31.1k
            if (pparams->changed & PDF14_SET_AIS)
9176
31.1k
                put_value(pbuf, pparams->ais);
9177
31.1k
            if (pparams->changed & PDF14_SET_OVERPRINT)
9178
31.1k
                put_value(pbuf, pparams->overprint);
9179
31.1k
            if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
9180
31.1k
                put_value(pbuf, pparams->stroke_overprint);
9181
31.1k
            if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
9182
31.1k
                put_value(pbuf, pparams->fillconstantalpha);
9183
31.1k
            if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
9184
31.1k
                put_value(pbuf, pparams->strokeconstantalpha);
9185
31.1k
            if (pparams->changed & PDF_SET_FILLSTROKE_STATE)
9186
31.1k
                put_value(pbuf, pparams->op_fs_state);
9187
31.1k
            break;
9188
0
        case PDF14_PUSH_TRANS_STATE:
9189
0
            break;
9190
2.73k
        case PDF14_POP_TRANS_STATE:
9191
2.73k
            break;
9192
0
        case PDF14_PUSH_SMASK_COLOR:
9193
0
            return 0;   /* We really should never be here */
9194
0
            break;
9195
0
        case PDF14_POP_SMASK_COLOR:
9196
0
            return 0;   /* We really should never be here */
9197
0
            break;
9198
103k
    }
9199
9200
    /* check for fit */
9201
103k
    need = (pbuf - buf) + mask_size;
9202
103k
    *psize = need;
9203
103k
    if (need > avail) {
9204
26.5k
        if (avail)
9205
0
            return_error(gs_error_rangecheck);
9206
26.5k
        else
9207
26.5k
            return gs_error_rangecheck;
9208
26.5k
    }
9209
9210
    /* If we are writing more than the maximum ever expected,
9211
     * return a rangecheck error. Second check is for Coverity
9212
     */
9213
76.7k
    if ((need + 3 > MAX_CLIST_COMPOSITOR_SIZE) ||
9214
76.7k
        (need + 3 - mask_size > MAX_CLIST_TRANSPARENCY_BUFFER_SIZE) )
9215
0
        return_error(gs_error_rangecheck);
9216
9217
    /* Copy our serialized data into the output buffer */
9218
76.7k
    memcpy(data, buf, need - mask_size);
9219
76.7k
    if (mask_size)  /* Include the transfer mask data if present */
9220
2
        memcpy(data + need - mask_size, pparams->transfer_fn, mask_size);
9221
76.7k
    if_debug3m('v', cdev->memory,
9222
76.7k
               "[v] c_pdf14trans_write: opcode = %s mask_id=%d need = %d\n",
9223
76.7k
               pdf14_opcode_names[opcode], mask_id, need);
9224
76.7k
    cdev->pdf14_needed = pdf14_needed;          /* all OK to update */
9225
76.7k
    cdev->pdf14_trans_group_level = trans_group_level;
9226
76.7k
    cdev->pdf14_smask_level = smask_level;
9227
76.7k
    return 0;
9228
76.7k
}
9229
9230
#undef put_value
9231
9232
/* Function prototypes */
9233
static int gs_create_pdf14trans( gs_composite_t ** ppct,
9234
                const gs_pdf14trans_params_t * pparams,
9235
                gs_memory_t * mem );
9236
9237
#define read_value(dp, value)\
9238
12.2M
    BEGIN\
9239
12.2M
        memcpy(&value, dp, sizeof(value));\
9240
12.2M
        dp += sizeof(value);\
9241
12.2M
    END
9242
9243
/*
9244
 * Convert the string representation of the PDF 1.4 transparency parameter
9245
 * into the full compositor.
9246
 */
9247
static  int
9248
c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
9249
                                uint size, gs_memory_t * mem )
9250
3.83M
{
9251
3.83M
    gs_pdf14trans_params_t params = {0};
9252
3.83M
    const byte * start = data;
9253
3.83M
    int used, code = 0;
9254
3.83M
    bool deep;
9255
9256
3.83M
    if (size < 1)
9257
0
        return_error(gs_error_rangecheck);
9258
9259
    /* Read PDF 1.4 compositor data from the clist */
9260
3.83M
    params.pdf14_op = *data++;
9261
3.83M
    if_debug2m('v', mem, "[v] c_pdf14trans_read: opcode = %s  avail = %d",
9262
3.83M
               pdf14_opcode_names[params.pdf14_op], size);
9263
3.83M
    memset(&params.ctm, 0, sizeof(params.ctm));
9264
3.83M
    switch (params.pdf14_op) {
9265
0
        default:      /* Should not occur. */
9266
0
            break;
9267
51.0k
        case PDF14_PUSH_DEVICE:
9268
51.0k
            read_value(data, params.num_spot_colors);
9269
51.0k
            read_value(data, params.num_spot_colors_int);
9270
51.0k
            read_value(data, params.overprint_sim_push);
9271
51.0k
            read_value(data, params.is_pattern);
9272
51.0k
            break;
9273
0
        case PDF14_ABORT_DEVICE:
9274
0
            break;
9275
51.0k
        case PDF14_POP_DEVICE:
9276
51.0k
            read_value(data, params.is_pattern);
9277
51.0k
            break;
9278
165k
        case PDF14_END_TRANS_GROUP:
9279
168k
        case PDF14_END_TRANS_TEXT_GROUP:
9280
#ifdef DEBUG
9281
            code += 0; /* A good place for a breakpoint. */
9282
#endif
9283
168k
            break;      /* No data */
9284
0
        case PDF14_PUSH_TRANS_STATE:
9285
0
            break;
9286
266k
        case PDF14_POP_TRANS_STATE:
9287
266k
            break;
9288
34.1k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9289
168k
        case PDF14_BEGIN_TRANS_GROUP:
9290
            /*
9291
             * We are currently not using the bbox or the colorspace so they were
9292
             * not placed in the clist
9293
             */
9294
168k
            data = cmd_read_matrix(&params.ctm, data);
9295
168k
            params.Isolated = (*data) & 1;
9296
168k
            params.Knockout = (*data++ >> 1) & 1;
9297
168k
            params.blend_mode = *data++;
9298
168k
            params.group_color_type = *data++;  /* Trans group color */
9299
168k
            params.page_group = *data++;
9300
168k
            read_value(data,params.group_color_numcomps);  /* color group size */
9301
168k
            read_value(data, params.opacity);
9302
168k
            read_value(data, params.shape);
9303
168k
            read_value(data, params.bbox);
9304
168k
            read_value(data, params.shade_group);
9305
168k
            read_value(data, params.text_group);
9306
168k
            read_value(data, params.mask_id);
9307
168k
            read_value(data, params.icc_hash);
9308
168k
            break;
9309
286k
        case PDF14_BEGIN_TRANS_MASK:
9310
                /* This is the largest transparency parameter at this time (potentially
9311
                 * 1531 bytes in size if Background_components =
9312
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and Matte_components =
9313
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and we have a transfer function as well).
9314
                 *
9315
                 * NOTE:
9316
                 * The clist reader must be able to handle this sized device.
9317
                 * If any changes are made here the #define MAX_CLIST_COMPOSITOR_SIZE
9318
                 * may also need to be changed correspondingly (defined in gstparam.h)
9319
                 * Also... if another compositor param should exceed this size, this
9320
                 * same condition applies.
9321
                 */
9322
286k
            data = cmd_read_matrix(&params.ctm, data);
9323
286k
            read_value(data, params.subtype);
9324
286k
            params.group_color_type = *data++;
9325
286k
            read_value(data, params.group_color_numcomps);
9326
286k
            params.replacing = *data++;
9327
286k
            params.function_is_identity = *data & 1;
9328
286k
            deep = (*data++)>>1;
9329
286k
            params.Background_components = *data++;
9330
286k
            params.Matte_components = *data++;
9331
286k
            read_value(data, params.bbox);
9332
286k
            read_value(data, params.mask_id);
9333
286k
            if (params.Background_components) {
9334
9.09k
                const int l = sizeof(params.Background[0]) * params.Background_components;
9335
9336
9.09k
                memcpy(params.Background, data, l);
9337
9.09k
                data += l;
9338
9.09k
                memcpy(&params.GrayBackground, data, sizeof(params.GrayBackground));
9339
9.09k
                data += sizeof(params.GrayBackground);
9340
9.09k
            }
9341
286k
            if (params.Matte_components) {
9342
0
                const int m = sizeof(params.Matte[0]) * params.Matte_components;
9343
9344
0
                memcpy(params.Matte, data, m);
9345
0
                data += m;
9346
0
            }
9347
286k
            read_value(data, params.icc_hash);
9348
286k
            if (params.function_is_identity) {
9349
285k
                int i;
9350
9351
285k
                if (deep) {
9352
0
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++)
9353
0
                        ((uint16_t *)params.transfer_fn)[i] = i*0x10000/MASK_TRANSFER_FUNCTION_SIZE;
9354
0
                    ((uint16_t *)params.transfer_fn)[i] = 0xffff;
9355
285k
                } else {
9356
73.4M
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
9357
73.1M
                        params.transfer_fn[i] = (byte)floor(i *
9358
73.1M
                            (255.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)) + 0.5);
9359
73.1M
                    }
9360
285k
                }
9361
285k
            } else {
9362
400
                memcpy(params.transfer_fn, data, (256+deep)<<deep);
9363
400
                data += (256+deep)<<deep;
9364
400
            }
9365
286k
            break;
9366
22.3k
        case PDF14_END_TRANS_MASK:
9367
22.3k
            break;
9368
0
        case PDF14_PUSH_SMASK_COLOR:
9369
0
            return 0;
9370
0
            break;
9371
0
        case PDF14_POP_SMASK_COLOR:
9372
0
            return 0;
9373
0
            break;
9374
2.82M
        case PDF14_SET_BLEND_PARAMS:
9375
2.82M
            read_value(data, params.changed);
9376
2.82M
            if (params.changed & PDF14_SET_BLEND_MODE)
9377
5.40k
                params.blend_mode = *data++;
9378
2.82M
            if (params.changed & PDF14_SET_TEXT_KNOCKOUT)
9379
51.0k
                params.text_knockout = *data++;
9380
2.82M
            if (params.changed & PDF14_SET_AIS)
9381
2.82M
                read_value(data, params.ais);
9382
2.82M
            if (params.changed & PDF14_SET_OVERPRINT)
9383
2.82M
                read_value(data, params.overprint);
9384
2.82M
            if (params.changed & PDF14_SET_STROKEOVERPRINT)
9385
2.82M
                read_value(data, params.stroke_overprint);
9386
2.82M
            if (params.changed & PDF14_SET_FILLCONSTANTALPHA)
9387
2.82M
                read_value(data, params.fillconstantalpha);
9388
2.82M
            if (params.changed & PDF14_SET_STROKECONSTANTALPHA)
9389
2.82M
                read_value(data, params.strokeconstantalpha);
9390
2.82M
            if (params.changed & PDF_SET_FILLSTROKE_STATE)
9391
2.82M
                read_value(data, params.op_fs_state);
9392
2.82M
            break;
9393
3.83M
    }
9394
3.83M
    code = gs_create_pdf14trans(ppct, &params, mem);
9395
3.83M
    if (code < 0)
9396
0
        return code;
9397
3.83M
    used = data - start;
9398
3.83M
    if_debug2m('v', mem, " mask_id=%d used = %d\n", params.mask_id, used);
9399
9400
    /* If we read more than the maximum expected, return a rangecheck error */
9401
3.83M
    if ( used + 3 > MAX_CLIST_COMPOSITOR_SIZE )
9402
0
        return_error(gs_error_rangecheck);
9403
3.83M
    else
9404
3.83M
        return used;
9405
3.83M
}
9406
9407
/*
9408
 * Adjust the compositor's CTM.
9409
 */
9410
static int
9411
c_pdf14trans_adjust_ctm(gs_composite_t * pct0, int x0, int y0, gs_gstate *pgs)
9412
1.64M
{
9413
1.64M
    gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pct0;
9414
1.64M
    gs_matrix mat = pct->params.ctm;
9415
9416
1.64M
    if_debug6m('L', pgs->memory, " [%g %g %g %g %g %g]\n",
9417
1.64M
               mat.xx, mat.xy, mat.yx, mat.yy,
9418
1.64M
               mat.tx, mat.ty);
9419
1.64M
    mat.tx -= x0;
9420
1.64M
    mat.ty -= y0;
9421
1.64M
    gs_gstate_setmatrix(pgs, &mat);
9422
1.64M
    return 0;
9423
1.64M
}
9424
9425
/*
9426
 * Create a PDF 1.4 transparency compositor.
9427
 *
9428
 * Note that this routine will be called only if the device is not already
9429
 * a PDF 1.4 transparency compositor.
9430
 * Return an error if it is not a PDF14_PUSH_DEVICE operation.
9431
 */
9432
static  int
9433
c_pdf14trans_create_default_compositor(const gs_composite_t * pct,
9434
    gx_device ** pp14dev, gx_device * tdev, gs_gstate * pgs,
9435
    gs_memory_t * mem)
9436
44.6k
{
9437
44.6k
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
9438
44.6k
    int code = 0;
9439
9440
    /*
9441
     * We only handle the push operation.  All other operations are ignored.
9442
     * The other operations will be handled by the composite routine
9443
     * for the PDF 1.4 compositing device.
9444
     */
9445
44.6k
    switch (pdf14pct->params.pdf14_op) {
9446
44.6k
        case PDF14_PUSH_DEVICE:
9447
44.6k
            code = gs_pdf14_device_push(mem, pgs, pp14dev, tdev, pdf14pct);
9448
            /* Change (non-error) code to 1 to indicate that we created
9449
             * a device. */
9450
44.6k
            if (code >= 0)
9451
44.6k
                code = 1;
9452
44.6k
            break;
9453
0
        default:
9454
            /* No other compositor actions are allowed if this isn't a pdf14 compositor */
9455
0
            *pp14dev = NULL;
9456
0
            return_error(gs_error_unregistered);
9457
44.6k
    }
9458
44.6k
    return code;
9459
44.6k
}
9460
9461
/*
9462
 * Find an opening compositor op.
9463
 */
9464
static gs_compositor_closing_state
9465
find_opening_op(int opening_op, gs_composite_t **ppcte,
9466
                gs_compositor_closing_state return_code)
9467
168k
{
9468
    /* Assuming a right *BEGIN* - *END* operation balance. */
9469
168k
    gs_composite_t *pcte = *ppcte;
9470
9471
514k
    for (;;) {
9472
514k
        if (pcte->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
9473
514k
            gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pcte;
9474
514k
            int op = pct->params.pdf14_op;
9475
9476
514k
            *ppcte = pcte;
9477
514k
            if (op == opening_op)
9478
134k
                return return_code;
9479
379k
            if (op != PDF14_SET_BLEND_PARAMS) {
9480
253k
                if (opening_op == PDF14_BEGIN_TRANS_MASK)
9481
11
                    return COMP_ENQUEUE;
9482
253k
                if (opening_op == PDF14_BEGIN_TRANS_GROUP || opening_op == PDF14_BEGIN_TRANS_PAGE_GROUP) {
9483
14.0k
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK)
9484
13.1k
                        return COMP_ENQUEUE;
9485
14.0k
                }
9486
240k
                if (opening_op == PDF14_PUSH_DEVICE) {
9487
239k
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK &&
9488
239k
                        op != PDF14_BEGIN_TRANS_GROUP && op != PDF14_BEGIN_TRANS_PAGE_GROUP && op != PDF14_END_TRANS_GROUP &&
9489
239k
                        op != PDF14_END_TRANS_TEXT_GROUP)
9490
4.10k
                        return COMP_ENQUEUE;
9491
239k
                }
9492
240k
            }
9493
379k
        } else
9494
8
            return COMP_ENQUEUE;
9495
362k
        pcte = pcte->prev;
9496
362k
        if (pcte == NULL)
9497
16.8k
            return COMP_EXEC_QUEUE; /* Not in queue. */
9498
362k
    }
9499
168k
}
9500
9501
/*
9502
 * Find an opening compositor op.
9503
 */
9504
static gs_compositor_closing_state
9505
find_same_op(const gs_composite_t *composite_action, int my_op, gs_composite_t **ppcte)
9506
2.55M
{
9507
2.55M
    const gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
9508
2.55M
    gs_composite_t *pct = *ppcte;
9509
9510
2.55M
    for (;;) {
9511
2.55M
        if (pct->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
9512
2.55M
            gs_pdf14trans_t *pct_pdf14 = (gs_pdf14trans_t *)pct;
9513
9514
2.55M
            *ppcte = pct;
9515
2.55M
            if (pct_pdf14->params.pdf14_op != my_op)
9516
188k
                return COMP_ENQUEUE;
9517
2.36M
            if (pct_pdf14->params.csel == pct0->params.csel) {
9518
                /* If the new parameters completely replace the old ones
9519
                   then remove the old one from the queu */
9520
2.36M
                if ((pct_pdf14->params.changed & pct0->params.changed) ==
9521
2.36M
                    pct_pdf14->params.changed) {
9522
2.19M
                    return COMP_REPLACE_CURR;
9523
2.19M
                } else {
9524
170k
                    return COMP_ENQUEUE;
9525
170k
                }
9526
2.36M
            }
9527
2.36M
        } else
9528
3.26k
            return COMP_ENQUEUE;
9529
0
        pct = pct->prev;
9530
0
        if (pct == NULL)
9531
0
            return COMP_ENQUEUE; /* Not in queue. */
9532
0
    }
9533
2.55M
}
9534
9535
/*
9536
 * Check for closing compositor.
9537
 */
9538
static gs_compositor_closing_state
9539
c_pdf14trans_is_closing(const gs_composite_t * composite_action, gs_composite_t ** ppcte,
9540
                        gx_device *dev)
9541
3.83M
{
9542
3.83M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
9543
3.83M
    int op0 = pct0->params.pdf14_op;
9544
9545
3.83M
    switch (op0) {
9546
0
        default: return_error(gs_error_unregistered); /* Must not happen. */
9547
51.0k
        case PDF14_PUSH_DEVICE:
9548
51.0k
            return COMP_ENQUEUE;
9549
0
        case PDF14_ABORT_DEVICE:
9550
0
            return COMP_ENQUEUE;
9551
51.0k
        case PDF14_POP_DEVICE:
9552
51.0k
            if (*ppcte == NULL)
9553
38.0k
                return COMP_ENQUEUE;
9554
12.9k
            else {
9555
12.9k
                gs_compositor_closing_state state = find_opening_op(PDF14_PUSH_DEVICE, ppcte, COMP_EXEC_IDLE);
9556
9557
12.9k
                if (state == COMP_EXEC_IDLE)
9558
7.02k
                    return COMP_DROP_QUEUE;
9559
5.96k
                return state;
9560
12.9k
            }
9561
34.1k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9562
168k
        case PDF14_BEGIN_TRANS_GROUP:
9563
168k
            return COMP_ENQUEUE;
9564
165k
        case PDF14_END_TRANS_GROUP:
9565
168k
        case PDF14_END_TRANS_TEXT_GROUP:
9566
168k
            if (*ppcte == NULL)
9567
22.4k
                return COMP_EXEC_QUEUE;
9568
146k
            return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, COMP_MARK_IDLE);
9569
286k
        case PDF14_BEGIN_TRANS_MASK:
9570
286k
            return COMP_ENQUEUE;
9571
0
        case PDF14_PUSH_TRANS_STATE:
9572
0
            return COMP_ENQUEUE;
9573
266k
        case PDF14_POP_TRANS_STATE:
9574
266k
            return COMP_ENQUEUE;
9575
0
        case PDF14_PUSH_SMASK_COLOR:
9576
0
            return COMP_ENQUEUE;
9577
0
            break;
9578
0
        case PDF14_POP_SMASK_COLOR:
9579
0
            return COMP_ENQUEUE;
9580
0
            break;
9581
22.3k
        case PDF14_END_TRANS_MASK:
9582
22.3k
            if (*ppcte == NULL)
9583
12.6k
                return COMP_EXEC_QUEUE;
9584
9.66k
            return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte, COMP_MARK_IDLE);
9585
2.82M
        case PDF14_SET_BLEND_PARAMS:
9586
2.82M
            if (*ppcte == NULL)
9587
267k
                return COMP_ENQUEUE;
9588
            /* hack : ignore csel - here it is always zero : */
9589
2.55M
            return find_same_op(composite_action, PDF14_SET_BLEND_PARAMS, ppcte);
9590
3.83M
    }
9591
3.83M
}
9592
9593
/*
9594
 * Check whether a next operation is friendly to the compositor.
9595
 */
9596
static bool
9597
c_pdf14trans_is_friendly(const gs_composite_t * composite_action, byte cmd0, byte cmd1)
9598
393k
{
9599
393k
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
9600
393k
    int op0 = pct0->params.pdf14_op;
9601
9602
393k
    if (op0 == PDF14_PUSH_DEVICE || op0 == PDF14_END_TRANS_GROUP ||
9603
393k
        op0 == PDF14_END_TRANS_TEXT_GROUP) {
9604
        /* Halftone commands are always passed to the target printer device,
9605
           because transparency buffers are always contone.
9606
           So we're safe to execute them before queued transparency compositors. */
9607
72.8k
        if (cmd0 == cmd_opv_extend && (cmd1 == cmd_opv_ext_put_halftone ||
9608
38.9k
                                       cmd1 == cmd_opv_ext_put_ht_seg))
9609
38.9k
            return true;
9610
33.8k
        if (cmd0 == cmd_opv_set_misc && (cmd1 >> 6) == (cmd_set_misc_map >> 6))
9611
33.1k
            return true;
9612
33.8k
    }
9613
321k
    return false;
9614
393k
}
9615
9616
static composite_create_default_compositor_proc(c_pdf14trans_create_default_compositor);
9617
static composite_equal_proc(c_pdf14trans_equal);
9618
static composite_write_proc(c_pdf14trans_write);
9619
static composite_read_proc(c_pdf14trans_read);
9620
static composite_adjust_ctm_proc(c_pdf14trans_adjust_ctm);
9621
static composite_is_closing_proc(c_pdf14trans_is_closing);
9622
static composite_is_friendly_proc(c_pdf14trans_is_friendly);
9623
static composite_clist_write_update(c_pdf14trans_clist_write_update);
9624
static composite_clist_read_update(c_pdf14trans_clist_read_update);
9625
static composite_get_cropping_proc(c_pdf14trans_get_cropping);
9626
9627
/*
9628
 * Methods for the PDF 1.4 transparency compositor
9629
 *
9630
 * Note:  We have two set of methods.  They are the same except for the
9631
 * composite_clist_write_update method.  Once the clist write device is created,
9632
 * we use the second set of procedures.  This prevents the creation of multiple
9633
 * PDF 1.4 clist write compositor devices being chained together.
9634
 */
9635
const gs_composite_type_t   gs_composite_pdf14trans_type = {
9636
    GX_COMPOSITOR_PDF14_TRANS,
9637
    {
9638
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
9639
        c_pdf14trans_equal,                      /* procs.equal */
9640
        c_pdf14trans_write,                      /* procs.write */
9641
        c_pdf14trans_read,                       /* procs.read */
9642
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
9643
        c_pdf14trans_is_closing,                 /* procs.is_closing */
9644
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
9645
                /* Create a PDF 1.4 clist write device */
9646
        c_pdf14trans_clist_write_update,   /* procs.composite_clist_write_update */
9647
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
9648
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
9649
    }                                            /* procs */
9650
};
9651
9652
const gs_composite_type_t   gs_composite_pdf14trans_no_clist_writer_type = {
9653
    GX_COMPOSITOR_PDF14_TRANS,
9654
    {
9655
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
9656
        c_pdf14trans_equal,                      /* procs.equal */
9657
        c_pdf14trans_write,                      /* procs.write */
9658
        c_pdf14trans_read,                       /* procs.read */
9659
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
9660
        c_pdf14trans_is_closing,                 /* procs.is_closing */
9661
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
9662
                /* The PDF 1.4 clist writer already exists, Do not create it. */
9663
        gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */
9664
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
9665
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
9666
    }                                            /* procs */
9667
};
9668
9669
/*
9670
 * Verify that a compositor data structure is for the PDF 1.4 compositor.
9671
 */
9672
int
9673
gs_is_pdf14trans_compositor(const gs_composite_t * pct)
9674
5.56M
{
9675
5.56M
    return (pct->type == &gs_composite_pdf14trans_type
9676
5.56M
                || pct->type == &gs_composite_pdf14trans_no_clist_writer_type);
9677
5.56M
}
9678
9679
/*
9680
 * Create a PDF 1.4 transparency compositor data structure.
9681
 */
9682
static int
9683
gs_create_pdf14trans(
9684
    gs_composite_t **               ppct,
9685
    const gs_pdf14trans_params_t *  pparams,
9686
    gs_memory_t *                   mem )
9687
4.01M
{
9688
4.01M
    gs_pdf14trans_t *                pct;
9689
9690
4.01M
    pct = gs_alloc_struct(mem, gs_pdf14trans_t, &st_pdf14trans,
9691
4.01M
                             "gs_create_pdf14trans");
9692
4.01M
    if (pct == NULL)
9693
0
        return_error(gs_error_VMerror);
9694
4.01M
    pct->type = &gs_composite_pdf14trans_type;
9695
4.01M
    pct->id = gs_next_ids(mem, 1);
9696
4.01M
    pct->params = *pparams;
9697
4.01M
    pct->idle = false;
9698
4.01M
    *ppct = (gs_composite_t *)pct;
9699
4.01M
    return 0;
9700
4.01M
}
9701
9702
/*
9703
 * Send a PDF 1.4 transparency compositor action to the specified device.
9704
 */
9705
int
9706
send_pdf14trans(gs_gstate * pgs, gx_device * dev,
9707
    gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem)
9708
166k
{
9709
166k
    gs_composite_t * pct = NULL;
9710
166k
    int code;
9711
9712
166k
    pparams->ctm = ctm_only(pgs);
9713
166k
    code = gs_create_pdf14trans(&pct, pparams, mem);
9714
166k
    if (code < 0)
9715
0
        return code;
9716
166k
    code = dev_proc(dev, composite) (dev, pcdev, pct, pgs, mem, NULL);
9717
166k
    if (code == gs_error_handled)
9718
0
        code = 0;
9719
9720
166k
    gs_free_object(pgs->memory, pct, "send_pdf14trans");
9721
9722
166k
    return code;
9723
166k
}
9724
9725
/* ------------- PDF 1.4 transparency device for clist writing ------------- */
9726
9727
/*
9728
 * The PDF 1.4 transparency compositor device may have a different process
9729
 * color model than the output device.  If we are banding then we need to
9730
 * create two compositor devices.  The output side (clist reader) needs a
9731
 * compositor to actually composite the output.  We also need a compositor
9732
 * device before the clist writer.  This is needed to provide a process color
9733
 * model which matches the PDF 1.4 blending space.
9734
 *
9735
 * This section provides support for this device.
9736
 */
9737
9738
/*
9739
 * Define the default pre-clist (clist writer) PDF 1.4 compositing device.
9740
 * We actually use the same structure for both the clist writer and reader
9741
 * devices.  However we use separate names to identify the routines for each
9742
 * device.
9743
 */
9744
9745
static  dev_proc_composite(pdf14_clist_composite);
9746
static  dev_proc_composite(pdf14_clist_forward_composite);
9747
static  dev_proc_fill_path(pdf14_clist_fill_path);
9748
static  dev_proc_stroke_path(pdf14_clist_stroke_path);
9749
static  dev_proc_fill_stroke_path(pdf14_clist_fill_stroke_path);
9750
static  dev_proc_text_begin(pdf14_clist_text_begin);
9751
static  dev_proc_begin_typed_image(pdf14_clist_begin_typed_image);
9752
static  dev_proc_copy_planes(pdf14_clist_copy_planes);
9753
9754
static void
9755
pdf14_clist_init_procs(gx_device *dev,
9756
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
9757
                       dev_proc_get_color_comp_index(get_color_comp_index))
9758
267
{
9759
267
    set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
9760
267
    set_dev_proc(dev, sync_output, gx_forward_sync_output);
9761
267
    set_dev_proc(dev, output_page, gx_forward_output_page);
9762
267
    set_dev_proc(dev, close_device, gx_forward_close_device);
9763
267
    set_dev_proc(dev, map_rgb_color, pdf14_encode_color);
9764
267
    set_dev_proc(dev, map_color_rgb, pdf14_decode_color);
9765
267
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
9766
267
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
9767
267
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
9768
267
    set_dev_proc(dev, get_params, gx_forward_get_params);
9769
267
    set_dev_proc(dev, put_params, pdf14_put_params);
9770
267
    set_dev_proc(dev, map_cmyk_color, pdf14_encode_color);
9771
267
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
9772
267
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
9773
267
    set_dev_proc(dev, fill_path, pdf14_clist_fill_path);
9774
267
    set_dev_proc(dev, stroke_path, pdf14_clist_stroke_path);
9775
267
    set_dev_proc(dev, fill_mask, gx_forward_fill_mask);
9776
267
    set_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid);
9777
267
    set_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram);
9778
267
    set_dev_proc(dev, fill_triangle, gx_forward_fill_triangle);
9779
267
    set_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line);
9780
267
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
9781
267
    set_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2);
9782
267
    set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box);
9783
267
    set_dev_proc(dev, begin_typed_image, pdf14_clist_begin_typed_image);
9784
267
    set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle);
9785
267
    set_dev_proc(dev, composite, pdf14_clist_composite);
9786
267
    set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params);
9787
267
    set_dev_proc(dev, text_begin, pdf14_clist_text_begin);
9788
267
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
9789
267
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
9790
267
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
9791
267
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
9792
267
    set_dev_proc(dev, discard_transparency_layer, gx_default_discard_transparency_layer);
9793
267
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
9794
267
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
9795
267
    set_dev_proc(dev, encode_color, pdf14_encode_color);
9796
267
    set_dev_proc(dev, decode_color, pdf14_decode_color);
9797
267
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
9798
267
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
9799
267
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
9800
267
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
9801
267
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
9802
267
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
9803
267
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
9804
267
    set_dev_proc(dev, copy_planes, pdf14_clist_copy_planes);
9805
267
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
9806
267
    set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color);
9807
267
    set_dev_proc(dev, fill_stroke_path, pdf14_clist_fill_stroke_path);
9808
267
}
9809
9810
static void
9811
pdf14_clist_Gray_initialize_device_procs(gx_device *dev)
9812
0
{
9813
0
    pdf14_clist_init_procs(dev,
9814
0
                           gx_default_DevGray_get_color_mapping_procs,
9815
0
                           gx_default_DevGray_get_color_comp_index);
9816
0
}
9817
9818
static void
9819
pdf14_clist_RGB_initialize_device_procs(gx_device *dev)
9820
267
{
9821
267
    pdf14_clist_init_procs(dev,
9822
267
                           gx_default_DevRGB_get_color_mapping_procs,
9823
267
                           gx_default_DevRGB_get_color_comp_index);
9824
267
}
9825
9826
static void
9827
pdf14_clist_CMYK_initialize_device_procs(gx_device *dev)
9828
0
{
9829
0
    pdf14_clist_init_procs(dev,
9830
0
                           gx_default_DevCMYK_get_color_mapping_procs,
9831
0
                           gx_default_DevCMYK_get_color_comp_index);
9832
0
}
9833
9834
static void
9835
pdf14_clist_CMYKspot_initialize_device_procs(gx_device *dev)
9836
0
{
9837
0
    pdf14_clist_init_procs(dev,
9838
0
                           pdf14_cmykspot_get_color_mapping_procs,
9839
0
                           pdf14_cmykspot_get_color_comp_index);
9840
0
}
9841
9842
#if 0 /* NOT USED */
9843
static void
9844
pdf14_clist_RGBspot_initialize_device_procs(gx_device *dev)
9845
{
9846
    pdf14_clist_init_procs(dev,
9847
                           pdf14_rgbspot_get_color_mapping_procs,
9848
                           pdf14_rgbspot_get_color_comp_index);
9849
}
9850
9851
static int
9852
pdf14_clist_Grayspot_initialize_device_procs(gx_device *dev)
9853
{
9854
    pdf14_clist_init_procs(dev,
9855
                           pdf14_grayspot_get_color_mapping_procs,
9856
                           pdf14_grayspot_get_color_comp_index);
9857
}
9858
#endif  /* NOT USED */
9859
9860
const pdf14_clist_device pdf14_clist_Gray_device = {
9861
    std_device_color_stype_body(pdf14_clist_device,
9862
                                pdf14_clist_Gray_initialize_device_procs,
9863
                                "pdf14clistgray",
9864
                                &st_pdf14_device,
9865
                                XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256),
9866
    { 0 },      /* Procs */
9867
    NULL,     /* target */
9868
    { 0 },      /* devn_params - not used */
9869
    &gray_pdf14_procs,
9870
    &gray_blending_procs
9871
};
9872
9873
const pdf14_clist_device pdf14_clist_RGB_device = {
9874
    std_device_color_stype_body(pdf14_clist_device,
9875
                                pdf14_clist_RGB_initialize_device_procs,
9876
                                "pdf14clistRGB",
9877
                                &st_pdf14_device,
9878
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
9879
    { 0 },      /* Procs */
9880
    NULL,     /* target */
9881
    { 0 },      /* devn_params - not used */
9882
    &rgb_pdf14_procs,
9883
    &rgb_blending_procs
9884
};
9885
9886
const pdf14_clist_device pdf14_clist_CMYK_device = {
9887
    std_device_std_color_full_body_type(pdf14_clist_device,
9888
                                        pdf14_clist_CMYK_initialize_device_procs,
9889
                                        "pdf14clistcmyk",
9890
                                        &st_pdf14_device,
9891
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
9892
                                        0, 0, 0, 0, 0, 0),
9893
    { 0 },      /* Procs */
9894
    NULL,     /* target */
9895
    { 0 },      /* devn_params - not used */
9896
    &cmyk_pdf14_procs,
9897
    &cmyk_blending_procs
9898
};
9899
9900
const pdf14_clist_device pdf14_clist_CMYKspot_device = {
9901
    std_device_part1_(pdf14_device,
9902
                      pdf14_clist_CMYKspot_initialize_device_procs,
9903
                      "pdf14clistcmykspot",
9904
                      &st_pdf14_device,
9905
                      open_init_closed),
9906
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
9907
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
9908
    offset_margin_values(0, 0, 0, 0, 0, 0),
9909
    std_device_part3_(),
9910
    { 0 },      /* Procs */
9911
    NULL,     /* target */
9912
    /* DeviceN parameters */
9913
    { 8,      /* Not used - Bits per color */
9914
      DeviceCMYKComponents, /* Names of color model colorants */
9915
      4,      /* Number colorants for CMYK */
9916
      0,      /* MaxSeparations has not been specified */
9917
      -1,     /* PageSpotColors has not been specified */
9918
      {0},      /* SeparationNames */
9919
      0,      /* SeparationOrder names */
9920
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
9921
    },
9922
    &cmykspot_pdf14_procs,
9923
    &cmyk_blending_procs
9924
};
9925
9926
const pdf14_clist_device pdf14_clist_custom_device = {
9927
    std_device_part1_(pdf14_device,
9928
                      pdf14_clist_CMYKspot_initialize_device_procs,
9929
                      "pdf14clistcustom",
9930
                      &st_pdf14_device,
9931
                      open_init_closed),
9932
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
9933
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
9934
    offset_margin_values(0, 0, 0, 0, 0, 0),
9935
    std_device_part3_(),
9936
    { 0 },      /* Procs */
9937
    NULL,     /* target */
9938
    /* DeviceN parameters */
9939
    { 8,      /* Not used - Bits per color */
9940
      DeviceCMYKComponents, /* Names of color model colorants */
9941
      4,      /* Number colorants for CMYK */
9942
      0,      /* MaxSeparations has not been specified */
9943
      -1,     /* PageSpotColors has not been specified */
9944
      {0},      /* SeparationNames */
9945
      0,      /* SeparationOrder names */
9946
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
9947
    },
9948
    &custom_pdf14_procs,
9949
    &custom_blending_procs
9950
};
9951
9952
/*
9953
 * the PDF 1.4 transparency spec says that color space for blending
9954
 * operations can be based upon either a color space specified in the
9955
 * group or a default value based upon the output device.  We are
9956
 * currently only using a color space based upon the device.
9957
 */
9958
static  int
9959
get_pdf14_clist_device_proto(gx_device          *dev,
9960
                             pdf14_clist_device *pdevproto,
9961
                             gs_gstate          *pgs,
9962
                       const gs_pdf14trans_t    *pdf14pct,
9963
                             bool                use_pdf14_accum)
9964
267
{
9965
267
    pdf14_blend_cs_t blend_cs_state;
9966
267
    pdf14_default_colorspace_t dev_cs =
9967
267
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
9968
267
                                                 &blend_cs_state);
9969
267
    bool has_tags = device_encodes_tags(dev);
9970
267
    bool deep = device_is_deep(dev);
9971
267
    int num_spots = pdf14pct->params.num_spot_colors;
9972
9973
    /* overprint overide */
9974
267
    if (pdf14pct->params.overprint_sim_push &&
9975
267
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
9976
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
9977
0
            dev_cs = PDF14_DeviceCMYKspot;
9978
0
            num_spots = pdf14pct->params.num_spot_colors_int;
9979
0
        } else
9980
0
            dev_cs = PDF14_DeviceCMYK;
9981
0
    }
9982
9983
267
    switch (dev_cs) {
9984
0
        case PDF14_DeviceGray:
9985
           /* We want gray to be single channel.  Low level
9986
               initialization of gray device prototype is
9987
               peculiar in that in dci_std_color_num_components
9988
               the comment is
9989
              "A device is monochrome only if it is bi-level"
9990
              Here we want monochrome anytime we have a gray device.
9991
              To avoid breaking things elsewhere, we will overide
9992
              the prototype intialization here */
9993
0
            *pdevproto = pdf14_clist_Gray_device;
9994
0
            pdevproto->color_info.max_components = 1;
9995
0
            pdevproto->color_info.num_components =
9996
0
                                    pdevproto->color_info.max_components;
9997
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
9998
0
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
9999
0
            pdevproto->color_info.dither_grays = pdevproto->color_info.max_gray+1;
10000
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10001
0
            pdevproto->color_info.depth = deep ? 16 : 8;
10002
0
            pdevproto->sep_device = false;
10003
0
            break;
10004
267
        case PDF14_DeviceRGB:
10005
267
            *pdevproto = pdf14_clist_RGB_device;
10006
267
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10007
267
            pdevproto->sep_device = false;
10008
267
            if (deep) {
10009
0
                pdevproto->color_info.depth = 3*16;
10010
0
                pdevproto->color_info.max_color = 65535;
10011
0
                pdevproto->color_info.max_gray = 65535;
10012
0
                pdevproto->color_info.dither_colors = 65536;
10013
0
                pdevproto->color_info.dither_grays = 65536;
10014
0
            }
10015
267
            break;
10016
0
        case PDF14_DeviceCMYK:
10017
0
            *pdevproto = pdf14_clist_CMYK_device;
10018
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10019
0
            pdevproto->sep_device = false;
10020
0
            if (deep) {
10021
0
                pdevproto->color_info.depth = 4*16;
10022
0
                pdevproto->color_info.max_color = 65535;
10023
0
                pdevproto->color_info.max_gray = 65535;
10024
0
                pdevproto->color_info.dither_colors = 65536;
10025
0
                pdevproto->color_info.dither_grays = 65536;
10026
0
            }
10027
0
            break;
10028
0
        case PDF14_DeviceCMYKspot:
10029
0
            *pdevproto = pdf14_clist_CMYKspot_device;
10030
            /*
10031
             * The number of components for the PDF14 device is the sum
10032
             * of the process components and the number of spot colors
10033
             * for the page. If we are using an NCLR ICC profile at
10034
             * the output device, those spot colors are skipped. They
10035
             * do not appear in the transparency buffer, but appear
10036
             * during put image transform of the page group to the target
10037
             * color space.
10038
             */
10039
0
            if (num_spots >= 0) {
10040
0
                pdevproto->devn_params.page_spot_colors = num_spots;
10041
0
                pdevproto->color_info.num_components =
10042
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10043
0
                if (pdevproto->color_info.num_components >
10044
0
                              pdevproto->color_info.max_components)
10045
0
                    pdevproto->color_info.num_components =
10046
0
                              pdevproto->color_info.max_components;
10047
0
                pdevproto->color_info.depth =
10048
0
                              pdevproto->color_info.num_components * (8<<deep);
10049
0
                if (deep && has_tags)
10050
0
                    pdevproto->color_info.depth -= 8;
10051
0
            }
10052
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10053
0
            pdevproto->sep_device = true;
10054
0
            break;
10055
0
        case PDF14_DeviceCustom:
10056
            /*
10057
             * We are using the output device's process color model.  The
10058
             * color_info for the PDF 1.4 compositing device needs to match
10059
             * the output device.
10060
             */
10061
0
            *pdevproto = pdf14_clist_custom_device;
10062
0
            pdevproto->color_info = dev->color_info;
10063
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
10064
0
            pdevproto->color_info.depth =
10065
0
                pdevproto->color_info.num_components * (8<<deep);
10066
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10067
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
10068
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
10069
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
10070
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10071
0
            break;
10072
0
        default:      /* Should not occur */
10073
0
            return_error(gs_error_rangecheck);
10074
267
    }
10075
267
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
10076
267
    pdevproto->blend_cs_state = blend_cs_state;
10077
267
    return 0;
10078
267
}
10079
10080
static  int
10081
pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10082
                                gx_device ** ppdev, gx_device * target,
10083
                                const gs_pdf14trans_t * pdf14pct)
10084
267
{
10085
267
    pdf14_clist_device dev_proto;
10086
267
    pdf14_clist_device * pdev;
10087
267
    int code;
10088
267
    bool has_tags = device_encodes_tags(target);
10089
267
    cmm_profile_t *target_profile;
10090
267
    gsicc_rendering_param_t render_cond;
10091
267
    cmm_dev_profile_t *dev_profile;
10092
267
    uchar k;
10093
267
    bool deep = device_is_deep(target);
10094
267
    cmm_profile_t *icc_profile;
10095
10096
10097
267
    code = dev_proc(target, get_profile)(target,  &dev_profile);
10098
267
    if (code < 0)
10099
0
        return code;
10100
267
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &target_profile,
10101
267
                          &render_cond);
10102
267
    if_debug0m('v', pgs->memory, "[v]pdf14_create_clist_device\n");
10103
267
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10104
267
                                        pgs, pdf14pct, false);
10105
267
    if (code < 0)
10106
0
        return code;
10107
267
    code = gs_copydevice((gx_device **) &pdev,
10108
267
                         (const gx_device *) &dev_proto, mem);
10109
267
    if (code < 0)
10110
0
        return code;
10111
10112
    /* If we are not using a blending color space, the number of color planes
10113
       should not exceed that of the target */
10114
267
    if (!(pdev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || pdev->overprint_sim)) {
10115
267
        if (pdev->color_info.num_components > target->color_info.num_components)
10116
0
            pdev->color_info.num_components = target->color_info.num_components;
10117
267
        if (pdev->color_info.max_components > target->color_info.max_components)
10118
0
            pdev->color_info.max_components = target->color_info.max_components;
10119
267
    }
10120
267
    pdev->color_info.depth = pdev->color_info.num_components * (8<<deep);
10121
267
    pdev->pad = target->pad;
10122
267
    pdev->log2_align_mod = target->log2_align_mod;
10123
10124
267
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && !target->is_planar)
10125
0
        pdev->is_planar = true;
10126
267
    else
10127
267
        pdev->is_planar = target->is_planar;
10128
267
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10129
10130
267
    pdev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
10131
10132
267
    if (deep) {
10133
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
10134
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
10135
0
    }
10136
    /* If we have a tag device then go ahead and do a special encoder decoder
10137
       for the pdf14 device to make sure we maintain this information in the
10138
       encoded color information.  We could use the target device's methods but
10139
       the PDF14 device has to maintain 8 bit color always and we could run
10140
       into other issues if the number of colorants became large.  If we need to
10141
       do compressed color with tags that will be a special project at that time */
10142
267
    if (has_tags) {
10143
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color_tag);
10144
0
        pdev->color_info.comp_shift[pdev->color_info.num_components] = pdev->color_info.depth;
10145
0
        pdev->color_info.depth += 8;
10146
0
    }
10147
267
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;  /* this is the standard */
10148
267
    gx_device_fill_in_procs((gx_device *)pdev);
10149
267
    gs_pdf14_device_copy_params((gx_device *)pdev, target);
10150
267
    gx_device_set_target((gx_device_forward *)pdev, target);
10151
10152
    /* Components shift, etc have to be based upon 8 bit */
10153
1.06k
    for (k = 0; k < pdev->color_info.num_components; k++) {
10154
801
        pdev->color_info.comp_bits[k] = 8<<deep;
10155
801
        pdev->color_info.comp_shift[k] = (pdev->color_info.num_components - 1 - k) * (8<<deep);
10156
801
    }
10157
267
    code = dev_proc((gx_device *) pdev, open_device) ((gx_device *) pdev);
10158
267
    pdev->pclist_device = target;
10159
10160
267
    code = dev_proc(target, get_profile)(target, &dev_profile);
10161
267
    if (code < 0)
10162
0
        return code;
10163
267
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
10164
267
        &render_cond);
10165
267
    if_debug0m('v', mem, "[v]pdf14_create_clist_device\n");
10166
10167
    /* Simulated overprint case.  We have to use CMYK-based profile
10168
       Also if the target profile is NCLR, we are going to use a pdf14
10169
       device that is CMYK based and do the mapping to the NCLR profile
10170
       when the put_image occurs */
10171
267
    if ((pdev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
10172
267
         icc_profile->data_cs == gsNCHANNEL) {
10173
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_create_clist_device");
10174
0
        gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10175
0
            -1, "pdf14_create_clist_device");
10176
0
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
10177
267
    } else {
10178
        /* If the target profile was CIELAB, then overide with default RGB for
10179
           proper blending.  During put_image we will convert from RGB to
10180
           CIELAB */
10181
267
        if ((target_profile->data_cs == gsCIELAB || target_profile->islab) &&
10182
267
            pdev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10183
0
            pdev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
10184
0
            rc_assign(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10185
0
                pgs->icc_manager->default_rgb, "pdf14_create_clist_device");
10186
0
        }
10187
267
    }
10188
10189
267
    if (pdf14pct->params.overprint_sim_push &&
10190
267
        pdf14pct->params.num_spot_colors_int > 0) {
10191
0
        pdev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
10192
0
        pdev->procs.ret_devn_params = pdf14_ret_devn_params;
10193
0
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
10194
0
        pdev->target_support_devn = pdev->icc_struct->supports_devn;
10195
0
        pdev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
10196
0
    }
10197
    /* if the device has separations already defined (by SeparationOrderNames) */
10198
    /* we need to copy them (allocating new names) so the colorants are in the */
10199
    /* same order as the target device.                                        */
10200
267
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0)) {
10201
0
        code = devn_copy_params(target, (gx_device *)pdev);
10202
0
        if (code < 0)
10203
0
            return code;
10204
0
    }
10205
267
    pdev->my_encode_color = dev_proc(pdev, encode_color);
10206
267
    pdev->my_decode_color = dev_proc(pdev, decode_color);
10207
267
    pdev->my_get_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
10208
267
    pdev->my_get_color_comp_index = dev_proc(pdev, get_color_comp_index);
10209
267
    pdev->color_info.separable_and_linear =
10210
267
        target->color_info.separable_and_linear;
10211
267
    *ppdev = (gx_device *) pdev;
10212
267
    return code;
10213
267
}
10214
10215
/*
10216
 * Disable the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10217
 * compositor device is never removed.  (We do not have a remove compositor
10218
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10219
 * routine implements that action.
10220
 */
10221
static  int
10222
pdf14_disable_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10223
                                gx_device * dev)
10224
267
{
10225
267
    gx_device_forward * pdev = (gx_device_forward *)dev;
10226
267
    gx_device * target = pdev->target;
10227
10228
267
    if_debug0m('v', pgs->memory, "[v]pdf14_disable_clist_device\n");
10229
10230
    /*
10231
     * To disable the action of this device, we forward all device
10232
     * procedures to the target except the composite and copy
10233
     * the target's color_info.
10234
     */
10235
267
    dev->color_info = target->color_info;
10236
267
    pdf14_forward_device_procs(dev);
10237
267
    set_dev_proc(dev, composite, pdf14_clist_forward_composite);
10238
267
    return 0;
10239
267
}
10240
10241
/*
10242
 * Recreate the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10243
 * compositor device is never removed.  (We do not have a remove compositor
10244
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10245
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
10246
 * again.
10247
 */
10248
static  int
10249
pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10250
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
10251
0
{
10252
0
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
10253
0
    gx_device * target = pdev->target;
10254
0
    pdf14_clist_device dev_proto;
10255
0
    int code;
10256
10257
0
    if_debug0m('v', pgs->memory, "[v]pdf14_recreate_clist_device\n");
10258
    /*
10259
     * We will not use the entire prototype device but we will set the
10260
     * color related info to match the prototype.
10261
     */
10262
0
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10263
0
                                        pgs, pdf14pct, false);
10264
0
    if (code < 0)
10265
0
        return code;
10266
0
    pdev->color_info = dev_proto.color_info;
10267
0
    pdev->procs = dev_proto.procs;
10268
0
    pdev->pad = target->pad;
10269
0
    pdev->log2_align_mod = target->log2_align_mod;
10270
10271
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && !target->is_planar)
10272
0
        pdev->is_planar = true;
10273
0
    else
10274
0
        pdev->is_planar = target->is_planar;
10275
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10276
10277
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
10278
0
    gx_device_fill_in_procs((gx_device *)pdev);
10279
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
10280
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
10281
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
10282
0
    check_device_separable((gx_device *)pdev);
10283
0
    return code;
10284
0
}
10285
10286
/*
10287
 * devicen params
10288
 */
10289
gs_devn_params *
10290
pdf14_ret_devn_params(gx_device *pdev)
10291
44.6k
{
10292
44.6k
    pdf14_device *p14dev = (pdf14_device *)pdev;
10293
10294
44.6k
    return &(p14dev->devn_params);
10295
44.6k
}
10296
10297
/*
10298
 * devicen params
10299
 */
10300
gs_devn_params *
10301
pdf14_accum_ret_devn_params(gx_device *pdev)
10302
0
{
10303
0
    gx_device_pdf14_accum *p14dev = (gx_device_pdf14_accum *)pdev;
10304
10305
0
    return &(p14dev->devn_params);
10306
0
}
10307
10308
static int
10309
pdf14_accum_get_color_comp_index(gx_device * dev,
10310
    const char * pname, int name_size, int component_type)
10311
0
{
10312
0
    pdf14_device *p14dev = (pdf14_device *)(((gx_device_pdf14_accum *)dev)->save_p14dev);
10313
0
    gx_device *target = p14dev->target;
10314
0
    int colorant_number = devn_get_color_comp_index(dev,
10315
0
                &(((gx_device_pdf14_accum *)dev)->devn_params),
10316
0
                &(((gx_device_pdf14_accum *)dev)->equiv_cmyk_colors),
10317
0
                pname, name_size, component_type, ENABLE_AUTO_SPOT_COLORS);
10318
10319
0
    if (target != NULL)
10320
        /* colorant_number returned here _should_ be the same as from above */
10321
0
        colorant_number = (*dev_proc(target, get_color_comp_index))
10322
0
                              (target, (const char *)pname, name_size, component_type);
10323
0
    return colorant_number;
10324
0
}
10325
10326
/*
10327
 * The following procedures are used to map the standard color spaces into
10328
 * the separation color components for the pdf14_accum device.
10329
 */
10330
static void
10331
pdf14_accum_gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[])
10332
0
{
10333
0
    int * map =
10334
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10335
10336
0
    gray_cs_to_devn_cm(dev, map, gray, out);
10337
0
}
10338
10339
static void
10340
pdf14_accum_rgb_cs_to_cmyk_cm(const gx_device * dev,
10341
    const gs_gstate *pgs, frac r, frac g, frac b, frac out[])
10342
0
{
10343
0
    int * map =
10344
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10345
10346
0
    rgb_cs_to_devn_cm(dev, map, pgs, r, g, b, out);
10347
0
}
10348
10349
static void
10350
pdf14_accum_cmyk_cs_to_cmyk_cm(const gx_device * dev,
10351
    frac c, frac m, frac y, frac k, frac out[])
10352
0
{
10353
0
    const int * map =
10354
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10355
10356
0
    cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out);
10357
0
}
10358
10359
static const gx_cm_color_map_procs pdf14_accum_cm_procs = {
10360
    pdf14_accum_gray_cs_to_cmyk_cm,
10361
    pdf14_accum_rgb_cs_to_cmyk_cm,
10362
    pdf14_accum_cmyk_cs_to_cmyk_cm
10363
};
10364
10365
static const gx_cm_color_map_procs *
10366
pdf14_accum_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev)
10367
0
{
10368
0
    *map_dev = dev;
10369
0
    return &pdf14_accum_cm_procs;
10370
0
}
10371
10372
/*
10373
 *  Device proc for updating the equivalent CMYK color for spot colors.
10374
 */
10375
static int
10376
pdf14_accum_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs, const gs_color_space *pcs)
10377
0
{
10378
0
    gx_device_pdf14_accum *pdev = (gx_device_pdf14_accum *)dev;
10379
0
    gx_device *tdev = ((pdf14_device *)(pdev->save_p14dev))->target;
10380
0
    int code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10381
0
                                              &pdev->equiv_cmyk_colors);
10382
10383
0
    if (code >= 0 && tdev != NULL)
10384
0
        code = dev_proc(tdev, update_spot_equivalent_colors)(tdev, pgs, pcs);
10385
0
    return code;
10386
0
}
10387
10388
/* Used when doing overprint simulation and have spot colors */
10389
static int
10390
pdf14_update_spot_equivalent_colors(gx_device *dev, const gs_gstate *pgs, const gs_color_space *pcs)
10391
0
{
10392
0
    pdf14_device *pdev = (pdf14_device *)dev;
10393
0
    int code;
10394
10395
    /* Make sure we are not All or None */
10396
0
    if (pcs != NULL && pcs->type->index == gs_color_space_index_Separation &&
10397
0
        pcs->params.separation.sep_type != SEP_OTHER)
10398
0
            return 0;
10399
10400
0
    code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10401
0
        &pdev->op_pequiv_cmyk_colors);
10402
0
    return code;
10403
0
}
10404
10405
/*
10406
 * Retrieve a list of spot color names for the PDF14 device.
10407
 */
10408
int
10409
put_param_pdf14_spot_names(gx_device * pdev,
10410
                gs_separations * pseparations, gs_param_list * plist)
10411
0
{
10412
0
    int code, num_spot_colors, i;
10413
0
    gs_param_string str;
10414
10415
    /* Check if the given keyname is present. */
10416
0
    code = param_read_int(plist, PDF14NumSpotColorsParamName,
10417
0
                                                &num_spot_colors);
10418
0
    switch (code) {
10419
0
        default:
10420
0
            param_signal_error(plist, PDF14NumSpotColorsParamName, code);
10421
0
            break;
10422
0
        case 1:
10423
0
            return 0;
10424
0
        case 0:
10425
0
            if (num_spot_colors < 1 ||
10426
0
                num_spot_colors > GX_DEVICE_COLOR_MAX_COMPONENTS)
10427
0
                return_error(gs_error_rangecheck);
10428
0
            for (i = 0; i < num_spot_colors; i++) {
10429
0
                char buff[20];
10430
0
                byte * sep_name;
10431
10432
0
                gs_snprintf(buff, sizeof(buff), "PDF14SpotName_%d", i);
10433
0
                code = param_read_string(plist, buff, &str);
10434
0
                switch (code) {
10435
0
                    default:
10436
0
                        param_signal_error(plist, buff, code);
10437
0
                        break;
10438
0
                    case 0:
10439
0
                        sep_name = gs_alloc_bytes(pdev->memory,
10440
0
                                str.size, "put_param_pdf14_spot_names");
10441
0
                        memcpy(sep_name, str.data, str.size);
10442
0
                        pseparations->names[i].size = str.size;
10443
0
                        pseparations->names[i].data = sep_name;
10444
0
                }
10445
0
            }
10446
0
            pseparations->num_separations = num_spot_colors;
10447
0
            break;
10448
0
    }
10449
0
    return 0;;
10450
0
}
10451
10452
/*
10453
 * This procedure will have information from the PDF 1.4 clist writing
10454
 * clist compositior device.  This is information output the compressed
10455
 * color list info which is needed for the support of spot colors in
10456
 * PDF 1.4 compositing.  This info needs to be passed to the PDF 1.4
10457
 * clist reading compositor.  However this device is not created until
10458
 * the clist is read.  To get this info to that device, we have to
10459
 * temporarily store that info in the output device.  This routine saves
10460
 * that info in the output device.
10461
 */
10462
int
10463
pdf14_put_devn_params(gx_device * pdev, gs_devn_params * pdevn_params,
10464
                                        gs_param_list * plist)
10465
0
{
10466
0
    int code;
10467
0
    code = put_param_pdf14_spot_names(pdev,
10468
0
                       &pdevn_params->pdf14_separations, plist);
10469
0
    return code;
10470
0
}
10471
10472
/*
10473
 * When we are banding, we have two PDF 1.4 compositor devices.  One for
10474
 * when we are creating the clist.  The second is for imaging the data from
10475
 * the clist.  This routine is part of the clist writing PDF 1.4 device.
10476
 * This routine is only called once the PDF 1.4 clist write compositor already
10477
 * exists.
10478
 */
10479
static  int
10480
pdf14_clist_composite(gx_device * dev, gx_device ** pcdev,
10481
    const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem,
10482
    gx_device *cdev)
10483
161k
{
10484
161k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
10485
161k
    int code, is_pdf14_compositor;
10486
161k
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
10487
161k
    bool deep = device_is_deep(dev);
10488
10489
    /* We only handle a few PDF 1.4 transparency operations */
10490
161k
    if ((is_pdf14_compositor = gs_is_pdf14trans_compositor(pct)) != 0) {
10491
161k
        switch (pdf14pct->params.pdf14_op) {
10492
0
            case PDF14_PUSH_DEVICE:
10493
                /* Re-activate the PDF 1.4 compositor */
10494
0
                pdev->saved_target_color_info = pdev->target->color_info;
10495
0
                pdev->target->color_info = pdev->color_info;
10496
0
                pdev->saved_target_encode_color = dev_proc(pdev->target, encode_color);
10497
0
                pdev->saved_target_decode_color = dev_proc(pdev->target, decode_color);
10498
0
                set_dev_proc(pdev->target, encode_color, pdev->my_encode_color);
10499
0
                set_dev_proc(pdev, encode_color, pdev->my_encode_color);
10500
0
                set_dev_proc(pdev->target, decode_color, pdev->my_decode_color);
10501
0
                set_dev_proc(pdev, decode_color, pdev->my_decode_color);
10502
0
                pdev->saved_target_get_color_mapping_procs =
10503
0
                                        dev_proc(pdev->target, get_color_mapping_procs);
10504
0
                pdev->saved_target_get_color_comp_index =
10505
0
                                        dev_proc(pdev->target, get_color_comp_index);
10506
0
                set_dev_proc(pdev->target, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
10507
0
                set_dev_proc(pdev, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
10508
0
                set_dev_proc(pdev->target, get_color_comp_index, pdev->my_get_color_comp_index);
10509
0
                set_dev_proc(pdev, get_color_comp_index, pdev->my_get_color_comp_index);
10510
0
                pdev->save_get_cmap_procs = pgs->get_cmap_procs;
10511
0
                pgs->get_cmap_procs = pdf14_get_cmap_procs;
10512
0
                gx_set_cmap_procs(pgs, dev);
10513
0
                code = pdf14_recreate_clist_device(mem, pgs, dev, pdf14pct);
10514
0
                pdev->blend_mode = pdev->text_knockout = 0;
10515
0
                pdev->opacity = pdev->shape = 0.0;
10516
0
                if (code < 0)
10517
0
                    return code;
10518
                /*
10519
                 * This routine is part of the PDF 1.4 clist write device.
10520
                 * Change the compositor procs to not create another since we
10521
                 * do not need to create a chain of identical devices.
10522
                 */
10523
0
                {
10524
0
                    gs_pdf14trans_t pctemp = *pdf14pct;
10525
10526
0
                    pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type;
10527
0
                    code = dev_proc(pdev->target, composite)
10528
0
                                (pdev->target, pcdev, (gs_composite_t *)&pctemp, pgs, mem, cdev);
10529
                    /* We should never have created a new device here. */
10530
0
                    assert(code != 1);
10531
0
                    return code;
10532
0
                }
10533
267
            case PDF14_POP_DEVICE:
10534
267
            {
10535
267
                gx_device *clistdev = pdev->target;
10536
10537
                /* Find the clist device */
10538
267
                while (1) {
10539
267
                    gxdso_device_child_request req;
10540
                    /* Ignore any errors here, that's expected as non-clist
10541
                     * devices don't implement it. */
10542
267
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_is_clist_device, NULL, 0);
10543
267
                    if (code == 1)
10544
267
                        break;
10545
0
                    req.n = 0;
10546
0
                    req.target = clistdev;
10547
0
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_device_child, &req, sizeof(req));
10548
0
                    if (code < 0)
10549
0
                        return code;
10550
0
                    clistdev = req.target;
10551
0
                }
10552
10553
                /* If we have overprint simulation spot color information, store
10554
                   it in a pseudo-band of the clist */
10555
267
                if (pdev->overprint_sim &&
10556
267
                    pdev->devn_params.page_spot_colors > 0) {
10557
0
                    code = clist_write_op_equiv_cmyk_colors((gx_device_clist_writer *)clistdev,
10558
0
                        &pdev->op_pequiv_cmyk_colors);
10559
0
                    if (code < 0)
10560
0
                        return code;
10561
0
                }
10562
10563
                /* If we hit an error during an SMask, we need to undo the color
10564
                 * swapping before continuing. pdf14_decrement_smask_color() checks
10565
                 * for itself if it needs to take action.
10566
                 */
10567
267
                pdf14_decrement_smask_color(pgs, dev);
10568
                /* Restore the color_info for the clist device */
10569
267
                clistdev->color_info = pdev->saved_target_color_info;
10570
267
                ((gx_device_clist_writer*)clistdev)->clist_color_info = clistdev->color_info; /* also reset for writer */
10571
267
                set_dev_proc(clistdev, encode_color, pdev->saved_target_encode_color);
10572
267
                set_dev_proc(clistdev, decode_color, pdev->saved_target_decode_color);
10573
267
                set_dev_proc(clistdev, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs);
10574
267
                set_dev_proc(clistdev, get_color_comp_index, pdev->saved_target_get_color_comp_index);
10575
267
                pgs->get_cmap_procs = pdev->save_get_cmap_procs;
10576
267
                gx_set_cmap_procs(pgs, clistdev);
10577
267
                gx_device_decache_colors(clistdev);
10578
                /* Disable the PDF 1.4 compositor */
10579
267
                pdf14_disable_clist_device(mem, pgs, dev);
10580
                /*
10581
                 * Make sure that the transfer funtions, etc. are current.
10582
                 */
10583
267
                code = cmd_put_color_mapping((gx_device_clist_writer *)clistdev, pgs);
10584
267
                if (code < 0)
10585
2
                    return code;
10586
265
                break;
10587
267
            }
10588
265
            case PDF14_BEGIN_TRANS_PAGE_GROUP:
10589
2.56k
            case PDF14_BEGIN_TRANS_GROUP:
10590
2.56k
                if (pdev->smask_constructed || pdev->depth_within_smask)
10591
1.32k
                    pdev->depth_within_smask++;
10592
2.56k
                pdev->smask_constructed = 0;
10593
                /*
10594
                 * Keep track of any changes made in the blending parameters.
10595
                   These need to be written out in the same bands as the group
10596
                   information is written.  Hence the passing of the dimensions
10597
                   for the group. */
10598
2.56k
                code = pdf14_clist_update_params(pdev, pgs, true,
10599
2.56k
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
10600
2.56k
                if (code < 0)
10601
0
                    return code;
10602
2.56k
                if (pdf14pct->params.Background_components != 0 &&
10603
2.56k
                    pdf14pct->params.Background_components !=
10604
0
                    pdev->color_info.num_components)
10605
0
                    return_error(gs_error_rangecheck);
10606
10607
                /* We need to update the clist writer device procs based upon the
10608
                   the group color space. This ensures the proper color data is
10609
                   written out to the device. For simplicity, the list item is
10610
                   created even if the color space did not change */
10611
2.56k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, false);
10612
2.56k
                if (code < 0)
10613
0
                    return code;
10614
10615
2.56k
                break;
10616
2.63k
            case PDF14_BEGIN_TRANS_MASK:
10617
                /* We need to update the clist writer device procs based upon the
10618
                   the group color space.  For simplicity, the list item is created
10619
                   even if the color space did not change */
10620
                /* First store the current ones */
10621
2.63k
                if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
10622
1.30k
                    break;
10623
10624
                /* Update the color settings of the clist writer.  Store information in stack */
10625
1.33k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, true);
10626
1.33k
                if (code < 0)
10627
0
                    return code;
10628
10629
                /* Also, if the BC is a value that may end up as something other
10630
                  than transparent. We must use the parent colors bounding box in
10631
                  determining the range of bands in which this mask can affect.
10632
                  So, if needed change the masks bounding box at this time */
10633
1.33k
                pdev->in_smask_construction++;
10634
1.33k
                break;
10635
61.9k
            case PDF14_BEGIN_TRANS_TEXT_GROUP:
10636
61.9k
                if (pdev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
10637
72
                    emprintf(pdev->memory, "Warning: Text group pushed but no ET found\n");
10638
72
                    pdev->text_group = PDF14_TEXTGROUP_MISSING_ET;
10639
72
                } else
10640
61.8k
                    pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
10641
61.9k
                *pcdev = dev;
10642
61.9k
                return 0; /* Never put into clist. Only used during writing */
10643
86.0k
            case PDF14_END_TRANS_TEXT_GROUP:
10644
86.0k
                if (pdev->text_group != PDF14_TEXTGROUP_BT_PUSHED) {
10645
85.8k
                    *pcdev = dev;
10646
85.8k
                    return 0; /* Avoids spurious ET calls in interpreter */
10647
85.8k
                }
10648
155
                pdev->text_group = PDF14_TEXTGROUP_NO_BT; /* These can't be nested */
10649
155
                code = pdf14_clist_pop_color_model(dev, pgs);
10650
155
                if (code < 0)
10651
0
                    return code;
10652
155
                break;
10653
1.33k
            case PDF14_END_TRANS_MASK:
10654
1.33k
                pdev->in_smask_construction--;
10655
1.33k
                if (pdev->in_smask_construction < 0)
10656
0
                    pdev->in_smask_construction = 0;
10657
1.33k
                if (pdev->in_smask_construction == 0)
10658
1.32k
                    pdev->smask_constructed = 1;
10659
                /* fallthrough */
10660
3.72k
            case PDF14_END_TRANS_GROUP:
10661
                /* We need to update the clist writer device procs based upon the
10662
                   the group color space. */
10663
3.72k
                code = pdf14_clist_pop_color_model(dev, pgs);
10664
3.72k
                if (pdev->depth_within_smask)
10665
1.32k
                    pdev->depth_within_smask--;
10666
3.72k
                if (code < 0)
10667
0
                    return code;
10668
3.72k
                break;
10669
3.72k
            case PDF14_PUSH_TRANS_STATE:
10670
0
                break;
10671
1.31k
            case PDF14_POP_TRANS_STATE:
10672
1.31k
                break;
10673
1.33k
            case PDF14_PUSH_SMASK_COLOR:
10674
1.33k
                code = pdf14_increment_smask_color(pgs,dev);
10675
1.33k
                *pcdev = dev;
10676
1.33k
                return code;  /* Note, this are NOT put in the clist */
10677
0
                break;
10678
1.33k
            case PDF14_POP_SMASK_COLOR:
10679
1.33k
                code = pdf14_decrement_smask_color(pgs,dev);
10680
1.33k
                *pcdev = dev;
10681
1.33k
                return code;  /* Note, this are NOT put in the clist */
10682
0
                break;
10683
0
            case PDF14_SET_BLEND_PARAMS:
10684
                /* If there is a change we go ahead and apply it to the target */
10685
0
                code = pdf14_clist_update_params(pdev, pgs, false,
10686
0
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
10687
0
                *pcdev = dev;
10688
0
                return code;
10689
0
                break;
10690
0
            case PDF14_ABORT_DEVICE:
10691
0
                code = gx_abort_trans_device(pgs, dev);
10692
0
                if (pdev->free_devicen) {
10693
0
                    devn_free_params(dev);
10694
0
                }
10695
0
                pdf14_disable_device(dev);
10696
0
                pdf14_close(dev);
10697
0
                *pcdev = dev;
10698
0
                return code;
10699
0
                break;
10700
0
            default:
10701
0
                break;   /* Pass remaining ops to target */
10702
161k
        }
10703
161k
    }
10704
10.6k
    code = dev_proc(pdev->target, composite)
10705
10.6k
                        (pdev->target, pcdev, pct, pgs, mem, cdev);
10706
    /* If we were accumulating into a pdf14-clist-accum device, */
10707
    /* we now have to render the page into it's target device */
10708
10.6k
    if (is_pdf14_compositor && pdf14pct->params.pdf14_op == PDF14_POP_DEVICE &&
10709
10.6k
        pdev->target->stype == &st_gx_devn_accum_device) {
10710
10711
0
        int i, y, rows_used;
10712
0
        byte *linebuf;
10713
0
        byte *actual_data;
10714
0
        gx_device_pdf14_accum *tdev = (gx_device_pdf14_accum *)(pdev->target);     /* the printer class clist device used to accumulate */
10715
        /* get the target device we want to send the image to */
10716
0
        gx_device *target = ((pdf14_device *)(tdev->save_p14dev))->target;
10717
0
        gs_image1_t image;
10718
0
        gs_color_space *pcs;
10719
0
        gx_image_enum_common_t *info;
10720
0
        gx_image_plane_t planes;
10721
0
        gsicc_rendering_param_t render_cond;
10722
0
        cmm_dev_profile_t *dev_profile;
10723
0
        bool save_planar = pdev->is_planar;
10724
0
        gs_devn_params *target_devn_params = dev_proc(target, ret_devn_params)(target);
10725
0
        int save_num_separations;
10726
0
        gs_int_rect rect;
10727
10728
0
        pdev->is_planar = false;   /* so gx_device_raster is for entire chunky pixel line */
10729
0
        linebuf = gs_alloc_bytes(mem, gx_device_raster((gx_device *)pdev, true), "pdf14-clist_accum pop dev");
10730
0
        pdev->is_planar = save_planar;
10731
10732
        /* As long as we don't have spot colors, we can use ICC colorspace, but spot
10733
         * colors do require devn support
10734
         */
10735
0
        if (tdev->color_info.num_components <= 4 ||
10736
0
             dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) <= 0) {
10737
            /*
10738
             * Set color space in preparation for sending an image.
10739
             */
10740
0
            code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
10741
0
            if (code < 0)
10742
0
                goto put_accum_error;
10743
10744
            /* Need to set this to avoid color management during the
10745
               image color render operation.  Exception is for the special case
10746
               when the destination was CIELAB.  Then we need to convert from
10747
               default RGB to CIELAB in the put image operation.  That will happen
10748
               here as we should have set the profile for the pdf14 device to RGB
10749
               and the target will be CIELAB */
10750
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
10751
0
            if (code < 0)
10752
0
                goto put_accum_error;
10753
0
            gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile,
10754
0
                                  &(pcs->cmm_icc_profile_data), &render_cond);
10755
            /* pcs takes a reference to the profile data it just retrieved. */
10756
0
            gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_clist_composite");
10757
0
            gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
10758
0
        } else {
10759
             /* DeviceN case -- need to handle spot colors */
10760
0
            code = gs_cspace_new_DeviceN(&pcs, tdev->color_info.num_components,
10761
0
                                         gs_currentcolorspace(pgs), pgs->memory);
10762
0
            if (code < 0)
10763
0
                goto put_accum_error;
10764
            /* set up a usable DeviceN space with info from the tdev->devn_params */
10765
0
            pcs->params.device_n.use_alt_cspace = false;
10766
10767
0
            if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
10768
0
                goto put_accum_error;
10769
0
            }
10770
            /* One last thing -- we need to fudge the pgs->color_component_map */
10771
0
            for (i=0; i < tdev->color_info.num_components; i++)
10772
0
                pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
10773
            /* copy devn_params that were accumulated into the target device's devn_params */
10774
0
            target_devn_params->bitspercomponent = tdev->devn_params.bitspercomponent;
10775
0
            target_devn_params->std_colorant_names = tdev->devn_params.std_colorant_names;
10776
0
            target_devn_params->num_std_colorant_names = tdev->devn_params.num_std_colorant_names;
10777
0
            target_devn_params->max_separations = tdev->devn_params.max_separations;
10778
0
            target_devn_params->page_spot_colors = tdev->devn_params.page_spot_colors;
10779
0
            target_devn_params->num_separation_order_names = tdev->devn_params.num_separation_order_names;
10780
0
            target_devn_params->separations = tdev->devn_params.separations;
10781
0
            memcpy(target_devn_params->separation_order_map, tdev->devn_params.separation_order_map,
10782
0
                   sizeof(gs_separation_map));
10783
0
            target_devn_params->pdf14_separations = tdev->devn_params.pdf14_separations;
10784
0
        }
10785
0
        if (linebuf == NULL) {
10786
0
            code = gs_error_VMerror;
10787
0
            goto put_accum_error;
10788
0
        }
10789
0
        gs_image_t_init_adjust(&image, pcs, false);
10790
0
        image.ImageMatrix.xx = (float)pdev->width;
10791
0
        image.ImageMatrix.yy = (float)pdev->height;
10792
0
        image.Width = pdev->width;
10793
0
        image.Height = pdev->height;
10794
0
        image.BitsPerComponent = 8<<deep;
10795
0
        ctm_only_writable(pgs).xx = (float)pdev->width;
10796
0
        ctm_only_writable(pgs).xy = 0;
10797
0
        ctm_only_writable(pgs).yx = 0;
10798
0
        ctm_only_writable(pgs).yy = (float)pdev->height;
10799
0
        ctm_only_writable(pgs).tx = 0.0;
10800
0
        ctm_only_writable(pgs).ty = 0.0;
10801
0
        code = dev_proc(target, begin_typed_image) (target,
10802
0
                                                    pgs, NULL,
10803
0
                                                    (gs_image_common_t *)&image,
10804
0
                                                    NULL, NULL, NULL,
10805
0
                                                    pgs->memory, &info);
10806
0
        if (code < 0)
10807
0
            goto put_accum_error;
10808
0
        rect.p.x = 0;
10809
0
        rect.q.x = tdev->width;
10810
0
        for (y=0; y < tdev->height; y++) {
10811
0
            gs_get_bits_params_t params;
10812
10813
0
            params.options = (GB_ALIGN_ANY |
10814
0
                              (GB_RETURN_COPY | GB_RETURN_POINTER) |
10815
0
                              GB_OFFSET_0 |
10816
0
                              GB_RASTER_STANDARD | GB_PACKING_CHUNKY |
10817
0
                              GB_COLORS_NATIVE | GB_ALPHA_NONE);
10818
0
            params.x_offset = 0;
10819
0
            params.raster = bitmap_raster(dev->width * dev->color_info.depth);
10820
0
            params.data[0] = linebuf;
10821
0
            rect.p.y = y;
10822
0
            rect.q.y = y+1;
10823
0
            code = dev_proc(tdev, get_bits_rectangle)((gx_device *)tdev,
10824
0
                                                      &rect, &params);
10825
0
            if (code < 0)
10826
0
                goto put_accum_error;
10827
0
            actual_data = params.data[0];
10828
0
            planes.data = actual_data;
10829
0
            planes.data_x = 0;
10830
0
            planes.raster = tdev->width * tdev->color_info.num_components;
10831
0
            if ((code = info->procs->plane_data(info, &planes, 1, &rows_used)) < 0)
10832
0
                goto put_accum_error;
10833
0
        }
10834
0
        code = info->procs->end_image(info, true);
10835
10836
0
put_accum_error:
10837
0
        gs_free_object(pdev->memory, linebuf, "pdf14_put_image");
10838
        /* This will also decrement the device profile */
10839
0
        rc_decrement_only_cs(pcs, "pdf14_put_image");
10840
0
        dev_proc(tdev, close_device)((gx_device *)tdev);  /* frees the prn_device memory */
10841
        /* Now unhook the clist device and hook to the original so we can clean up */
10842
0
        gx_device_set_target((gx_device_forward *)pdev,
10843
0
                             ((gx_device_pdf14_accum *)(pdev->target))->save_p14dev);
10844
0
        pdev->pclist_device = pdev->target;
10845
0
        *pcdev = pdev->target;          /* pass upwards to switch devices */
10846
0
        pdev->color_info = target->color_info;      /* same as in pdf14_disable_clist */
10847
0
        if (target_devn_params != NULL) {
10848
            /* prevent devn_free_params from freeing names still in use by target device */
10849
0
            save_num_separations = tdev->devn_params.separations.num_separations;
10850
0
            tdev->devn_params.separations.num_separations = 0;
10851
0
        }
10852
0
        gs_free_object(tdev->memory, tdev, "popdevice pdf14-accum");
10853
0
        if (target_devn_params != NULL) {
10854
0
            target_devn_params->separations.num_separations = save_num_separations;
10855
0
        }
10856
0
        return code;    /* DON'T perform set_target */
10857
0
    }
10858
10.6k
    if (code == 1) {
10859
        /* We just wrapped pdev->target, so we need to update that.*/
10860
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
10861
0
        code = 0; /* We did not wrap dev. */
10862
0
    }
10863
10.6k
    *pcdev = dev;
10864
10.6k
    return code;
10865
10.6k
}
10866
10867
/*
10868
 * The PDF 1.4 clist compositor is never removed.  (We do not have a 'remove
10869
 * compositor' method.  However the compositor is disabled when we are not
10870
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
10871
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
10872
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
10873
 * to the targer.
10874
 */
10875
static  int
10876
pdf14_clist_forward_composite(gx_device * dev, gx_device * * pcdev,
10877
        const gs_composite_t * pct, gs_gstate * pgs,
10878
        gs_memory_t * mem, gx_device *cdev)
10879
0
{
10880
0
    pdf14_device *pdev = (pdf14_device *)dev;
10881
0
    gx_device * tdev = pdev->target;
10882
0
    gx_device * ndev;
10883
0
    int code;
10884
10885
0
    *pcdev = dev;
10886
0
    if (gs_is_pdf14trans_compositor(pct)) {
10887
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
10888
10889
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
10890
0
            return pdf14_clist_composite(dev, &ndev, pct, pgs, mem, cdev);
10891
0
        return 0;
10892
0
    }
10893
0
    code = dev_proc(tdev, composite)(tdev, &ndev, pct, pgs, mem, cdev);
10894
0
    if (code == 1) {
10895
        /* We just wrapped tdev, so update our target. */
10896
0
        gx_device_set_target((gx_device_forward *)pdev, ndev);
10897
0
        code = 0; /* We did not wrap dev. */
10898
0
    }
10899
0
    return code;
10900
0
}
10901
10902
/*
10903
 * If any of the PDF 1.4 transparency blending parameters have changed, we
10904
 * need to send them to the PDF 1.4 compositor on the output side of the clist.
10905
 */
10906
static  int
10907
pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs,
10908
                          bool crop_blend_params,
10909
                          gs_pdf14trans_params_t *group_params)
10910
222k
{
10911
222k
    gs_pdf14trans_params_t params = { 0 };
10912
222k
    gx_device * pcdev;
10913
222k
    int changed = 0;
10914
222k
    int code = 0;
10915
222k
    gs_composite_t *pct_new = NULL;
10916
10917
222k
    params.crop_blend_params = crop_blend_params;
10918
10919
222k
    params.pdf14_op = PDF14_SET_BLEND_PARAMS;
10920
222k
    if (pgs->blend_mode != pdev->blend_mode) {
10921
27
        changed |= PDF14_SET_BLEND_MODE;
10922
27
        params.blend_mode = pdev->blend_mode = pgs->blend_mode;
10923
27
    }
10924
222k
    if (pgs->text_knockout != pdev->text_knockout) {
10925
267
        changed |= PDF14_SET_TEXT_KNOCKOUT;
10926
267
        params.text_knockout = pdev->text_knockout = pgs->text_knockout;
10927
267
    }
10928
222k
    if (pgs->alphaisshape != pdev->ais) {
10929
116
        changed |= PDF14_SET_AIS;
10930
116
        params.ais = pdev->ais = pgs->alphaisshape;
10931
116
    }
10932
222k
    if (pgs->overprint != pdev->overprint) {
10933
28
        changed |= PDF14_SET_OVERPRINT;
10934
28
        params.overprint = pdev->overprint = pgs->overprint;
10935
28
    }
10936
222k
    if (pgs->stroke_overprint != pdev->stroke_overprint) {
10937
28
        changed |= PDF14_SET_STROKEOVERPRINT;
10938
28
        params.stroke_overprint = pdev->stroke_overprint = pgs->stroke_overprint;
10939
28
    }
10940
222k
    if (pgs->fillconstantalpha != pdev->fillconstantalpha) {
10941
2.37k
        changed |= PDF14_SET_FILLCONSTANTALPHA;
10942
2.37k
        params.fillconstantalpha = pdev->fillconstantalpha = pgs->fillconstantalpha;
10943
2.37k
    }
10944
222k
    if (pgs->strokeconstantalpha != pdev->strokeconstantalpha) {
10945
1.91k
        changed |= PDF14_SET_STROKECONSTANTALPHA;
10946
1.91k
        params.strokeconstantalpha = pdev->strokeconstantalpha = pgs->strokeconstantalpha;
10947
1.91k
    }
10948
222k
    if ((pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_FILL)) {
10949
6.58k
        changed |= PDF_SET_FILLSTROKE_STATE;
10950
6.58k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_FILL;
10951
6.58k
    }
10952
222k
    if ((!pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_STROKE)) {
10953
6.60k
        changed |= PDF_SET_FILLSTROKE_STATE;
10954
6.60k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_STROKE;
10955
6.60k
    }
10956
222k
    if (crop_blend_params) {
10957
2.56k
        params.ctm = group_params->ctm;
10958
2.56k
        params.bbox = group_params->bbox;
10959
2.56k
    }
10960
222k
    params.changed = changed;
10961
    /* Avoid recursion when we have a PDF14_SET_BLEND_PARAMS forced and apply
10962
       now to the target.  Otherwise we send the compositor action
10963
       to the pdf14 device at this time.  This is due to the fact that we
10964
       need to often perform this operation when we are already starting to
10965
       do a compositor action */
10966
222k
    if (changed != 0) {
10967
15.5k
        code = gs_create_pdf14trans(&pct_new, &params, pgs->memory);
10968
15.5k
        if (code < 0)
10969
0
            return code;
10970
15.5k
        code = dev_proc(pdev->target, composite)
10971
15.5k
                    (pdev->target, &pcdev, pct_new, (gs_gstate *)pgs, pgs->memory, NULL);
10972
15.5k
        gs_free_object(pgs->memory, pct_new, "pdf14_clist_update_params");
10973
15.5k
    }
10974
222k
    return code;
10975
222k
}
10976
10977
/*
10978
 * fill_path routine for the PDF 1.4 transaprency compositor device for
10979
 * writing the clist.
10980
 */
10981
static  int
10982
pdf14_clist_fill_path(gx_device *dev, const gs_gstate *pgs,
10983
                           gx_path *ppath, const gx_fill_params *params,
10984
                           const gx_drawing_color *pdcolor,
10985
                           const gx_clip_path *pcpath)
10986
35.6k
{
10987
35.6k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
10988
35.6k
    gs_gstate new_pgs = *pgs;
10989
35.6k
    int code;
10990
35.6k
    gs_pattern2_instance_t *pinst = NULL;
10991
35.6k
    gx_device_forward * fdev = (gx_device_forward *)dev;
10992
35.6k
    cmm_dev_profile_t *dev_profile, *fwd_profile;
10993
35.6k
    gsicc_rendering_param_t render_cond;
10994
35.6k
    cmm_profile_t *icc_profile_fwd, *icc_profile_dev;
10995
35.6k
    int push_group = 0;
10996
10997
35.6k
    code = dev_proc(dev, get_profile)(dev,  &dev_profile);
10998
35.6k
    if (code < 0)
10999
0
        return code;
11000
35.6k
    code = dev_proc(fdev->target, get_profile)(fdev->target,  &fwd_profile);
11001
35.6k
    if (code < 0)
11002
0
        return code;
11003
11004
35.6k
    if (dev->color_info.separable_and_linear == GX_CINFO_UNKNOWN_SEP_LIN)
11005
0
        check_device_separable(dev);
11006
11007
35.6k
    gsicc_extract_profile(GS_UNKNOWN_TAG, fwd_profile, &icc_profile_fwd,
11008
35.6k
                          &render_cond);
11009
35.6k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile_dev,
11010
35.6k
                          &render_cond);
11011
11012
    /*
11013
     * Ensure that that the PDF 1.4 reading compositor will have the current
11014
     * blending parameters.  This is needed since the fill_rectangle routines
11015
     * do not have access to the gs_gstate.  Thus we have to pass any
11016
     * changes explictly.
11017
     */
11018
35.6k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11019
35.6k
    if (code < 0)
11020
0
        return code;
11021
    /* If we are doing a shading fill and we are in a transparency group of a
11022
       different color space, then we do not want to do the shading in the
11023
       device color space. It must occur in the source space.  To handle it in
11024
       the device space would require knowing all the nested transparency group
11025
       color space as well as the transparency.  Some of the shading code ignores
11026
       this, so we have to pass on the clist_writer device to enable proper
11027
       mapping to the transparency group color space. */
11028
11029
35.6k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11030
        /* Non-idempotent blends require a transparency
11031
         * group to be pushed because shadings might
11032
         * paint several pixels twice. */
11033
5.95k
        push_group = pgs->fillconstantalpha != 1.0 ||
11034
5.95k
               !blend_is_idempotent(gs_currentblendmode(pgs));
11035
5.95k
        pinst =
11036
5.95k
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11037
5.95k
           pinst->saved->has_transparency = true;
11038
           /* The transparency color space operations are driven by the pdf14
11039
              clist writer device.  */
11040
5.95k
           pinst->saved->trans_device = dev;
11041
5.95k
    }
11042
35.6k
    if (push_group) {
11043
98
        gs_fixed_rect box;
11044
98
        gs_fixed_rect dev_bbox;
11045
11046
98
        if (pcpath) {
11047
98
            gx_cpath_outer_box(pcpath, &box);
11048
98
            (*dev_proc(dev, get_clipping_box)) (dev, &dev_bbox);
11049
98
            rect_intersect(box, dev_bbox);
11050
98
        } else
11051
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11052
11053
98
        if (ppath) {
11054
0
            gs_fixed_rect path_box;
11055
11056
0
            gx_path_bbox(ppath, &path_box);
11057
0
            if (box.p.x < path_box.p.x)
11058
0
                box.p.x = path_box.p.x;
11059
0
            if (box.p.y < path_box.p.y)
11060
0
                box.p.y = path_box.p.y;
11061
0
            if (box.q.x > path_box.q.x)
11062
0
                box.q.x = path_box.q.x;
11063
0
            if (box.q.y > path_box.q.y)
11064
0
                box.q.y = path_box.q.y;
11065
0
        }
11066
11067
98
        if (box.p.y >= box.q.y || box.p.x >= box.q.x) {
11068
            /* No need to do anything */
11069
92
            if (pinst != NULL) {
11070
92
                pinst->saved->trans_device = NULL;
11071
92
            }
11072
92
            return 0;
11073
92
        }
11074
11075
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11076
6
        code = push_shfill_group(pdev, &new_pgs, &box);
11077
6
    } else
11078
35.5k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11079
35.5k
    if (code >= 0) {
11080
35.5k
        new_pgs.trans_device = dev;
11081
35.5k
        new_pgs.has_transparency = true;
11082
35.5k
        if (gx_dc_is_pattern2_color(pdcolor))
11083
5.86k
            code = gx_default_fill_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11084
29.6k
        else
11085
29.6k
            code = gx_forward_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11086
35.5k
        new_pgs.trans_device = NULL;
11087
35.5k
        new_pgs.has_transparency = false;
11088
35.5k
    }
11089
35.5k
    if (code >= 0 && push_group) {
11090
6
        code = pop_shfill_group(&new_pgs);
11091
6
        if (code >= 0)
11092
6
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11093
6
    }
11094
35.5k
    if (pinst != NULL){
11095
5.86k
        pinst->saved->trans_device = NULL;
11096
5.86k
    }
11097
35.5k
    return code;
11098
35.6k
}
11099
11100
/*
11101
 * stroke_path routine for the PDF 1.4 transparency compositor device for
11102
 * writing the clist.
11103
 */
11104
static  int
11105
pdf14_clist_stroke_path(gx_device *dev, const gs_gstate *pgs,
11106
                             gx_path *ppath, const gx_stroke_params *params,
11107
                             const gx_drawing_color *pdcolor,
11108
                             const gx_clip_path *pcpath)
11109
25.9k
{
11110
25.9k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11111
25.9k
    gs_gstate new_pgs = *pgs;
11112
25.9k
    int code = 0;
11113
25.9k
    gs_pattern2_instance_t *pinst = NULL;
11114
25.9k
    int push_group = 0;
11115
11116
    /*
11117
     * Ensure that that the PDF 1.4 reading compositor will have the current
11118
     * blending parameters.  This is needed since the fill_rectangle routines
11119
     * do not have access to the gs_gstate.  Thus we have to pass any
11120
     * changes explictly.
11121
     */
11122
25.9k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11123
25.9k
    if (code < 0)
11124
0
        return code;
11125
    /* If we are doing a shading stroke and we are in a transparency group of a
11126
       different color space, then we need to get the proper device information
11127
       passed along so that we use the correct color procs and colorinfo about
11128
       the transparency device and not the final target device */
11129
25.9k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11130
        /* Non-idempotent blends require a transparency
11131
         * group to be pushed because shadings might
11132
         * paint several pixels twice. */
11133
13
        push_group = pgs->strokeconstantalpha != 1.0 ||
11134
13
               !blend_is_idempotent(gs_currentblendmode(pgs));
11135
13
        if (pdev->color_model_stack != NULL) {
11136
13
            pinst =
11137
13
                (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11138
13
            pinst->saved->has_transparency = true;
11139
            /* The transparency color space operations are driven
11140
              by the pdf14 clist writer device.  */
11141
13
            pinst->saved->trans_device = dev;
11142
13
        }
11143
13
    }
11144
25.9k
    if (push_group) {
11145
0
        gs_fixed_rect box;
11146
0
        if (pcpath)
11147
0
            gx_cpath_outer_box(pcpath, &box);
11148
0
        else
11149
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11150
0
        if (ppath) {
11151
0
            gs_fixed_rect path_box;
11152
0
            gs_fixed_point expansion;
11153
11154
0
            gx_path_bbox(ppath, &path_box);
11155
            /* Expand the path bounding box by the scaled line width. */
11156
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
11157
                /* The expansion is so large it caused a limitcheck. */
11158
0
                path_box.p.x = path_box.p.y = min_fixed;
11159
0
                path_box.q.x = path_box.q.y = max_fixed;
11160
0
            } else {
11161
0
                expansion.x += pgs->fill_adjust.x;
11162
0
                expansion.y += pgs->fill_adjust.y;
11163
                /*
11164
                 * It's theoretically possible for the following computations to
11165
                 * overflow, so we need to check for this.
11166
                 */
11167
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
11168
0
                                path_box.p.x - expansion.x);
11169
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
11170
0
                                path_box.p.y - expansion.y);
11171
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
11172
0
                                path_box.q.x + expansion.x);
11173
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
11174
0
                                path_box.q.y + expansion.y);
11175
0
            }
11176
0
            if (box.p.x < path_box.p.x)
11177
0
                box.p.x = path_box.p.x;
11178
0
            if (box.p.y < path_box.p.y)
11179
0
                box.p.y = path_box.p.y;
11180
0
            if (box.q.x > path_box.q.x)
11181
0
                box.q.x = path_box.q.x;
11182
0
            if (box.q.y > path_box.q.y)
11183
0
                box.q.y = path_box.q.y;
11184
0
        }
11185
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11186
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
11187
0
        code = push_shfill_group(pdev, &new_pgs, &box);
11188
0
    } else
11189
25.9k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11190
11191
25.9k
    if (code >= 0) {
11192
25.9k
        new_pgs.trans_device = dev;
11193
25.9k
        new_pgs.has_transparency = true;
11194
25.9k
        if (gx_dc_is_pattern2_color(pdcolor))
11195
13
            code = gx_default_stroke_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11196
25.9k
        else
11197
25.9k
            code = gx_forward_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11198
25.9k
        new_pgs.trans_device = NULL;
11199
25.9k
        new_pgs.has_transparency = false;
11200
25.9k
    }
11201
25.9k
    if (code >= 0 && push_group) {
11202
0
        code = pop_shfill_group(&new_pgs);
11203
0
        if (code >= 0)
11204
0
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11205
0
    }
11206
25.9k
    if (pinst != NULL)
11207
13
        pinst->saved->trans_device = NULL;
11208
25.9k
    return code;
11209
25.9k
}
11210
11211
/* Set up work for doing shading patterns in fill stroke through
11212
   the clist.  We have to do all the dirty work now since we are
11213
   going through the default fill and stroke operations individually */
11214
static int
11215
pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs, gx_path* ppath,
11216
    const gx_fill_params* params_fill, const gx_drawing_color* pdevc_fill,
11217
    const gx_stroke_params* params_stroke, const gx_drawing_color* pdevc_stroke,
11218
    const gx_clip_path* pcpath)
11219
0
{
11220
0
    union {
11221
0
        const gs_gstate *cpgs;
11222
0
        gs_gstate *pgs;
11223
0
    } const_breaker;
11224
0
    gs_gstate *pgs;
11225
0
    int code, code2;
11226
0
    gs_transparency_group_params_t params = { 0 };
11227
0
    gs_fixed_rect clip_bbox;
11228
0
    gs_rect bbox, group_stroke_box;
11229
0
    float fill_alpha;
11230
0
    float stroke_alpha;
11231
0
    gs_blend_mode_t blend_mode;
11232
0
    gs_fixed_rect path_bbox;
11233
0
    int expansion_code;
11234
0
    gs_fixed_point expansion;
11235
11236
    /* Break const just once, neatly */
11237
0
    const_breaker.cpgs = cpgs;
11238
0
    pgs = const_breaker.pgs;
11239
11240
0
    fill_alpha = pgs->fillconstantalpha;
11241
0
    stroke_alpha = pgs->strokeconstantalpha;
11242
0
    blend_mode = pgs->blend_mode;
11243
11244
0
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
11245
0
    if (code < 0 && code != gs_error_unknownerror)
11246
0
        return code;
11247
0
    if (code == gs_error_unknownerror) {
11248
        /* didn't get clip box from gx_curr_fixed_bbox */
11249
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
11250
0
        clip_bbox.q.x = int2fixed(dev->width);
11251
0
        clip_bbox.q.y = int2fixed(dev->height);
11252
0
    }
11253
0
    if (pcpath)
11254
0
        rect_intersect(clip_bbox, pcpath->outer_box);
11255
11256
    /* expand the ppath using stroke expansion rule, then intersect it */
11257
0
    code = gx_path_bbox(ppath, &path_bbox);
11258
0
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0)
11259
0
        return 0;   /* ignore empty path */
11260
0
    if (code < 0)
11261
0
        return code;
11262
0
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
11263
0
    if (expansion_code >= 0) {
11264
0
        path_bbox.p.x -= expansion.x;
11265
0
        path_bbox.p.y -= expansion.y;
11266
0
        path_bbox.q.x += expansion.x;
11267
0
        path_bbox.q.y += expansion.y;
11268
0
    }
11269
0
    rect_intersect(path_bbox, clip_bbox);
11270
0
    bbox.p.x = fixed2float(path_bbox.p.x);
11271
0
    bbox.p.y = fixed2float(path_bbox.p.y);
11272
0
    bbox.q.x = fixed2float(path_bbox.q.x);
11273
0
    bbox.q.y = fixed2float(path_bbox.q.y);
11274
11275
0
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
11276
0
    if (code < 0)
11277
0
        return code;
11278
11279
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
11280
0
    if (pgs->fillconstantalpha == pgs->strokeconstantalpha &&
11281
0
        pgs->overprint && pgs->stroke_overprint &&
11282
0
        (dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11283
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
11284
11285
0
        params.Isolated = false;
11286
0
        params.group_color_type = UNKNOWN;
11287
0
        params.Knockout = false;
11288
0
        params.page_group = false;
11289
0
        params.group_opacity = fill_alpha;
11290
0
        params.group_shape = 1.0;
11291
11292
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
11293
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11294
0
        if (code < 0)
11295
0
            return code;
11296
11297
        /* Set alpha to 1.0 and compatible overprint mode for actual drawings */
11298
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11299
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
11300
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11301
11302
0
        code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11303
0
        if (code < 0)
11304
0
            goto cleanup;
11305
11306
0
        code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11307
0
        if (code < 0)
11308
0
            goto cleanup;
11309
11310
0
    } else {
11311
        /* Push a non-isolated knockout group. Do not change the alpha or
11312
           blend modes */
11313
0
        params.Isolated = false;
11314
0
        params.group_color_type = UNKNOWN;
11315
0
        params.Knockout = true;
11316
0
        params.page_group = false;
11317
0
        params.group_opacity = 1.0;
11318
0
        params.group_shape = 1.0;
11319
11320
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
11321
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11322
0
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11323
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11324
11325
        /* restore blend mode for actual drawing in the group */
11326
0
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11327
11328
0
        if (fill_alpha > 0.0) {
11329
0
            (void)gs_setfillconstantalpha(pgs, fill_alpha);
11330
11331
            /* If we are in an overprint situation, set the blend mode to compatible
11332
               overprint */
11333
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11334
0
                pgs->overprint &&
11335
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11336
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11337
11338
0
            code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11339
0
            if (code < 0)
11340
0
                goto cleanup;
11341
11342
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11343
0
                pgs->overprint &&
11344
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11345
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11346
0
        }
11347
11348
0
        if (stroke_alpha > 0.0) {
11349
            /* Note that the stroke can end up looking like a fill here */
11350
0
            (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11351
0
            (void)gs_setfillconstantalpha(pgs, stroke_alpha);
11352
11353
0
            if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11354
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11355
11356
0
            code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11357
0
            if (code < 0)
11358
0
                goto cleanup;
11359
11360
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11361
0
                pgs->overprint &&
11362
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11363
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11364
0
        }
11365
0
    }
11366
11367
0
cleanup:
11368
    /* Now during the pop do the compositing with alpha of 1.0 and normal blend */
11369
0
    (void)gs_setfillconstantalpha(pgs, 1.0);
11370
0
    (void)gs_setstrokeconstantalpha(pgs, 1.0);
11371
0
    (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11372
11373
    /* Restore where we were. If an error occured while in the group push
11374
       return that error code but try to do the cleanup */
11375
0
    code2 = gs_end_transparency_group(pgs);
11376
0
    if (code2 < 0) {
11377
        /* At this point things have gone very wrong. We should just shut down */
11378
0
        code = gs_abort_pdf14trans_device(pgs);
11379
0
        return code2;
11380
0
    }
11381
11382
    /* Restore if there were any changes */
11383
0
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
11384
0
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11385
0
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11386
11387
0
    return code;
11388
0
}
11389
11390
/*
11391
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11392
 * writing the clist.
11393
 */
11394
static  int
11395
pdf14_clist_fill_stroke_path(gx_device  *dev, const gs_gstate *pgs, gx_path *ppath,
11396
                             const gx_fill_params *params_fill, const gx_drawing_color *pdevc_fill,
11397
                             const gx_stroke_params *params_stroke, const gx_drawing_color *pdevc_stroke,
11398
                             const gx_clip_path *pcpath)
11399
1.16k
{
11400
1.16k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11401
1.16k
    gs_gstate new_pgs = *pgs;
11402
1.16k
    int code;
11403
11404
1.16k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
11405
1.16k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
11406
0
        return 0;
11407
11408
    /*
11409
     * Ensure that that the PDF 1.4 reading compositor will have the current
11410
     * blending parameters.  This is needed since the fill_rectangle routines
11411
     * do not have access to the gs_gstate.  Thus we have to pass any
11412
     * changes explictly.
11413
     */
11414
1.16k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11415
1.16k
    if (code < 0)
11416
0
        return code;
11417
    /* If we are doing a shading fill or stroke, the clist can't
11418
       deal with this and end up in the pdf_fill_stroke operation.
11419
       We will need to break up the fill stroke now and do
11420
       the appropriate group pushes and set up. */
11421
11422
1.16k
    if (gx_dc_is_pattern2_color(pdevc_fill) ||
11423
1.16k
        gx_dc_is_pattern2_color(pdevc_stroke)) {
11424
0
        return pdf14_clist_fill_stroke_path_pattern_setup(dev, pgs, ppath,
11425
0
            params_fill, pdevc_fill, params_stroke, pdevc_stroke, pcpath);
11426
0
    }
11427
1.16k
    update_lop_for_pdf14(&new_pgs, pdevc_fill);
11428
1.16k
    new_pgs.trans_device = dev;
11429
1.16k
    new_pgs.has_transparency = true;
11430
1.16k
    code = gx_forward_fill_stroke_path(dev, &new_pgs, ppath, params_fill, pdevc_fill,
11431
1.16k
                                       params_stroke, pdevc_stroke, pcpath);
11432
1.16k
    new_pgs.trans_device = NULL;
11433
1.16k
    new_pgs.has_transparency = false;
11434
1.16k
    return code;
11435
1.16k
}
11436
11437
/*
11438
 * text_begin routine for the PDF 1.4 transaprency compositor device for
11439
 * writing the clist.
11440
 */
11441
static  int
11442
pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs,
11443
                 const gs_text_params_t * text, gs_font * font,
11444
                 const gx_clip_path * pcpath,
11445
                 gs_text_enum_t ** ppenum)
11446
154k
{
11447
154k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11448
154k
    gs_text_enum_t *penum;
11449
154k
    int code;
11450
154k
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
11451
154k
    float opacity = pgs->fillconstantalpha;
11452
154k
    float shape = 1.0;
11453
154k
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
11454
154k
    bool draw = !(text->operation & TEXT_DO_NONE);
11455
154k
    uint text_mode = gs_currenttextrenderingmode(pgs);
11456
154k
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
11457
154k
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
11458
11459
154k
    if_debug0m('v', pgs->memory, "[v]pdf14_clist_text_begin\n");
11460
    /*
11461
     * Ensure that that the PDF 1.4 reading compositor will have the current
11462
     * blending parameters.  This is needed since the fill_rectangle routines
11463
     * do not have access to the gs_gstate.  Thus we have to pass any
11464
     * changes explictly.
11465
     */
11466
154k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11467
154k
    if (code < 0)
11468
0
        return code;
11469
    /* Pass text_begin to the target */
11470
154k
    code = gx_forward_text_begin(dev, pgs, text, font,
11471
154k
                                 pcpath, &penum);
11472
154k
    if (code < 0)
11473
1
        return code;
11474
11475
   /* Catch case where we already pushed a group and are trying to push another one.
11476
   In that case, we will pop the current one first, as we don't want to be left
11477
   with it. Note that if we have a BT and no other BTs or ETs then this issue
11478
   will not be caught until we do the put_image and notice that the stack is not
11479
   empty. */
11480
154k
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
11481
52
        code = gs_end_transparency_group(pgs);
11482
52
        if (code < 0)
11483
0
            return code;
11484
52
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
11485
52
    }
11486
11487
    /* We may need to push a non-isolated transparency group if the following
11488
    is true.
11489
    1) We are not currently in one that we pushed for text.  This is
11490
    is determined by looking at the pdf14 device.
11491
    2) The blend mode is not Normal or the opacity is not 1.0
11492
    3) Text knockout is set to true
11493
    4) And we are actually drawing text
11494
    */
11495
11496
154k
    if (gs_currenttextknockout(pgs) && (blend_issue ||
11497
154k
        (pgs->fillconstantalpha != 1.0 && text_fill) ||
11498
154k
        (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
11499
154k
        text_mode != 3 && /* don't bother with invisible text */
11500
154k
        pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED) {
11501
227
        if (draw) {
11502
227
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape, true);
11503
227
            if (code == 0)
11504
227
                pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* Needed during clist writing */
11505
227
        }
11506
227
    }
11507
154k
    *ppenum = (gs_text_enum_t *)penum;
11508
154k
    return code;
11509
154k
}
11510
11511
static  int
11512
pdf14_clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
11513
                           const gs_matrix *pmat, const gs_image_common_t *pic,
11514
                           const gs_int_rect * prect,
11515
                           const gx_drawing_color * pdcolor,
11516
                           const gx_clip_path * pcpath, gs_memory_t * mem,
11517
                           gx_image_enum_common_t ** pinfo)
11518
2.66k
{
11519
2.66k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11520
2.66k
    int code;
11521
2.66k
    gs_gstate * pgs_noconst = (gs_gstate *)pgs; /* Break 'const'. */
11522
2.66k
    const gs_image_t *pim = (const gs_image_t *)pic;
11523
2.66k
    gx_image_enum *penum;
11524
2.66k
    gx_color_tile *ptile;
11525
2.66k
    gs_rect bbox_in, bbox_out;
11526
2.66k
    gs_transparency_group_params_t tgp;
11527
    /*
11528
     * Ensure that that the PDF 1.4 reading compositor will have the current
11529
     * blending parameters.  This is needed since the fill_rectangle routines
11530
     * do not have access to the gs_gstate.  Thus we have to pass any
11531
     * changes explictly.
11532
     */
11533
2.66k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11534
2.66k
    if (code < 0)
11535
0
        return code;
11536
    /* Pass image to the target */
11537
    /* Do a quick change to the gs_gstate so that if we can return with -1 in
11538
       case the clist writer cannot handle this image itself.  In such a case,
11539
       we want to make sure we dont use the target device.  I don't necc. like
11540
       doing it this way.  Probably need to go back and do something a bit
11541
       more elegant. */
11542
2.66k
    pgs_noconst->has_transparency = true;
11543
2.66k
    pgs_noconst->trans_device = dev;
11544
11545
    /* If we are filling an image mask with a pattern that has a transparency
11546
       then we need to do some special handling */
11547
2.66k
    if (pim->ImageMask) {
11548
0
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
11549
0
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
11550
0
                if (dev_proc(dev, begin_typed_image) != pdf14_clist_begin_typed_image) {
11551
0
                    ptile = pdcolor->colors.pattern.p_tile;
11552
                    /* Set up things in the ptile so that we get the proper
11553
                       blending etc */
11554
                    /* Set the blending procs and the is_additive setting based
11555
                       upon the number of channels */
11556
0
                    if (ptile->ttrans->n_chan-1 < 4) {
11557
0
                        ptile->ttrans->blending_procs = &rgb_blending_procs;
11558
0
                        ptile->ttrans->is_additive = true;
11559
0
                    } else {
11560
0
                        ptile->ttrans->blending_procs = &cmyk_blending_procs;
11561
0
                        ptile->ttrans->is_additive = false;
11562
0
                    }
11563
                    /* Set the blending mode in the ptile based upon the current
11564
                       setting in the gs_gstate */
11565
0
                    ptile->blending_mode = pgs->blend_mode;
11566
                    /* Set the procs so that we use the proper filling method. */
11567
                    /* Let the imaging stuff get set up */
11568
0
                    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
11569
0
                                                        prect, pdcolor,
11570
0
                                                        pcpath, mem, pinfo);
11571
0
                    if (code < 0)
11572
0
                        return code;
11573
11574
0
                    penum = (gx_image_enum *) *pinfo;
11575
                    /* Apply inverse of the image matrix to our
11576
                       image size to get our bounding box. */
11577
0
                    bbox_in.p.x = 0;
11578
0
                    bbox_in.p.y = 0;
11579
0
                    bbox_in.q.x = pim->Width;
11580
0
                    bbox_in.q.y = pim->Height;
11581
0
                    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
11582
0
                                                     &bbox_out);
11583
0
                    if (code < 0)
11584
0
                        return code;
11585
                    /* Set up a compositor action for pushing the group */
11586
0
                    if_debug0m('v', pgs->memory, "[v]Pushing special trans group for image\n");
11587
0
                    tgp.Isolated = true;
11588
0
                    tgp.Knockout = false;
11589
0
                    tgp.page_group = false;
11590
0
                    tgp.mask_id = 0;
11591
0
                    tgp.image_with_SMask = false;
11592
0
                    tgp.idle = false;
11593
0
                    tgp.iccprofile = NULL;
11594
0
                    tgp.icc_hashcode = 0;
11595
0
                    tgp.group_color_numcomps = ptile->ttrans->n_chan-1;
11596
0
                    tgp.ColorSpace = NULL;
11597
0
                    tgp.text_group = 0;
11598
0
                    tgp.group_opacity = pgs->fillconstantalpha;
11599
0
                    tgp.group_shape = 1.0;
11600
                    /* This will handle the compositor command */
11601
0
                    gs_begin_transparency_group((gs_gstate *) pgs_noconst, &tgp,
11602
0
                                                &bbox_out, PDF14_BEGIN_TRANS_GROUP);
11603
0
                    ptile->ttrans->image_render = penum->render;
11604
0
                    penum->render = &pdf14_pattern_trans_render;
11605
0
                    ptile->trans_group_popped = false;
11606
0
                    pgs_noconst->has_transparency = false;
11607
0
                    pgs_noconst->trans_device = NULL;
11608
0
                    return code;
11609
0
                }
11610
0
            }
11611
0
        }
11612
0
    }
11613
    /* This basically tries high level images for clist. If that fails
11614
       then we do the default */
11615
2.66k
    code = gx_forward_begin_typed_image(dev, pgs, pmat,
11616
2.66k
                            pic, prect, pdcolor, pcpath, mem, pinfo);
11617
2.66k
    if (code < 0){
11618
1.83k
        code = gx_default_begin_typed_image(dev, pgs, pmat, pic, prect,
11619
1.83k
                                        pdcolor, pcpath, mem, pinfo);
11620
1.83k
        pgs_noconst->has_transparency = false;
11621
1.83k
        pgs_noconst->trans_device = NULL;
11622
1.83k
        return code;
11623
1.83k
    } else {
11624
829
        pgs_noconst->has_transparency = false;
11625
829
        pgs_noconst->trans_device = NULL;
11626
829
        return code;
11627
829
    }
11628
2.66k
}
11629
11630
static int
11631
pdf14_clist_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
11632
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
11633
0
{
11634
0
    int code;
11635
11636
0
    code = gx_forward_copy_planes(dev, data, data_x, raster, id,
11637
0
                                  x, y, w, h, plane_height);
11638
0
    return code;
11639
0
}
11640
11641
static int
11642
gs_pdf14_clist_device_push(gs_memory_t *mem, gs_gstate *pgs, gx_device **pcdev,
11643
                           gx_device *dev, const gs_pdf14trans_t *pdf14pct)
11644
267
{
11645
267
    int code;
11646
267
    pdf14_clist_device *p14dev;
11647
267
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
11648
11649
267
    code = pdf14_create_clist_device(mem, pgs, pcdev, dev, pdf14pct);
11650
267
    if (code < 0)
11651
0
        return code;
11652
    /*
11653
     * Set the color_info of the clist device to match the compositing
11654
     * device.  We will restore it when the compositor is popped.
11655
     * See pdf14_clist_composite for the restore.  Do the
11656
     * same with the gs_gstate's get_cmap_procs.  We do not want
11657
     * the gs_gstate to use transfer functions on our color values.
11658
     * The transfer functions will be applied at the end after we
11659
     * have done our PDF 1.4 blend operations.
11660
     */
11661
267
    p14dev = (pdf14_clist_device *)(*pcdev);
11662
267
    p14dev->saved_target_color_info = dev->color_info;
11663
267
    dev->color_info = (*pcdev)->color_info;
11664
    /* Make sure that we keep the anti-alias information though */
11665
267
    dev->color_info.anti_alias = p14dev->saved_target_color_info.anti_alias;
11666
267
    p14dev->color_info.anti_alias = dev->color_info.anti_alias;
11667
11668
    /* adjust the clist_color_info now */
11669
267
    cdev->clist_color_info.depth = p14dev->color_info.depth;
11670
267
    cdev->clist_color_info.polarity = p14dev->color_info.polarity;
11671
267
    cdev->clist_color_info.num_components = p14dev->color_info.num_components;
11672
267
    cdev->clist_color_info.max_color = p14dev->color_info.max_color;
11673
267
    cdev->clist_color_info.max_gray = p14dev->color_info.max_gray;
11674
11675
267
    p14dev->saved_target_encode_color = dev_proc(dev, encode_color);
11676
267
    p14dev->saved_target_decode_color = dev_proc(dev, decode_color);
11677
267
    set_dev_proc(dev, encode_color, p14dev->my_encode_color);
11678
267
    set_dev_proc(p14dev, encode_color, p14dev->my_encode_color);
11679
267
    set_dev_proc(dev, decode_color, p14dev->my_decode_color);
11680
267
    set_dev_proc(p14dev, decode_color, p14dev->my_decode_color);
11681
267
    p14dev->saved_target_get_color_mapping_procs =
11682
267
                              dev_proc(dev, get_color_mapping_procs);
11683
267
    p14dev->saved_target_get_color_comp_index =
11684
267
                              dev_proc(dev, get_color_comp_index);
11685
267
    set_dev_proc(dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
11686
267
    set_dev_proc(p14dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
11687
267
    set_dev_proc(dev, get_color_comp_index, p14dev->my_get_color_comp_index);
11688
267
    set_dev_proc(p14dev, get_color_comp_index, p14dev->my_get_color_comp_index);
11689
267
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
11690
267
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
11691
267
    gx_set_cmap_procs(pgs, dev);
11692
267
    return code;
11693
267
}
11694
/*
11695
 * When we push a PDF 1.4 transparency compositor onto the clist, we also need
11696
 * to create a compositing device for clist writing.  The primary purpose of
11697
 * this device is to provide support for the process color model in which
11698
 * the PDF 1.4 transparency is done.  (This may differ from the process color
11699
 * model of the output device.)  The actual work of compositing the image is
11700
 * done on the output (reader) side of the clist.
11701
 */
11702
static  int
11703
c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev,
11704
                gx_device ** pcdev, gs_gstate * pgs, gs_memory_t * mem)
11705
26.5k
{
11706
26.5k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
11707
26.5k
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte;
11708
26.5k
    int code = 0;
11709
11710
    /* We only handle the push/pop operations */
11711
26.5k
    switch (pdf14pct->params.pdf14_op) {
11712
267
        case PDF14_PUSH_DEVICE:
11713
267
            code = gs_pdf14_clist_device_push(mem, pgs, pcdev, dev, pdf14pct);
11714
            /* Change (non-error) code to 1 to indicate that we created
11715
             * a device. */
11716
267
            if (code >= 0)
11717
267
                code = 1;
11718
267
            return code;
11719
11720
265
        case PDF14_POP_DEVICE:
11721
265
            code = clist_writer_check_empty_cropping_stack(cdev);
11722
265
            break;
11723
11724
178
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
11725
2.56k
        case PDF14_BEGIN_TRANS_GROUP:
11726
2.56k
            { /* HACK: store mask_id into our params for subsequent
11727
                   calls of c_pdf14trans_write. To do this we must
11728
                   break const. */
11729
2.56k
                gs_pdf14trans_t * pdf14pct_noconst;
11730
11731
2.56k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
11732
                /* What ever the current mask ID is, that is the
11733
                   softmask group through which this transparency
11734
                   group must be rendered. Store it now. */
11735
2.56k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
11736
2.56k
                if_debug1m('v', pgs->memory,
11737
2.56k
                           "[v]c_pdf14trans_clist_write_update group mask_id=%d \n",
11738
2.56k
                           cdev->mask_id);
11739
2.56k
            }
11740
2.56k
            break;
11741
2.38k
        case PDF14_END_TRANS_GROUP:
11742
2.54k
        case PDF14_END_TRANS_TEXT_GROUP:
11743
2.54k
            code = 0; /* A place for breakpoint. */
11744
2.54k
            break;
11745
2.63k
        case PDF14_BEGIN_TRANS_MASK:
11746
            /* A new mask has been started */
11747
2.63k
            cdev->mask_id = ++cdev->mask_id_count;
11748
            /* replacing is set everytime that we
11749
               have a zpushtransparencymaskgroup */
11750
2.63k
            { /* HACK: store mask_id into our params for subsequent
11751
                   calls of c_pdf14trans_write. To do this we must
11752
                   break const. */
11753
2.63k
                gs_pdf14trans_t * pdf14pct_noconst;
11754
11755
2.63k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
11756
2.63k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
11757
2.63k
                if_debug1m('v', pgs->memory,
11758
2.63k
                           "[v]c_pdf14trans_clist_write_update mask mask_id=%d \n",
11759
2.63k
                           cdev->mask_id);
11760
2.63k
            }
11761
2.63k
            break;
11762
1.33k
        case PDF14_END_TRANS_MASK:
11763
1.33k
            code = 0; /* A place for breakpoint. */
11764
1.33k
            break;
11765
0
        case PDF14_PUSH_TRANS_STATE:
11766
0
            code = 0; /* A place for breakpoint. */
11767
0
            break;
11768
1.31k
        case PDF14_POP_TRANS_STATE:
11769
1.31k
            code = 0; /* A place for breakpoint. */
11770
1.31k
            break;
11771
0
        case PDF14_ABORT_DEVICE:
11772
0
            code = 0;
11773
0
            break;
11774
0
        case PDF14_PUSH_SMASK_COLOR:
11775
0
            *pcdev = dev;
11776
0
            return 0;
11777
0
            break;
11778
0
        case PDF14_POP_SMASK_COLOR:
11779
0
            *pcdev = dev;
11780
0
            return 0;
11781
0
            break;
11782
15.5k
        default:
11783
15.5k
            break;   /* do nothing for remaining ops */
11784
26.5k
    }
11785
26.2k
    *pcdev = dev;
11786
26.2k
    if (code < 0)
11787
0
        return code;
11788
    /* See c_pdf14trans_write, c_pdf14trans_adjust_ctm, and
11789
       apply_composite. */
11790
26.2k
    code = gs_gstate_setmatrix(&cdev->gs_gstate, &pdf14pct->params.ctm);
11791
    /* Wrote an extra ctm. */
11792
26.2k
    cmd_clear_known(cdev, ctm_known);
11793
11794
26.2k
    return code;
11795
26.2k
}
11796
11797
/*
11798
 * When we push a PDF 1.4 transparency compositor, we need to make the clist
11799
 * device color_info data match the compositing device.  We need to do this
11800
 * since the PDF 1.4 transparency compositing device may use a different
11801
 * process color model than the output device.  We do not need to modify the
11802
 * color related device procs since the compositing device has its own.  We
11803
 * restore the color_info data when the transparency device is popped.
11804
 */
11805
static  int
11806
c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
11807
                gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem)
11808
1.60M
{
11809
1.60M
    pdf14_device * p14dev = (pdf14_device *)tdev;
11810
1.60M
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
11811
1.60M
    gs_devn_params * pclist_devn_params;
11812
1.60M
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)cdev;
11813
1.60M
    cmm_profile_t *cl_icc_profile, *p14_icc_profile;
11814
1.60M
    gsicc_rendering_param_t render_cond;
11815
1.60M
    cmm_dev_profile_t *dev_profile;
11816
11817
1.60M
    dev_proc(cdev, get_profile)(cdev,  &dev_profile);
11818
1.60M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &cl_icc_profile,
11819
1.60M
                          &render_cond);
11820
11821
    /* If we are using the blending color space, then be sure to use that. */
11822
1.60M
    if (p14dev->blend_cs_state == PDF14_BLEND_CS_SPECIFIED &&
11823
1.60M
        dev_profile->blend_profile != NULL)
11824
0
        cl_icc_profile = dev_profile->blend_profile;
11825
1.60M
    else if (p14dev->blend_cs_state == PDF14_BLEND_CS_OUTPUTINTENT &&
11826
1.60M
        dev_profile->oi_profile != NULL)
11827
0
        cl_icc_profile = dev_profile->oi_profile;
11828
11829
1.60M
    dev_proc(p14dev, get_profile)((gx_device *)p14dev,  &dev_profile);
11830
1.60M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &p14_icc_profile,
11831
1.60M
                          &render_cond);
11832
    /*
11833
     * We only handle the push/pop operations. Save and restore the color_info
11834
     * field for the clist device.  This is needed since the process color
11835
     * model of the clist device needs to match the PDF 1.4 compositing
11836
     * device.
11837
     */
11838
1.60M
    switch (pdf14pct->params.pdf14_op) {
11839
43.9k
    case PDF14_PUSH_DEVICE:
11840
        /* Overprint simulation sets the profile at prototype creation, as does
11841
           when the target profile is NCLR. Match the logic in gs_pdf14_device_push */
11842
43.9k
        if (!((p14dev->overprint_sim && cl_icc_profile->data_cs != gsCMYK) ||
11843
43.9k
            cl_icc_profile->data_cs == gsNCHANNEL)) {
11844
43.9k
            gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update");
11845
43.9k
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
11846
43.9k
                -1, "c_pdf14trans_clist_read_update");
11847
43.9k
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile;
11848
43.9k
        }
11849
            /*
11850
             * If we are blending using spot colors (i.e. the output device
11851
             * supports spot colors) then we need to transfer
11852
             * color info from the clist PDF 1.4 compositing reader device
11853
             * to the clist writer PDF 1.4 compositing device.
11854
             * This info was transfered from that device to the output
11855
             * device as a set of device parameters.  However the clist
11856
             * reader PDF 1.4 compositing device did not exist when the
11857
             * device parameters were read from the clist.  So that info
11858
             * was buffered into the output device.
11859
             */
11860
43.9k
            pclist_devn_params = dev_proc(cdev, ret_devn_params)(cdev);
11861
43.9k
            if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors != 0) {
11862
0
                int num_comp = p14dev->color_info.num_components;
11863
                /*
11864
                 * The number of components for the PDF14 device is the sum
11865
                 * of the process components and the number of spot colors
11866
                 * for the page.  If the color capabilities of the parent
11867
                 * device (which coming into this are the same as the p14dev)
11868
                 * are smaller than the number of page spot colors then
11869
                 * use that for the number of components. Otherwise use
11870
                 * the page_spot_colors.
11871
                 */
11872
0
                p14dev->devn_params.page_spot_colors =
11873
0
                    pclist_devn_params->page_spot_colors;
11874
0
                if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
11875
0
                    p14dev->color_info.num_components = num_comp;
11876
0
                } else {
11877
                    /* if page_spot_colors < 0, this will be wrong, so don't update num_components */
11878
0
                    if (p14dev->devn_params.page_spot_colors >= 0) {
11879
0
                        p14dev->color_info.num_components =
11880
0
                            p14dev->devn_params.num_std_colorant_names +
11881
0
                            p14dev->devn_params.page_spot_colors;
11882
0
                    }
11883
0
                }
11884
                /* limit the num_components to the max. */
11885
0
                if (p14dev->color_info.num_components > p14dev->color_info.max_components)
11886
0
                    p14dev->color_info.num_components = p14dev->color_info.max_components;
11887
                /* Transfer the data for the spot color names
11888
                   But we have to free what may be there before we do this */
11889
0
                devn_free_params((gx_device*) p14dev);
11890
0
                p14dev->devn_params.separations =
11891
0
                    pclist_devn_params->pdf14_separations;
11892
0
                p14dev->free_devicen = false;  /* to avoid freeing the clist ones */
11893
0
                if (num_comp != p14dev->color_info.num_components) {
11894
                    /* When the pdf14 device is opened it creates a context
11895
                       and some soft mask related objects.  The push device
11896
                       compositor action will have already created these but
11897
                       they are the wrong size.  We must destroy them though
11898
                       before reopening the device */
11899
0
                    if (p14dev->ctx != NULL) {
11900
0
                        pdf14_ctx_free(p14dev->ctx);
11901
0
                        p14dev->ctx = NULL;
11902
0
                    }
11903
0
                    dev_proc(tdev, open_device) (tdev);
11904
0
                }
11905
0
            }
11906
            /* Check if we need to swap out the ICC profile for the pdf14
11907
               device.  This will occur if our source profile for our device
11908
               happens to be something like CIELAB.  Then we will blend in
11909
               RGB (unless a trans group is specified) */
11910
43.9k
            if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) {
11911
0
                gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
11912
0
                                        -1, "c_pdf14trans_clist_read_update");
11913
                /* Initial ref count from gsicc_read_serial_icc() is 1, which is what we want */
11914
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
11915
0
                                        gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash);
11916
                /* Keep a pointer to the clist device */
11917
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->dev = (gx_device *) cdev;
11918
0
            }
11919
43.9k
            break;
11920
11921
43.9k
        case PDF14_POP_DEVICE:
11922
#     if 0 /* Disabled because *p14dev has no forwarding methods during
11923
                    the clist playback. This code is not executed while clist
11924
                    writing. */
11925
            cdev->color_info = p14dev->saved_target_color_info;
11926
#     endif
11927
43.9k
           break;
11928
11929
1.51M
        default:
11930
1.51M
            break;   /* do nothing for remaining ops */
11931
1.60M
    }
11932
11933
1.60M
    return 0;
11934
1.60M
}
11935
11936
/*
11937
 * Get cropping for the compositor command.
11938
 */
11939
static  int
11940
c_pdf14trans_get_cropping(const gs_composite_t *pcte, int *ry, int *rheight,
11941
                          int cropping_min, int cropping_max)
11942
26.5k
{
11943
26.5k
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
11944
26.5k
    switch (pdf14pct->params.pdf14_op) {
11945
267
        case PDF14_PUSH_DEVICE: return ALLBANDS; /* Applies to all bands. */
11946
265
        case PDF14_POP_DEVICE:  return ALLBANDS; /* Applies to all bands. */
11947
0
        case PDF14_ABORT_DEVICE: return ALLBANDS; /* Applies to all bands */
11948
178
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
11949
2.56k
        case PDF14_BEGIN_TRANS_GROUP:
11950
2.56k
            { gs_int_rect rect;
11951
11952
                /* Text group always uses parents size*/
11953
2.56k
                if (pdf14pct->params.text_group == PDF14_TEXTGROUP_BT_PUSHED) {
11954
227
                    *ry = cropping_min;
11955
227
                    *rheight = cropping_max - *ry;
11956
2.33k
                } else {
11957
2.33k
                    pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
11958
2.33k
                        &pdf14pct->params.bbox, &rect);
11959
                    /* We have to crop this by the parent object.   */
11960
2.33k
                    *ry = max(rect.p.y, cropping_min);
11961
2.33k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
11962
2.33k
                }
11963
2.56k
                return PUSHCROP; /* Push cropping. */
11964
178
            }
11965
2.63k
        case PDF14_BEGIN_TRANS_MASK:
11966
2.63k
            { gs_int_rect rect;
11967
11968
2.63k
                pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
11969
2.63k
                                                    &pdf14pct->params.bbox, &rect);
11970
                /* We have to crop this by the parent object and worry about the BC outside
11971
                   the range, except for image SMask which don't affect areas outside the image.
11972
                   The presence of a transfer function opens the possibility of issues with this */
11973
2.63k
                if (pdf14pct->params.mask_is_image || (pdf14pct->params.GrayBackground == 1.0 &&
11974
1.35k
                      pdf14pct->params.function_is_identity)) {
11975
                    /* In this case there will not be a background effect to
11976
                       worry about.  The mask will not have any effect outside
11977
                       the bounding box.  This is NOT the default or common case. */
11978
1.27k
                    *ry = max(rect.p.y, cropping_min);
11979
1.27k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
11980
1.27k
                    return PUSHCROP; /* Push cropping. */
11981
1.35k
                }  else {
11982
                    /* We need to make the soft mask range as large as the parent
11983
                       due to the fact that the background color can have an impact
11984
                       OUTSIDE the bounding box of the soft mask */
11985
1.35k
                    *ry = cropping_min;
11986
1.35k
                    *rheight = cropping_max - cropping_min;
11987
1.35k
                    if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
11988
1.30k
                        return SAMEAS_PUSHCROP_BUTNOPUSH;
11989
52
                    else
11990
52
                        return PUSHCROP; /* Push cropping. */
11991
1.35k
                }
11992
2.63k
            }
11993
2.38k
        case PDF14_END_TRANS_GROUP: return POPCROP; /* Pop cropping. */
11994
155
        case PDF14_END_TRANS_TEXT_GROUP: return POPCROP; /* Pop cropping. */
11995
1.33k
        case PDF14_END_TRANS_MASK: return POPCROP;   /* Pop the cropping */
11996
0
        case PDF14_PUSH_TRANS_STATE: return CURRBANDS;
11997
1.31k
        case PDF14_POP_TRANS_STATE: return CURRBANDS;
11998
15.5k
        case PDF14_SET_BLEND_PARAMS: return ALLBANDS;
11999
0
        case PDF14_PUSH_SMASK_COLOR: return POPCROP; /* Pop cropping. */
12000
0
        case PDF14_POP_SMASK_COLOR: return POPCROP;   /* Pop the cropping */
12001
0
        case PDF14_BEGIN_TRANS_TEXT_GROUP: return ALLBANDS; /* should never occur */
12002
26.5k
    }
12003
0
    return ALLBANDS;
12004
26.5k
}
12005
12006
/*
12007
 * This routine will check to see if the color component name matches those
12008
 * that are available amoung the current device's color components.  If the
12009
 * color name is known to the output device then we add it to the list of
12010
 * colorants for the PDF 1.4 transparency compositor.
12011
 *
12012
 * Notes:  There are currently three different versions of The PDF 1.4
12013
 * transparency compositor device.  The choice of which one is being used
12014
 * depends upon the process color model of the output device.  This procedure
12015
 * is only used if the output (target) device uses a CMYK, or RGB or Gray
12016
 * plus spot color process color model.
12017
 *
12018
 * Parameters:
12019
 *   dev - pointer to device data structure.
12020
 *   pname - pointer to name (zero termination not required)
12021
 *   nlength - length of the name
12022
 *   number of process colorants (either 1, 3, or 4)
12023
 *
12024
 * This routine returns a positive value (0 to n) which is the device colorant
12025
 * number if the name is found.  It returns GX_DEVICE_COLOR_MAX_COMPONENTS if
12026
 * the colorant is not being used due to a SeparationOrder device parameter.
12027
 * It returns a negative value if not found.
12028
 */
12029
static int
12030
pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname,
12031
    int name_size, int component_type, int num_process_colors)
12032
0
{
12033
0
    pdf14_device *pdev = (pdf14_device *)dev;
12034
0
    gx_device *tdev = pdev->target;
12035
0
    gs_devn_params *pdevn_params = &pdev->devn_params;
12036
0
    gs_separations *pseparations;
12037
0
    int comp_index;
12038
0
    dev_proc_get_color_comp_index(*target_get_color_comp_index);
12039
0
    int offset = 4 - num_process_colors;
12040
12041
0
    while (tdev->child) {
12042
0
        tdev = tdev->child;
12043
0
    }
12044
    /* If something has gone wrong and this is no longer the pdf14 compositor, */
12045
    /* get the devn_params from the target to avoid accessing using the wrong  */
12046
    /* pointer. Bug 696372.                                                    */
12047
0
    if (tdev == (gx_device *)pdev)
12048
0
        pdevn_params = dev_proc(pdev, ret_devn_params)(dev);
12049
0
    pseparations = &pdevn_params->separations;
12050
    /* If num_process_colors is 3 or 1 (RGB or Gray) then we are in a situation
12051
     * where we are in a blend color space that is RGB or Gray based and we
12052
     * have a spot colorant.  If the spot colorant name is Cyan, Magenta
12053
     * Yellow or Black, then we should use the alternate tint transform */
12054
0
    if (num_process_colors < 4) {
12055
0
        int k;
12056
0
        for (k = 0; k < 4; k++) {
12057
0
            if (strncmp(pname, pdev->devn_params.std_colorant_names[k], name_size) == 0)
12058
0
                return -1;
12059
0
        }
12060
0
    }
12061
12062
0
    target_get_color_comp_index = dev_proc(tdev, get_color_comp_index);
12063
12064
    /* The pdf14_clist_composite may have set the color procs.
12065
       We need the real target procs, but not if we are doing simulated
12066
       overprint */
12067
0
    if (target_get_color_comp_index == pdf14_cmykspot_get_color_comp_index &&
12068
0
        !pdev->overprint_sim)
12069
0
        target_get_color_comp_index =
12070
0
            ((pdf14_clist_device *)pdev)->saved_target_get_color_comp_index;
12071
    /*
12072
    * If this is not a separation name then simply forward it to the target
12073
    * device or return -1 if we are doing overprint simulation.
12074
    * The halftone setup expects this.
12075
    */
12076
0
    if (!pdev->overprint_sim && (component_type == NO_COMP_NAME_TYPE_HT ||
12077
0
        component_type == NO_COMP_NAME_TYPE_OP)) {
12078
0
        return  (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12079
0
    }
12080
0
    if (pdev->overprint_sim && component_type == NO_COMP_NAME_TYPE_HT) {
12081
0
        return -1;
12082
0
    }
12083
12084
    /*
12085
    * Check if the component is in either the process color model list
12086
    * or in the SeparationNames list.
12087
    */
12088
0
    comp_index = check_pcm_and_separation_names(dev, pdevn_params, pname,
12089
0
        name_size, component_type);
12090
    /*
12091
    * Return the colorant number if we know this name.  Note adjustment for
12092
    * compensating of blend color space.
12093
    */
12094
0
    if (comp_index >= 0)
12095
0
        return comp_index - offset;
12096
12097
    /* Only worry about the target if we are not doing an overprint simulation */
12098
0
    if (!pdev->overprint_sim) {
12099
        /*
12100
        * If we do not know this color, check if the output (target) device does.
12101
        * Note that if the target device has ENABLE_AUTO_SPOT_COLORS this will add
12102
        * the colorant so we will only get < 0 returned when we hit the max. for
12103
        * the target device.
12104
        */
12105
0
        comp_index = (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12106
        /*
12107
        * Ignore color if unknown to the output device or if color is not being
12108
        * imaged due to the SeparationOrder device parameter.
12109
        */
12110
0
        if (comp_index < 0 || comp_index == GX_DEVICE_COLOR_MAX_COMPONENTS)
12111
0
            return comp_index - offset;
12112
0
    }
12113
12114
    /*
12115
    * This is a new colorant.  Add it to our list of colorants.
12116
    * The limit accounts for the number of process colors (at least 4).
12117
    */
12118
0
    if ((pseparations->num_separations + 1) <
12119
0
            (GX_DEVICE_COLOR_MAX_COMPONENTS - max(num_process_colors, 4))) {
12120
0
        int sep_num = pseparations->num_separations++;
12121
0
        int color_component_number;
12122
0
        byte * sep_name;
12123
12124
0
        sep_name = gs_alloc_bytes(dev->memory->stable_memory,
12125
0
            name_size, "pdf14_spot_get_color_comp_index");
12126
0
        if (sep_name == NULL) {
12127
0
            pseparations->num_separations--;  /* we didn't add it */
12128
0
            return -1;
12129
0
        }
12130
0
        memcpy(sep_name, pname, name_size);
12131
0
        pseparations->names[sep_num].size = name_size;
12132
0
        pseparations->names[sep_num].data = sep_name;
12133
0
        color_component_number = sep_num + num_process_colors;
12134
0
        if (color_component_number >= dev->color_info.max_components)
12135
0
            color_component_number = GX_DEVICE_COLOR_MAX_COMPONENTS;
12136
0
        else
12137
0
            pdevn_params->separation_order_map[color_component_number] =
12138
0
            color_component_number;
12139
12140
        /* Indicate that we need to find equivalent CMYK color. */
12141
0
        pdev->op_pequiv_cmyk_colors.color[sep_num].color_info_valid = false;
12142
0
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
12143
12144
0
        return color_component_number;
12145
0
    }
12146
12147
0
    return GX_DEVICE_COLOR_MAX_COMPONENTS;
12148
0
}
12149
12150
12151
/* CMYK process + spots */
12152
static int
12153
pdf14_cmykspot_get_color_comp_index(gx_device * dev, const char * pname,
12154
    int name_size, int component_type)
12155
0
{
12156
0
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 4);
12157
0
}
12158
12159
/* RGB process + spots */
12160
static int
12161
pdf14_rgbspot_get_color_comp_index(gx_device * dev, const char * pname,
12162
    int name_size, int component_type)
12163
0
{
12164
0
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 3);
12165
0
}
12166
12167
/* Gray process + spots */
12168
static int
12169
pdf14_grayspot_get_color_comp_index(gx_device * dev, const char * pname,
12170
    int name_size, int component_type)
12171
0
{
12172
0
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 1);
12173
0
}
12174
12175
/* These functions keep track of when we are dealing with soft masks.
12176
   In such a case, we set the default color profiles to ones that ensure
12177
   proper soft mask rendering. */
12178
static int
12179
pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev)
12180
1.91k
{
12181
1.91k
    pdf14_device * pdev = (pdf14_device *) dev;
12182
1.91k
    pdf14_smaskcolor_t *result;
12183
1.91k
    gsicc_smask_t *smask_profiles = pgs->icc_manager->smask_profiles;
12184
1.91k
    int k;
12185
12186
    /* See if we have profiles already in place.   Note we also have to
12187
       worry about a corner case where this device does not have a
12188
       smaskcolor stucture to store the profiles AND the profiles were
12189
       already swapped out in the icc_manager.  This can occur when we
12190
       pushed a transparency mask and then inside the mask we have a pattern
12191
       which also has a transparency mask.   The state of the icc_manager
12192
       is that it already has done the swap and there is no need to fool
12193
       with any of this while dealing with the soft mask within the pattern */
12194
1.91k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12195
1.91k
        pgs->icc_manager->smask_profiles->swapped) {
12196
0
            return 0;
12197
0
    }
12198
1.91k
    if (pdev->smaskcolor != NULL) {
12199
2
        pdev->smaskcolor->ref_count++;
12200
2
        if_debug1m(gs_debug_flag_icc, dev->memory,
12201
2
                   "[icc] Increment smask color now %d\n",
12202
2
                   pdev->smaskcolor->ref_count);
12203
1.91k
    } else {
12204
        /* Allocate and swap out the current profiles.  The softmask
12205
           profiles should already be in place */
12206
1.91k
        result = gs_alloc_struct(pdev->memory->stable_memory, pdf14_smaskcolor_t,
12207
1.91k
                                &st_pdf14_smaskcolor,
12208
1.91k
                                "pdf14_increment_smask_color");
12209
1.91k
        if (result == NULL)
12210
0
            return gs_error_VMerror;
12211
12212
1.91k
        result->profiles = gsicc_new_iccsmask(pdev->memory->stable_memory);
12213
1.91k
        if (result->profiles == NULL)
12214
0
            return gs_error_VMerror;
12215
12216
1.91k
        pdev->smaskcolor = result;
12217
12218
1.91k
        result->profiles->smask_gray = pgs->icc_manager->default_gray;
12219
1.91k
        result->profiles->smask_rgb = pgs->icc_manager->default_rgb;
12220
1.91k
        result->profiles->smask_cmyk = pgs->icc_manager->default_cmyk;
12221
1.91k
        pgs->icc_manager->default_gray = smask_profiles->smask_gray;
12222
1.91k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "pdf14_increment_smask_color");
12223
1.91k
        pgs->icc_manager->default_rgb = smask_profiles->smask_rgb;
12224
1.91k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "pdf14_increment_smask_color");
12225
1.91k
        pgs->icc_manager->default_cmyk = smask_profiles->smask_cmyk;
12226
1.91k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_increment_smask_color");
12227
1.91k
        pgs->icc_manager->smask_profiles->swapped = true;
12228
1.91k
        if_debug0m(gs_debug_flag_icc, pgs->memory,
12229
1.91k
                   "[icc] Initial creation of smask color. Ref count 1\n");
12230
1.91k
        pdev->smaskcolor->ref_count = 1;
12231
        /* We also need to update the profile that is currently in the
12232
           color spaces of the graphic state.  Otherwise this can be
12233
           referenced, which will result in a mismatch.  What we want to do
12234
           is see if it was the original default and only swap in that case. */
12235
5.73k
        for (k = 0; k < 2; k++) {
12236
3.82k
            gs_color_space *pcs     = pgs->color[k].color_space;
12237
3.82k
            cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12238
3.82k
            if (profile != NULL) {
12239
3.77k
                switch(profile->data_cs) {
12240
2.08k
                    case gsGRAY:
12241
2.08k
                        if (profile->hashcode ==
12242
2.08k
                            result->profiles->smask_gray->hashcode) {
12243
1.80k
                                profile = pgs->icc_manager->default_gray;
12244
1.80k
                        }
12245
2.08k
                        break;
12246
1.64k
                    case gsRGB:
12247
1.64k
                        if (profile->hashcode ==
12248
1.64k
                            result->profiles->smask_rgb->hashcode) {
12249
349
                                profile = pgs->icc_manager->default_rgb;
12250
349
                        }
12251
1.64k
                        break;
12252
47
                    case gsCMYK:
12253
47
                        if (profile->hashcode ==
12254
47
                            result->profiles->smask_cmyk->hashcode) {
12255
47
                                profile = pgs->icc_manager->default_cmyk;
12256
47
                        }
12257
47
                        break;
12258
0
                    default:
12259
12260
0
                        break;
12261
3.77k
                }
12262
3.77k
                if (pcs->cmm_icc_profile_data != profile) {
12263
2.20k
                    gsicc_adjust_profile_rc(profile, 1, "pdf14_increment_smask_color");
12264
2.20k
                    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_increment_smask_color");
12265
2.20k
                    pcs->cmm_icc_profile_data = profile;
12266
2.20k
                }
12267
3.77k
            }
12268
3.82k
        }
12269
1.91k
    }
12270
1.91k
    return 0;
12271
1.91k
}
12272
12273
static int
12274
pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev)
12275
2.18k
{
12276
2.18k
    pdf14_device * pdev = (pdf14_device *) dev;
12277
2.18k
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
12278
2.18k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
12279
2.18k
    int k;
12280
12281
    /* See comment in pdf14_increment_smask_color to understand this one */
12282
2.18k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12283
2.18k
        pgs->icc_manager->smask_profiles->swapped) {
12284
0
            return 0;
12285
0
    }
12286
2.18k
    if (smaskcolor != NULL) {
12287
1.91k
        smaskcolor->ref_count--;
12288
1.91k
        if_debug1m(gs_debug_flag_icc, pgs->memory,
12289
1.91k
                   "[icc] Decrement smask color.  Now %d\n",
12290
1.91k
                   smaskcolor->ref_count);
12291
1.91k
        if (smaskcolor->ref_count == 0) {
12292
1.91k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reset smask color.\n");
12293
            /* Lets return the profiles and clean up */
12294
            /* First see if we need to "reset" the profiles that are in
12295
               the graphic state */
12296
1.91k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reseting graphic state color spaces\n");
12297
5.73k
            for (k = 0; k < 2; k++) {
12298
3.82k
                gs_color_space *pcs = pgs->color[k].color_space;
12299
3.82k
                cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12300
3.82k
                if (profile != NULL) {
12301
3.77k
                    switch(profile->data_cs) {
12302
2.08k
                        case gsGRAY:
12303
2.08k
                            if (profile->hashcode ==
12304
2.08k
                                pgs->icc_manager->default_gray->hashcode) {
12305
1.80k
                                    profile =
12306
1.80k
                                        smaskcolor->profiles->smask_gray;
12307
1.80k
                            }
12308
2.08k
                            break;
12309
1.64k
                        case gsRGB:
12310
1.64k
                            if (profile->hashcode ==
12311
1.64k
                                pgs->icc_manager->default_rgb->hashcode) {
12312
349
                                    profile =
12313
349
                                        smaskcolor->profiles->smask_rgb;
12314
349
                            }
12315
1.64k
                            break;
12316
47
                        case gsCMYK:
12317
47
                            if (profile->hashcode ==
12318
47
                                pgs->icc_manager->default_cmyk->hashcode) {
12319
47
                                    profile =
12320
47
                                        smaskcolor->profiles->smask_cmyk;
12321
47
                            }
12322
47
                            break;
12323
0
                        default:
12324
12325
0
                            break;
12326
3.77k
                    }
12327
3.77k
                    if (pcs->cmm_icc_profile_data != profile) {
12328
2.20k
                        gsicc_adjust_profile_rc(profile, 1, "pdf14_decrement_smask_color");
12329
2.20k
                        gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_decrement_smask_color");
12330
2.20k
                        pcs->cmm_icc_profile_data = profile;
12331
2.20k
                    }
12332
3.77k
                }
12333
3.82k
            }
12334
12335
1.91k
            gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "pdf14_decrement_smask_color");
12336
1.91k
            icc_manager->default_gray = smaskcolor->profiles->smask_gray;
12337
1.91k
            gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "pdf14_decrement_smask_color");
12338
1.91k
            icc_manager->default_rgb = smaskcolor->profiles->smask_rgb;
12339
1.91k
            gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "pdf14_decrement_smask_color");
12340
1.91k
            icc_manager->default_cmyk = smaskcolor->profiles->smask_cmyk;
12341
1.91k
            icc_manager->smask_profiles->swapped = false;
12342
            /* We didn't increment the reference count when we assigned these
12343
             * so NULL them to avoid decrementing when smaskcolor is freed
12344
             */
12345
1.91k
            smaskcolor->profiles->smask_gray =
12346
1.91k
              smaskcolor->profiles->smask_rgb =
12347
1.91k
              smaskcolor->profiles->smask_cmyk = NULL;
12348
12349
1.91k
            pdf14_free_smask_color(pdev);
12350
1.91k
        }
12351
1.91k
    }
12352
2.18k
    return 0;
12353
2.18k
}
12354
12355
static void
12356
pdf14_free_smask_color(pdf14_device * pdev)
12357
1.91k
{
12358
1.91k
    if (pdev->smaskcolor != NULL) {
12359
1.91k
        if ( pdev->smaskcolor->profiles != NULL) {
12360
            /* Do not decrement the profiles - the references were moved
12361
               here and moved back again, so the ref counts don't change
12362
             */
12363
1.91k
            gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor->profiles,
12364
1.91k
                        "pdf14_free_smask_color");
12365
1.91k
        }
12366
1.91k
        gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor, "pdf14_free_smask_color");
12367
1.91k
        pdev->smaskcolor = NULL;
12368
1.91k
    }
12369
1.91k
}
12370
12371
static void
12372
pdf14_device_finalize(const gs_memory_t *cmem, void *vptr)
12373
44.9k
{
12374
44.9k
    gx_device * const dev = (gx_device *)vptr;
12375
44.9k
    pdf14_device * pdev = (pdf14_device *)dev;
12376
44.9k
    int k;
12377
12378
44.9k
    pdf14_cleanup_group_color_profiles (pdev);
12379
12380
44.9k
    if (pdev->ctx) {
12381
2
        pdf14_ctx_free(pdev->ctx);
12382
2
        pdev->ctx = NULL;
12383
2
    }
12384
12385
44.9k
    while (pdev->color_model_stack) {
12386
20
        pdf14_pop_group_color(dev, NULL);
12387
20
    }
12388
12389
44.9k
    for (k = 0; k < pdev->devn_params.separations.num_separations; k++) {
12390
0
        if (pdev->devn_params.separations.names[k].data) {
12391
0
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.separations.names[k].data, "pdf14_device_finalize");
12392
0
            pdev->devn_params.separations.names[k].data = NULL;
12393
0
        }
12394
0
    }
12395
12396
44.9k
    for (k = 0; k < pdev->devn_params.pdf14_separations.num_separations; k++) {
12397
0
        if (pdev->devn_params.pdf14_separations.names[k].data) {
12398
0
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.pdf14_separations.names[k].data, "pdf14_device_finalize");
12399
0
            pdev->devn_params.pdf14_separations.names[k].data = NULL;
12400
0
        }
12401
0
    }
12402
12403
44.9k
    gx_device_finalize(cmem, vptr);
12404
44.9k
}
12405
12406
#if DUMP_MASK_STACK
12407
12408
static void
12409
dump_mask_stack(pdf14_mask_t *mask_stack)
12410
{
12411
    pdf14_mask_t *curr_mask = mask_stack;
12412
    int level = 0;
12413
12414
    while (curr_mask != NULL) {
12415
        if_debug1m('v', curr_mask->memory, "[v]mask_level, %d\n", level);
12416
        if_debug1m('v', curr_mask->memory, "[v]mask_buf, %p\n", curr_mask->rc_mask->mask_buf);
12417
        if_debug1m('v', curr_mask->memory, "[v]rc_count, %ld\n", curr_mask->rc_mask->rc.ref_count);
12418
        level++;
12419
        curr_mask = curr_mask->previous;
12420
    }
12421
}
12422
12423
/* A function to display the current state of the mask stack */
12424
static void
12425
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
12426
{
12427
    if_debug1m('v', ctx->memory, "[v]ctx_maskstack, %p\n", ctx->mask_stack);
12428
    if (ctx->mask_stack != NULL) {
12429
        dump_mask_stack(ctx->mask_stack);
12430
    }
12431
    if_debug1m('v', ctx->memory, "[v]ctx_stack, %p\n", ctx->stack);
12432
    if (ctx->stack != NULL) {
12433
        if_debug1m('v', ctx->memory, "[v]ctx_stack_maskstack, %p\n", ctx->stack->mask_stack);
12434
        if (ctx->stack->mask_stack != NULL) {
12435
            dump_mask_stack(ctx->stack->mask_stack);
12436
        }
12437
    }
12438
}
12439
12440
#else
12441
12442
#ifdef DEBUG
12443
static void
12444
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
12445
{
12446
    return;
12447
}
12448
#endif
12449
12450
#endif /* DUMP_MASK_STACK */