Coverage Report

Created: 2025-11-16 07:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gdevp14.c
Line
Count
Source
1
/* Copyright (C) 2001-2025 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
/* Compositing devices for implementing PDF 1.4 imaging model */
17
18
#include "assert_.h"
19
#include "math_.h"
20
#include "memory_.h"
21
#include "gx.h"
22
#include "gserrors.h"
23
#include "gscdefs.h"
24
#include "gxdevice.h"
25
#include "gsdevice.h"
26
#include "gsstruct.h"
27
#include "gxgstate.h"
28
#include "gxdcolor.h"
29
#include "gxiparam.h"
30
#include "gstparam.h"
31
#include "gxblend.h"
32
#include "gxtext.h"
33
#include "gsimage.h"
34
#include "gsrect.h"
35
#include "gscoord.h"
36
#include "gzstate.h"
37
#include "gdevdevn.h"
38
#include "gdevmem.h"
39
#include "gdevp14.h"
40
#include "gdevprn.h"    /* for prn_device structures */
41
#include "gdevppla.h"   /* for gdev_prn_open_planar */
42
#include "gdevdevnprn.h"
43
#include "gscdevn.h"
44
#include "gsovrc.h"
45
#include "gxcmap.h"
46
#include "gscolor1.h"
47
#include "gstrans.h"
48
#include "gsutil.h"
49
#include "gxcldev.h"
50
#include "gxclpath.h"
51
#include "gxdcconv.h"
52
#include "gsptype2.h"
53
#include "gxpcolor.h"
54
#include "gsptype1.h"
55
#include "gzcpath.h"
56
#include "gxpaint.h"
57
#include "gsicc_manage.h"
58
#include "gsicc_cache.h"
59
#include "gxclist.h"
60
#include "gxiclass.h"
61
#include "gximage.h"
62
#include "gsmatrix.h"
63
#include "gxdevsop.h"
64
#include "gsicc.h"
65
#ifdef WITH_CAL
66
#include "cal.h"
67
#define CAL_SLOP 16
68
#else
69
#define CAL_SLOP 0
70
#endif
71
#include "assert_.h"
72
#include "gxgetbit.h"
73
#include "gdevkrnlsclass.h"
74
75
#if RAW_DUMP
76
unsigned int global_index = 0;
77
unsigned int clist_band_count = 0;
78
#endif
79
80
#define DUMP_MASK_STACK 0
81
82
/* Static prototypes */
83
/* Used for filling rects when we are doing a fill with a pattern that
84
   has transparency */
85
static int pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
86
                                   gx_path * ppath, const gx_fill_params * params,
87
                                   const gx_device_color * pdevc, const gx_clip_path * pcpath);
88
static pdf14_mask_t *pdf14_mask_element_new(gs_memory_t *memory);
89
static void pdf14_free_smask_color(pdf14_device * pdev);
90
static int compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
91
                                         const gs_rect *pbbox, gs_gstate *pgs);
92
static int pdf14_clist_update_params(pdf14_clist_device * pdev,
93
                                     const gs_gstate * pgs,
94
                                     bool crop_blend_params,
95
                                     gs_pdf14trans_params_t *group_params);
96
static int pdf14_mark_fill_rectangle_ko_simple(gx_device *  dev, int x, int y,
97
                                               int w, int h, gx_color_index color,
98
                                               const gx_device_color *pdc,
99
                                               bool devn);
100
static int pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
101
                                  int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
102
                                  gx_color_index color, const gx_device_color *pdc,
103
                                  int depth, bool devn);
104
105
/* Functions for dealing with soft mask color */
106
static int pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev);
107
static int pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev);
108
109
/*
110
 * We chose the blending color space based upon the process color model of the
111
 * output device.  For gray, RGB, CMYK, or CMYK+spot devices, the choice is
112
 * usually simple.  For other devices or if the user is doing custom color
113
 * processing then the user may want to control this choice.
114
 */
115
#define AUTO_USE_CUSTOM_BLENDING 0
116
#define ALWAYS_USE_CUSTOM_BLENDING 1
117
#define DO_NOT_USE_CUSTOM_BLENDING 2
118
119
#define CUSTOM_BLENDING_MODE AUTO_USE_CUSTOM_BLENDING
120
121
# define INCR(v) DO_NOTHING
122
123
/* Forward prototypes */
124
void pdf14_cmyk_cs_to_cmyk_cm(const gx_device *, frac, frac, frac, frac, frac *);
125
static int gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
126
                                gx_device ** pdev, gx_device * target,
127
                                const gs_pdf14trans_t * pdf14pct);
128
static int gs_pdf14_clist_device_push(gs_memory_t * mem, gs_gstate * pgs,
129
                                      gx_device ** pdev, gx_device * target,
130
                                      const gs_pdf14trans_t * pdf14pct);
131
static int pdf14_tile_pattern_fill(gx_device * pdev,
132
                const gs_gstate * pgs, gx_path * ppath,
133
                const gx_fill_params * params,
134
                const gx_device_color * pdevc, const gx_clip_path * pcpath);
135
static pdf14_mask_t * pdf14_mask_element_new(gs_memory_t * memory);
136
#ifdef DEBUG
137
static void pdf14_debug_mask_stack_state(pdf14_ctx *ctx);
138
#endif
139
140
/* A structure used by the pdf14 device so that
141
   we can do the proper dance when the alphabuf
142
   device is being used */
143
typedef struct pdf14_abuf_state_s {
144
    bool op_ca_eq_CA;
145
    bool path_empty;
146
    float stroke_alpha;
147
    float fill_alpha;
148
    gs_gstate* pgs;
149
    gs_blend_mode_t blend_mode;
150
    bool group_needed;
151
    OP_FS_STATE orig_state;
152
} pdf14_abuf_state_t;
153
154
/* Buffer stack data structure */
155
gs_private_st_ptrs7(st_pdf14_buf, pdf14_buf, "pdf14_buf",
156
                    pdf14_buf_enum_ptrs, pdf14_buf_reloc_ptrs,
157
                    saved, data, backdrop, transfer_fn, mask_stack,
158
                    matte, group_color_info);
159
160
gs_private_st_ptrs3(st_pdf14_ctx, pdf14_ctx, "pdf14_ctx",
161
                    pdf14_ctx_enum_ptrs, pdf14_ctx_reloc_ptrs,
162
                    stack, mask_stack, base_color);
163
164
gs_private_st_ptrs1(st_pdf14_clr, pdf14_group_color_t, "pdf14_clr",
165
                    pdf14_clr_enum_ptrs, pdf14_clr_reloc_ptrs, previous);
166
167
gs_private_st_ptrs2(st_pdf14_mask, pdf14_mask_t, "pdf_mask",
168
                    pdf14_mask_enum_ptrs, pdf14_mask_reloc_ptrs,
169
                    rc_mask, previous);
170
171
gs_private_st_ptrs1(st_pdf14_rcmask, pdf14_rcmask_t, "pdf_rcmask",
172
                    pdf14_rcmask_enum_ptrs, pdf14_rcmask_reloc_ptrs,
173
                    mask_buf);
174
175
gs_private_st_ptrs1(st_pdf14_smaskcolor, pdf14_smaskcolor_t, "pdf14_smaskcolor",
176
                    pdf14_smaskcolor_enum_ptrs, pdf14_smaskcolor_reloc_ptrs,
177
                    profiles);
178
179
/* ------ The device descriptors ------ */
180
181
/*
182
 * Default X and Y resolution.
183
 */
184
#define X_DPI 72
185
#define Y_DPI 72
186
187
static int pdf14_initialize_device(gx_device *dev);
188
189
static  int pdf14_open(gx_device * pdev);
190
static  dev_proc_close_device(pdf14_close);
191
static  int pdf14_output_page(gx_device * pdev, int num_copies, int flush);
192
static  dev_proc_put_params(pdf14_put_params);
193
static  dev_proc_get_color_comp_index(pdf14_cmykspot_get_color_comp_index);
194
static  dev_proc_get_color_comp_index(pdf14_rgbspot_get_color_comp_index);
195
static  dev_proc_get_color_comp_index(pdf14_grayspot_get_color_comp_index);
196
static  dev_proc_get_color_mapping_procs(pdf14_cmykspot_get_color_mapping_procs);
197
static  dev_proc_get_color_mapping_procs(pdf14_rgbspot_get_color_mapping_procs);
198
static  dev_proc_get_color_mapping_procs(pdf14_grayspot_get_color_mapping_procs);
199
dev_proc_encode_color(pdf14_encode_color);
200
dev_proc_encode_color(pdf14_encode_color_tag);
201
dev_proc_decode_color(pdf14_decode_color);
202
dev_proc_encode_color(pdf14_encode_color16);
203
dev_proc_encode_color(pdf14_encode_color16_tag);
204
dev_proc_decode_color(pdf14_decode_color16);
205
static  dev_proc_fill_rectangle(pdf14_fill_rectangle);
206
static  dev_proc_fill_rectangle_hl_color(pdf14_fill_rectangle_hl_color);
207
static  dev_proc_fill_path(pdf14_fill_path);
208
static  dev_proc_fill_stroke_path(pdf14_fill_stroke_path);
209
static  dev_proc_copy_mono(pdf14_copy_mono);
210
static  dev_proc_fill_mask(pdf14_fill_mask);
211
static  dev_proc_stroke_path(pdf14_stroke_path);
212
static  dev_proc_begin_typed_image(pdf14_begin_typed_image);
213
static  dev_proc_text_begin(pdf14_text_begin);
214
static  dev_proc_composite(pdf14_composite);
215
static  dev_proc_composite(pdf14_forward_composite);
216
static  dev_proc_begin_transparency_group(pdf14_begin_transparency_group);
217
static  dev_proc_end_transparency_group(pdf14_end_transparency_group);
218
static  dev_proc_begin_transparency_mask(pdf14_begin_transparency_mask);
219
static  dev_proc_end_transparency_mask(pdf14_end_transparency_mask);
220
static  dev_proc_dev_spec_op(pdf14_dev_spec_op);
221
static  dev_proc_push_transparency_state(pdf14_push_transparency_state);
222
static  dev_proc_pop_transparency_state(pdf14_pop_transparency_state);
223
static  dev_proc_ret_devn_params(pdf14_ret_devn_params);
224
static  dev_proc_update_spot_equivalent_colors(pdf14_update_spot_equivalent_colors);
225
static  dev_proc_copy_alpha(pdf14_copy_alpha);
226
static  dev_proc_copy_planes(pdf14_copy_planes);
227
static  dev_proc_copy_alpha_hl_color(pdf14_copy_alpha_hl_color);
228
static  dev_proc_discard_transparency_layer(pdf14_discard_trans_layer);
229
static  dev_proc_strip_tile_rect_devn(pdf14_strip_tile_rect_devn);
230
static  const gx_color_map_procs *
231
    pdf14_get_cmap_procs(const gs_gstate *, const gx_device *);
232
233
#define XSIZE (int)(8.5 * X_DPI)  /* 8.5 x 11 inch page, by default */
234
#define YSIZE (int)(11 * Y_DPI)
235
236
/* 24-bit color. */
237
238
static void
239
pdf14_procs_initialize(gx_device *dev,
240
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
241
                       dev_proc_get_color_comp_index(get_color_comp_index),
242
                       dev_proc_encode_color(encode_color),
243
                       dev_proc_decode_color(decode_color))
244
9.92M
{
245
9.92M
    set_dev_proc(dev, initialize_device, pdf14_initialize_device);
246
9.92M
    set_dev_proc(dev, open_device, pdf14_open);
247
9.92M
    set_dev_proc(dev, output_page, pdf14_output_page);
248
9.92M
    set_dev_proc(dev, close_device, pdf14_close);
249
9.92M
    set_dev_proc(dev, map_rgb_color, encode_color);
250
9.92M
    set_dev_proc(dev, map_color_rgb, decode_color);
251
9.92M
    set_dev_proc(dev, fill_rectangle, pdf14_fill_rectangle);
252
9.92M
    set_dev_proc(dev, copy_mono, pdf14_copy_mono);
253
9.92M
    set_dev_proc(dev, get_params, gx_forward_get_params);
254
9.92M
    set_dev_proc(dev, put_params, pdf14_put_params);
255
9.92M
    set_dev_proc(dev, copy_alpha, pdf14_copy_alpha);
256
9.92M
    set_dev_proc(dev, fill_path, pdf14_fill_path);
257
9.92M
    set_dev_proc(dev, stroke_path, pdf14_stroke_path);
258
9.92M
    set_dev_proc(dev, fill_mask, pdf14_fill_mask);
259
9.92M
    set_dev_proc(dev, begin_typed_image, pdf14_begin_typed_image);
260
9.92M
    set_dev_proc(dev, composite, pdf14_composite);
261
9.92M
    set_dev_proc(dev, text_begin, pdf14_text_begin);
262
9.92M
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
263
9.92M
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
264
9.92M
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
265
9.92M
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
266
9.92M
    set_dev_proc(dev, discard_transparency_layer, pdf14_discard_trans_layer);
267
9.92M
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
268
9.92M
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
269
9.92M
    set_dev_proc(dev, encode_color, encode_color);
270
9.92M
    set_dev_proc(dev, decode_color, decode_color);
271
9.92M
    set_dev_proc(dev, fill_rectangle_hl_color, pdf14_fill_rectangle_hl_color);
272
9.92M
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
273
9.92M
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
274
9.92M
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
275
9.92M
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
276
9.92M
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
277
9.92M
    set_dev_proc(dev, copy_planes, pdf14_copy_planes);
278
9.92M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
279
9.92M
    set_dev_proc(dev, strip_tile_rect_devn, pdf14_strip_tile_rect_devn);
280
9.92M
    set_dev_proc(dev, copy_alpha_hl_color, pdf14_copy_alpha_hl_color);
281
9.92M
    set_dev_proc(dev, fill_stroke_path, pdf14_fill_stroke_path);
282
9.92M
}
283
284
static void
285
pdf14_Gray_initialize_device_procs(gx_device *dev)
286
2.62M
{
287
2.62M
    pdf14_procs_initialize(dev,
288
2.62M
                           gx_default_DevGray_get_color_mapping_procs,
289
2.62M
                           gx_default_DevGray_get_color_comp_index,
290
2.62M
                           pdf14_encode_color,
291
2.62M
                           pdf14_decode_color);
292
2.62M
}
293
294
static void
295
pdf14_RGB_initialize_device_procs(gx_device *dev)
296
5.44M
{
297
5.44M
    pdf14_procs_initialize(dev,
298
5.44M
                           gx_default_DevRGB_get_color_mapping_procs,
299
5.44M
                           gx_default_DevRGB_get_color_comp_index,
300
5.44M
                           pdf14_encode_color,
301
5.44M
                           pdf14_decode_color);
302
5.44M
}
303
304
static void
305
pdf14_CMYK_initialize_device_procs(gx_device *dev)
306
1.29M
{
307
1.29M
    pdf14_procs_initialize(dev,
308
1.29M
                           gx_default_DevCMYK_get_color_mapping_procs,
309
1.29M
                           gx_default_DevCMYK_get_color_comp_index,
310
1.29M
                           pdf14_encode_color,
311
1.29M
                           pdf14_decode_color);
312
1.29M
}
313
314
static void
315
pdf14_CMYKspot_initialize_device_procs(gx_device *dev)
316
435k
{
317
435k
    pdf14_procs_initialize(dev,
318
435k
                           pdf14_cmykspot_get_color_mapping_procs,
319
435k
                           pdf14_cmykspot_get_color_comp_index,
320
435k
                           pdf14_encode_color,
321
435k
                           pdf14_decode_color);
322
435k
}
323
324
static void
325
pdf14_RGBspot_initialize_device_procs(gx_device *dev)
326
125k
{
327
125k
    pdf14_procs_initialize(dev,
328
125k
                           pdf14_rgbspot_get_color_mapping_procs,
329
125k
                           pdf14_rgbspot_get_color_comp_index,
330
125k
                           pdf14_encode_color,
331
125k
                           pdf14_decode_color);
332
125k
}
333
334
static void
335
pdf14_Grayspot_initialize_device_procs(gx_device *dev)
336
30
{
337
30
    pdf14_procs_initialize(dev,
338
30
                           pdf14_grayspot_get_color_mapping_procs,
339
30
                           pdf14_grayspot_get_color_comp_index,
340
30
                           pdf14_encode_color,
341
30
                           pdf14_decode_color);
342
30
}
343
344
static void
345
pdf14_custom_initialize_device_procs(gx_device *dev)
346
0
{
347
0
    pdf14_procs_initialize(dev,
348
0
                           gx_forward_get_color_mapping_procs,
349
0
                           gx_forward_get_color_comp_index,
350
0
                           gx_forward_encode_color,
351
0
                           gx_forward_decode_color);
352
0
}
353
354
static struct_proc_finalize(pdf14_device_finalize);
355
356
gs_private_st_composite_use_final(st_pdf14_device, pdf14_device, "pdf14_device",
357
                                  pdf14_device_enum_ptrs, pdf14_device_reloc_ptrs,
358
                          pdf14_device_finalize);
359
360
static int pdf14_put_image(gx_device * dev, gs_gstate * pgs,
361
                                                        gx_device * target);
362
static int pdf14_cmykspot_put_image(gx_device * dev, gs_gstate * pgs,
363
                                                        gx_device * target);
364
static int pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs,
365
                                                        gx_device * target);
366
367
/* Alter pdf14 device color model based upon group or softmask. This occurs
368
   post clist or in immediate rendering case. Data stored with buffer */
369
static pdf14_group_color_t* pdf14_push_color_model(gx_device *dev,
370
                              gs_transparency_color_t group_color, int64_t icc_hashcode,
371
                              cmm_profile_t *iccprofile, bool is_mask);
372
static void pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color);
373
374
/* Alter clist writer device color model based upon group or softmask. Data
375
   stored in the device color model stack */
376
static int pdf14_clist_push_color_model(gx_device* dev, gx_device* cdev, gs_gstate* pgs,
377
    const gs_pdf14trans_t* pdf14pct, gs_memory_t* mem, bool is_mask);
378
static int pdf14_clist_pop_color_model(gx_device* dev, gs_gstate* pgs);
379
380
/* Used for cleaning up the stack if things go wrong */
381
static void pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs);
382
383
static const pdf14_procs_t gray_pdf14_procs = {
384
    pdf14_unpack_additive,
385
    pdf14_put_image,
386
    pdf14_unpack16_additive
387
};
388
389
static const pdf14_procs_t rgb_pdf14_procs = {
390
    pdf14_unpack_additive,
391
    pdf14_put_image,
392
    pdf14_unpack16_additive
393
};
394
395
static const pdf14_procs_t cmyk_pdf14_procs = {
396
    pdf14_unpack_subtractive,
397
    pdf14_put_image,
398
    pdf14_unpack16_subtractive
399
};
400
401
static const pdf14_procs_t cmykspot_pdf14_procs = {
402
    pdf14_unpack_custom,  /* should never be used since we will use devn values */
403
    pdf14_cmykspot_put_image,
404
    pdf14_unpack16_custom /* should never be used since we will use devn values */
405
};
406
407
static const pdf14_procs_t rgbspot_pdf14_procs = {
408
    pdf14_unpack_rgb_mix,
409
    pdf14_cmykspot_put_image,
410
    pdf14_unpack16_rgb_mix
411
};
412
413
static const pdf14_procs_t grayspot_pdf14_procs = {
414
    pdf14_unpack_gray_mix,
415
    pdf14_cmykspot_put_image,
416
    pdf14_unpack16_gray_mix
417
};
418
419
static const pdf14_procs_t custom_pdf14_procs = {
420
    pdf14_unpack_custom,
421
    pdf14_custom_put_image,
422
    pdf14_unpack16_custom
423
};
424
425
static const pdf14_nonseparable_blending_procs_t gray_blending_procs = {
426
    art_blend_luminosity_custom_8,
427
    art_blend_saturation_custom_8,
428
    art_blend_luminosity_custom_16,
429
    art_blend_saturation_custom_16
430
};
431
432
static const pdf14_nonseparable_blending_procs_t rgb_blending_procs = {
433
    art_blend_luminosity_rgb_8,
434
    art_blend_saturation_rgb_8,
435
    art_blend_luminosity_rgb_16,
436
    art_blend_saturation_rgb_16
437
};
438
439
static const pdf14_nonseparable_blending_procs_t cmyk_blending_procs = {
440
    art_blend_luminosity_cmyk_8,
441
    art_blend_saturation_cmyk_8,
442
    art_blend_luminosity_cmyk_16,
443
    art_blend_saturation_cmyk_16
444
};
445
446
static const pdf14_nonseparable_blending_procs_t rgbspot_blending_procs = {
447
    art_blend_luminosity_rgb_8,
448
    art_blend_saturation_rgb_8,
449
    art_blend_luminosity_rgb_16,
450
    art_blend_saturation_rgb_16
451
};
452
453
static const pdf14_nonseparable_blending_procs_t grayspot_blending_procs = {
454
    art_blend_luminosity_custom_8,
455
    art_blend_saturation_custom_8,
456
    art_blend_luminosity_custom_16,
457
    art_blend_saturation_custom_16
458
};
459
460
static const pdf14_nonseparable_blending_procs_t custom_blending_procs = {
461
    art_blend_luminosity_custom_8,
462
    art_blend_saturation_custom_8,
463
    art_blend_luminosity_custom_16,
464
    art_blend_saturation_custom_16
465
};
466
467
const pdf14_device gs_pdf14_Gray_device = {
468
    std_device_std_color_full_body_type(pdf14_device,
469
                                        pdf14_Gray_initialize_device_procs,
470
                                        "pdf14gray",
471
                                        &st_pdf14_device,
472
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 8,
473
                                        0, 0, 0, 0, 0, 0),
474
    { 0 },      /* Procs */
475
    NULL,     /* target */
476
    { 0 },      /* devn_params - not used */
477
    &gray_pdf14_procs,
478
    &gray_blending_procs,
479
    1
480
};
481
482
const pdf14_device gs_pdf14_RGB_device = {
483
    std_device_color_stype_body(pdf14_device,
484
                                pdf14_RGB_initialize_device_procs,
485
                                "pdf14RGB",
486
                                &st_pdf14_device,
487
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
488
    { 0 },      /* Procs */
489
    NULL,     /* target */
490
    { 0 },      /* devn_params - not used */
491
    &rgb_pdf14_procs,
492
    &rgb_blending_procs,
493
    3
494
};
495
496
const pdf14_device gs_pdf14_CMYK_device = {
497
    std_device_std_color_full_body_type(pdf14_device,
498
                                        pdf14_CMYK_initialize_device_procs,
499
                                        "pdf14cmyk",
500
                                        &st_pdf14_device,
501
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
502
                                        0, 0, 0, 0, 0, 0),
503
    { 0 },      /* Procs */
504
    NULL,     /* target */
505
    { 0 },      /* devn_params - not used */
506
    &cmyk_pdf14_procs,
507
    &cmyk_blending_procs,
508
    4
509
};
510
511
const pdf14_device gs_pdf14_CMYKspot_device = {
512
    std_device_part1_(pdf14_device,
513
                      pdf14_CMYKspot_initialize_device_procs,
514
                      "pdf14cmykspot",
515
                      &st_pdf14_device,
516
                      open_init_closed),
517
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
518
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
519
    offset_margin_values(0, 0, 0, 0, 0, 0),
520
    std_device_part3_(),
521
    { 0 },      /* Procs */
522
    NULL,     /* target */
523
    /* DeviceN parameters */
524
    { 8,      /* Not used - Bits per color */
525
      DeviceCMYKComponents, /* Names of color model colorants */
526
      4,      /* Number colorants for CMYK */
527
      0,      /* MaxSeparations has not been specified */
528
      -1,     /* PageSpotColors has not been specified */
529
      {0},      /* SeparationNames */
530
      0,      /* SeparationOrder names */
531
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
532
    },
533
    &cmykspot_pdf14_procs,
534
    &cmyk_blending_procs,
535
    4
536
};
537
538
const pdf14_device gs_pdf14_RGBspot_device = {
539
    std_device_part1_(pdf14_device,
540
                      pdf14_RGBspot_initialize_device_procs,
541
                      "pdf14rgbspot",
542
                      &st_pdf14_device,
543
                      open_init_closed),
544
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
545
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
546
    offset_margin_values(0, 0, 0, 0, 0, 0),
547
    std_device_part3_(),
548
    { 0 },      /* Procs */
549
    NULL,     /* target */
550
                    /* DeviceN parameters */
551
    { 8,      /* Not used - Bits per color */
552
    0,              /* Names of color model colorants */
553
    3,          /* Number colorants for RGB */
554
    0,          /* MaxSeparations has not been specified */
555
    -1,         /* PageSpotColors has not been specified */
556
    { 0 },      /* SeparationNames */
557
    0,          /* SeparationOrder names */
558
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
559
    },
560
    &rgbspot_pdf14_procs,
561
    &rgbspot_blending_procs,
562
    3
563
};
564
565
const pdf14_device gs_pdf14_Grayspot_device = {
566
    std_device_part1_(pdf14_device,
567
                      pdf14_Grayspot_initialize_device_procs,
568
                      "pdf14grayspot",
569
                      &st_pdf14_device,
570
                      open_init_closed),
571
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
572
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
573
    offset_margin_values(0, 0, 0, 0, 0, 0),
574
    std_device_part3_(),
575
    { 0 },      /* Procs */
576
    NULL,     /* target */
577
                    /* DeviceN parameters */
578
    { 8,      /* Not used - Bits per color */
579
    0,              /* Names of color model colorants */
580
    3,          /* Number colorants for RGB */
581
    0,          /* MaxSeparations has not been specified */
582
    -1,         /* PageSpotColors has not been specified */
583
    { 0 },      /* SeparationNames */
584
    0,          /* SeparationOrder names */
585
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
586
    },
587
    &grayspot_pdf14_procs,
588
    &grayspot_blending_procs,
589
    1
590
};
591
592
/*
593
 * The 'custom' PDF 1.4 compositor device is for working with those devices
594
 * which support spot colors but do not have a CMYK process color model.
595
 *
596
 * This causes some problems with the Hue, Saturation, Color, and Luminosity
597
 * blending modes.  These blending modes are 'non separable' and depend upon
598
 * knowing the details of the blending color space.  However we use the
599
 * process color model of the output device for our blending color space.
600
 * With an unknown process color model, we have to fall back to some 'guesses'
601
 * about how to treat these blending modes.
602
 */
603
const pdf14_device gs_pdf14_custom_device = {
604
    std_device_part1_(pdf14_device,
605
                      pdf14_custom_initialize_device_procs,
606
                      "pdf14custom",
607
                      &st_pdf14_device,
608
                      open_init_closed),
609
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
610
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
611
    offset_margin_values(0, 0, 0, 0, 0, 0),
612
    std_device_part3_(),
613
    { 0 },      /* Procs */
614
    NULL,     /* target */
615
    /* DeviceN parameters */
616
    { 8,      /* Not used - Bits per color */
617
      DeviceCMYKComponents, /* Names of color model colorants */
618
      4,      /* Number colorants for CMYK */
619
      0,      /* MaxSeparations has not been specified */
620
      -1,     /* PageSpotColors has not been specified */
621
      {0},      /* SeparationNames */
622
      0,      /* SeparationOrder names */
623
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
624
    },
625
    &custom_pdf14_procs,
626
    &custom_blending_procs,
627
    4
628
};
629
630
/* Devices used for pdf14-accum-* device, one for  each image colorspace, */
631
/* Gray, RGB, CMYK, DeviceN. Before calling gdev_prn_open, the following  */
632
/* are set from the target device: width, height, xdpi, ydpi, MaxBitmap.  */
633
634
static dev_proc_print_page(no_print_page);
635
static  dev_proc_ret_devn_params(pdf14_accum_ret_devn_params);
636
static  dev_proc_get_color_comp_index(pdf14_accum_get_color_comp_index);
637
static  dev_proc_get_color_mapping_procs(pdf14_accum_get_color_mapping_procs);
638
static  dev_proc_update_spot_equivalent_colors(pdf14_accum_update_spot_equivalent_colors);
639
640
static int
641
no_print_page(gx_device_printer *pdev, gp_file *prn_stream)
642
0
{
643
0
    return_error(gs_error_unknownerror);
644
0
}
645
646
struct gx_device_pdf14_accum_s {
647
    gx_devn_prn_device_common;
648
    gx_device *save_p14dev;   /* the non-clist pdf14 deivce saved for after accum */
649
};
650
typedef struct gx_device_pdf14_accum_s gx_device_pdf14_accum;
651
652
int
653
pdf14_accum_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size)
654
25.3M
{
655
25.3M
    gx_device_pdf14_accum *adev = (gx_device_pdf14_accum *)pdev;
656
657
25.3M
    if (dev_spec_op == gxdso_device_child) {
658
4.47k
        gxdso_device_child_request *req = (gxdso_device_child_request *)data;
659
4.47k
        if (size < sizeof(*req))
660
0
            return gs_error_unknownerror;
661
4.47k
        req->target = adev->save_p14dev;
662
4.47k
        req->n = 0;
663
4.47k
        return 0;
664
4.47k
    }
665
666
25.3M
    return gdev_prn_dev_spec_op(pdev, dev_spec_op, data, size);
667
25.3M
}
668
669
gs_private_st_suffix_add1_final(st_gx_devn_accum_device, gx_device_pdf14_accum,
670
        "gx_device_pdf14_accum", pdf14_accum_device_enum_ptrs, pdf14_accum_device_reloc_ptrs,
671
                          gx_devn_prn_device_finalize, st_gx_devn_prn_device, save_p14dev);
672
673
static void
674
pdf14_accum_Gray_initialize_device_procs(gx_device *dev)
675
1.35k
{
676
1.35k
    gdev_prn_initialize_device_procs_gray8(dev);
677
678
1.35k
    set_dev_proc(dev, encode_color, gx_default_8bit_map_gray_color);
679
1.35k
    set_dev_proc(dev, decode_color, gx_default_8bit_map_color_gray);
680
1.35k
}
681
682
const gx_device_pdf14_accum pdf14_accum_Gray = {
683
    prn_device_stype_body(gx_device_pdf14_accum,
684
                          pdf14_accum_Gray_initialize_device_procs,
685
                          "pdf14-accum-Gray",
686
                          &st_gx_devn_accum_device,
687
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
688
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
689
                          1/*ncomp*/, 8/*depth*/, 255/*max_gray*/, 0/*max_color*/,
690
                          256/*dither_grays*/, 0/*dither_colors*/,
691
                          no_print_page),
692
    { 0 },      /* devn_params - not used */
693
    { 0 },      /* equivalent_cmyk_color_params - not used */
694
    0/*save_p14dev*/
695
};
696
697
static void
698
pdf14_accum_RGB_initialize_device_procs(gx_device *dev)
699
5.39k
{
700
5.39k
    gdev_prn_initialize_device_procs_rgb(dev);
701
5.39k
}
702
703
const gx_device_pdf14_accum pdf14_accum_RGB = {
704
    prn_device_stype_body(gx_device_pdf14_accum,
705
                          pdf14_accum_RGB_initialize_device_procs,
706
                          "pdf14-accum-RGB",
707
                          &st_gx_devn_accum_device,
708
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
709
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
710
                          3/*ncomp*/, 24/*depth*/, 0/*max_gray*/, 255/*max_color*/,
711
                          1/*dither_grays*/, 256/*dither_colors*/,
712
                          no_print_page),
713
    { 0 },      /* devn_params - not used */
714
    { 0 },      /* equivalent_cmyk_color_params - not used */
715
    0/*save_p14dev*/
716
};
717
718
static void
719
pdf14_accum_CMYK_initialize_device_procs(gx_device *dev)
720
0
{
721
0
    gdev_prn_initialize_device_procs_cmyk8(dev);
722
723
0
    set_dev_proc(dev, encode_color, cmyk_8bit_map_cmyk_color);
724
0
    set_dev_proc(dev, decode_color, cmyk_8bit_map_color_cmyk);
725
0
}
726
727
const gx_device_pdf14_accum pdf14_accum_CMYK = {
728
    prn_device_stype_body(gx_device_pdf14_accum,
729
                          pdf14_accum_CMYK_initialize_device_procs,
730
                          "pdf14-accum-CMYK",
731
                          &st_gx_devn_accum_device,
732
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
733
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
734
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
735
                          256/*dither_grays*/, 256/*dither_colors*/,
736
                          no_print_page),
737
    { 0 },      /* devn_params - not used */
738
    { 0 },      /* equivalent_cmyk_color_params - not used */
739
    0/*save_p14dev*/
740
};
741
742
static void
743
pdf14_accum_initialize_device_procs_cmykspot(gx_device *dev)
744
0
{
745
0
    pdf14_accum_CMYK_initialize_device_procs(dev);
746
747
0
    set_dev_proc(dev, get_color_mapping_procs, pdf14_accum_get_color_mapping_procs);
748
0
    set_dev_proc(dev, get_color_comp_index, pdf14_accum_get_color_comp_index);
749
0
    set_dev_proc(dev, update_spot_equivalent_colors, pdf14_accum_update_spot_equivalent_colors);
750
0
    set_dev_proc(dev, ret_devn_params, pdf14_accum_ret_devn_params);
751
0
}
752
753
const gx_device_pdf14_accum pdf14_accum_CMYKspot = {
754
    prn_device_stype_body(gx_device_pdf14_accum,
755
                          pdf14_accum_initialize_device_procs_cmykspot,
756
                          "pdf14-accum-CMYKspot",
757
                          &st_gx_devn_accum_device,
758
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
759
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
760
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
761
                          256/*dither_grays*/, 256/*dither_colors*/,
762
                          no_print_page),
763
    /* DeviceN parameters */
764
    { 8,      /* Not used - Bits per color */
765
      DeviceCMYKComponents, /* Names of color model colorants */
766
      4,      /* Number colorants for CMYK */
767
      0,      /* MaxSeparations has not been specified */
768
      -1,     /* PageSpotColors has not been specified */
769
      { 0 },      /* SeparationNames */
770
      0,      /* SeparationOrder names */
771
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
772
    },
773
    { true },     /* equivalent_cmyk_color_params */
774
    0/*save_p14dev*/
775
};
776
777
/* GC procedures */
778
static
779
0
ENUM_PTRS_WITH(pdf14_device_enum_ptrs, pdf14_device *pdev)
780
0
{
781
0
    index -= 5;
782
0
    if (index < pdev->devn_params.separations.num_separations)
783
0
        ENUM_RETURN(pdev->devn_params.separations.names[index].data);
784
0
    index -= pdev->devn_params.separations.num_separations;
785
0
    if (index < pdev->devn_params.pdf14_separations.num_separations)
786
0
        ENUM_RETURN(pdev->devn_params.pdf14_separations.names[index].data);
787
0
    return 0;
788
0
}
789
0
case 0: return ENUM_OBJ(pdev->ctx);
790
0
case 1: return ENUM_OBJ(pdev->color_model_stack);
791
0
case 2: return ENUM_OBJ(pdev->smaskcolor);
792
0
case 3: ENUM_RETURN(gx_device_enum_ptr(pdev->target));
793
0
case 4: ENUM_RETURN(gx_device_enum_ptr(pdev->pclist_device));
794
0
ENUM_PTRS_END
795
796
0
static  RELOC_PTRS_WITH(pdf14_device_reloc_ptrs, pdf14_device *pdev)
797
0
{
798
0
    {
799
0
        int i;
800
801
0
        for (i = 0; i < pdev->devn_params.separations.num_separations; ++i) {
802
0
            RELOC_PTR(pdf14_device, devn_params.separations.names[i].data);
803
0
        }
804
0
    }
805
0
    RELOC_VAR(pdev->ctx);
806
0
    RELOC_VAR(pdev->smaskcolor);
807
0
    RELOC_VAR(pdev->color_model_stack);
808
0
    pdev->target = gx_device_reloc_ptr(pdev->target, gcst);
809
0
    pdev->pclist_device = gx_device_reloc_ptr(pdev->pclist_device, gcst);
810
0
}
811
0
RELOC_PTRS_END
812
813
/* ------ Private definitions ------ */
814
815
static void
816
resolve_matte(pdf14_buf *maskbuf, byte *src_data, intptr_t src_planestride, intptr_t src_rowstride,
817
              int width, int height, cmm_profile_t *src_profile, int deep)
818
1.84k
{
819
1.84k
    if (deep) {
820
0
        int x, y, i;
821
0
        uint16_t *mask_row_ptr  = (uint16_t *)maskbuf->data;
822
0
        uint16_t *src_row_ptr   = (uint16_t *)src_data;
823
0
        uint16_t *mask_tr_fn    = (uint16_t *)maskbuf->transfer_fn;
824
825
0
        src_planestride >>= 1;
826
0
        src_rowstride >>= 1;
827
828
0
        for (y = 0; y < height; y++) {
829
0
            uint16_t *mask_curr_ptr = mask_row_ptr;
830
0
            uint16_t *src_curr_ptr = src_row_ptr;
831
0
            for (x = 0; x < width; x++) {
832
0
                uint16_t idx = *mask_curr_ptr;
833
0
                byte     top = idx>>8;
834
0
                uint16_t a   = mask_tr_fn[top];
835
0
                int      b   = mask_tr_fn[top+1]-a;
836
0
                uint16_t matte_alpha = a + ((0x80 + b*(idx & 0xff))>>8);
837
838
                /* matte's happen rarely enough that we allow ourselves to
839
                 * resort to 64bit here. */
840
0
                if (matte_alpha != 0 && matte_alpha != 0xffff) {
841
0
                    for (i = 0; i < src_profile->num_comps; i++) {
842
0
                        int val = src_curr_ptr[i * src_planestride] - maskbuf->matte[i];
843
0
                        int temp = (((int64_t)val) * 0xffff / matte_alpha) + maskbuf->matte[i];
844
845
                        /* clip */
846
0
                        if (temp > 0xffff)
847
0
                            src_curr_ptr[i * src_planestride] = 0xffff;
848
0
                        else if (temp < 0)
849
0
                            src_curr_ptr[i * src_planestride] = 0;
850
0
                        else
851
0
                            src_curr_ptr[i * src_planestride] = temp;
852
0
                    }
853
0
                }
854
0
                mask_curr_ptr++;
855
0
                src_curr_ptr++;
856
0
            }
857
0
            src_row_ptr += src_rowstride;
858
0
            mask_row_ptr += (maskbuf->rowstride>>1);
859
0
        }
860
1.84k
    } else {
861
1.84k
        int x, y, i;
862
1.84k
        byte *mask_row_ptr  = maskbuf->data;
863
1.84k
        byte *src_row_ptr   = src_data;
864
1.84k
        byte *mask_tr_fn    = maskbuf->transfer_fn;
865
866
23.7k
        for (y = 0; y < height; y++) {
867
21.8k
            byte *mask_curr_ptr = mask_row_ptr;
868
21.8k
            byte *src_curr_ptr = src_row_ptr;
869
27.6M
            for (x = 0; x < width; x++) {
870
27.6M
                byte matte_alpha = mask_tr_fn[*mask_curr_ptr];
871
27.6M
                if (matte_alpha != 0 && matte_alpha != 0xff) {
872
17.5M
                    for (i = 0; i < src_profile->num_comps; i++) {
873
13.1M
                        byte matte = maskbuf->matte[i]>>8;
874
13.1M
                        int val = src_curr_ptr[i * src_planestride] - matte;
875
13.1M
                        int temp = ((((val * 0xff) << 8) / matte_alpha) >> 8) + matte;
876
877
                        /* clip */
878
13.1M
                        if (temp > 0xff)
879
8.00M
                            src_curr_ptr[i * src_planestride] = 0xff;
880
5.18M
                        else if (temp < 0)
881
0
                            src_curr_ptr[i * src_planestride] = 0;
882
5.18M
                        else
883
5.18M
                            src_curr_ptr[i * src_planestride] = temp;
884
13.1M
                    }
885
4.39M
                }
886
27.6M
                mask_curr_ptr++;
887
27.6M
                src_curr_ptr++;
888
27.6M
            }
889
21.8k
            src_row_ptr += src_rowstride;
890
21.8k
            mask_row_ptr += maskbuf->rowstride;
891
21.8k
        }
892
1.84k
    }
893
1.84k
}
894
895
/* Transform of color data and copy noncolor data.  Used in
896
   group pop and during the pdf14 put image calls when the blend color space
897
   is different than the target device color space.  The function will try do
898
   in-place conversion if possible.  If not, it will do an allocation.  The
899
   put_image call needs to know if an allocation was made so that it can adjust
900
   for the fact that we likely don't have a full page any longer and we don't
901
   need to do the offset to our data in the buffer. Bug 700686: If we are in
902
   a softmask that includes a matte entry, then we need to undo the matte
903
   entry here at this time in the image's native color space not the parent
904
   color space.   The endian_swap term here is only set to true if the data
905
   has been baked as BE during the put_image blending operation and we are
906
   on a LE machine.  */
907
static forceinline pdf14_buf*
908
template_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
909
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
910
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
911
    bool has_matte, bool deep, bool endian_swap, int num_channels_to_lose)
912
35.3k
{
913
35.3k
    gsicc_rendering_param_t rendering_params;
914
35.3k
    gsicc_link_t *icc_link;
915
35.3k
    gsicc_bufferdesc_t src_buff_desc;
916
35.3k
    gsicc_bufferdesc_t des_buff_desc;
917
35.3k
    intptr_t src_planestride = src_buf->planestride;
918
35.3k
    intptr_t src_rowstride = src_buf->rowstride;
919
35.3k
    int src_n_planes = src_buf->n_planes;
920
35.3k
    int src_n_chan = src_buf->n_chan;
921
35.3k
    intptr_t des_planestride = src_planestride;
922
35.3k
    intptr_t des_rowstride = src_rowstride;
923
35.3k
    int des_n_planes = src_n_planes;
924
35.3k
    int des_n_chan = src_n_chan;
925
35.3k
    int diff;
926
35.3k
    int k, j;
927
35.3k
    byte *des_data = NULL;
928
35.3k
    pdf14_buf *output = src_buf;
929
35.3k
    pdf14_mask_t *mask_stack;
930
35.3k
    pdf14_buf *maskbuf;
931
35.3k
    int code;
932
933
35.3k
    *did_alloc = false;
934
935
    /* Same profile */
936
35.3k
    if (gsicc_get_hash(src_profile) == gsicc_get_hash(des_profile))
937
0
        return src_buf;
938
939
    /* Define the rendering intent get the link */
940
35.3k
    rendering_params.black_point_comp = gsBLACKPTCOMP_ON;
941
35.3k
    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
942
35.3k
    rendering_params.override_icc = false;
943
35.3k
    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
944
35.3k
    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;  /* Use relative intent */
945
35.3k
    rendering_params.cmm = gsCMM_DEFAULT;
946
35.3k
    icc_link = gsicc_get_link_profile(pgs, dev, src_profile, des_profile,
947
35.3k
        &rendering_params, pgs->memory, false);
948
35.3k
    if (icc_link == NULL)
949
0
        return NULL;
950
951
    /* If different data sizes, we have to do an allocation */
952
35.3k
    diff = des_profile->num_comps - src_profile->num_comps;
953
35.3k
    if (diff != 0) {
954
34.9k
        byte *src_ptr;
955
34.9k
        byte *des_ptr;
956
957
34.9k
        *did_alloc = true;
958
34.9k
        des_rowstride = ((width + 3) & -4)<<deep;
959
34.9k
        des_planestride = height * des_rowstride;
960
34.9k
        des_n_planes = src_n_planes + diff - num_channels_to_lose;
961
34.9k
        des_n_chan = src_n_chan + diff;
962
34.9k
        des_data = gs_alloc_bytes(ctx->memory,
963
34.9k
                                  des_planestride * des_n_planes + CAL_SLOP,
964
34.9k
                                  "pdf14_transform_color_buffer");
965
34.9k
        if (des_data == NULL)
966
0
            return NULL;
967
968
        /* Copy over the noncolor planes. May only be a dirty part, so have
969
           to copy row by row */
970
34.9k
        src_ptr = src_data;
971
34.9k
        des_ptr = des_data;
972
386k
        for (j = 0; j < height; j++) {
973
719k
            for (k = 0; k < (src_n_planes - src_profile->num_comps); k++) {
974
368k
                memcpy(des_ptr + des_planestride * (k + des_profile->num_comps - num_channels_to_lose),
975
368k
                       src_ptr + src_planestride * (k + src_profile->num_comps),
976
368k
                       width<<deep);
977
368k
            }
978
351k
            src_ptr += src_rowstride;
979
351k
            des_ptr += des_rowstride;
980
351k
        }
981
34.9k
    } else
982
423
        des_data = src_data;
983
984
    /* Set up the buffer descriptors. */
985
35.3k
    gsicc_init_buffer(&src_buff_desc, src_profile->num_comps, 1<<deep, false,
986
35.3k
                      false, true, src_planestride, src_rowstride, height, width);
987
35.3k
    gsicc_init_buffer(&des_buff_desc, des_profile->num_comps, 1<<deep, false,
988
35.3k
                      false, true, des_planestride, des_rowstride, height, width);
989
990
35.3k
    src_buff_desc.endian_swap = endian_swap;
991
35.3k
    des_buff_desc.endian_swap = endian_swap;
992
993
    /* If we have a matte entry, undo the pre-blending now.  Also set pdf14
994
       context to ensure that this is not done again during the group
995
       composition */
996
35.3k
    if (has_matte &&
997
        /* Should always happen, but check for safety */
998
2.41k
        ((mask_stack = ctx->mask_stack) != NULL) &&
999
2.41k
        ((maskbuf = mask_stack->rc_mask->mask_buf) != NULL) &&
1000
2.41k
         (maskbuf->data != NULL))
1001
1.84k
    {
1002
1.84k
        resolve_matte(maskbuf, src_data, src_planestride, src_rowstride, width, height, src_profile, deep);
1003
1.84k
    }
1004
1005
    /* Transform the data. Since the pdf14 device should be using RGB, CMYK or
1006
       Gray buffers, this transform does not need to worry about the cmap procs
1007
       of the target device. */
1008
35.3k
    code = (icc_link->procs.map_buffer)(dev, icc_link, &src_buff_desc, &des_buff_desc,
1009
35.3k
        src_data, des_data);
1010
35.3k
    gsicc_release_link(icc_link);
1011
35.3k
    if (code < 0)
1012
0
        return NULL;
1013
1014
35.3k
    output->planestride = des_planestride;
1015
35.3k
    output->rowstride = des_rowstride;
1016
35.3k
    output->n_planes = des_n_planes;
1017
35.3k
    output->n_chan = des_n_chan;
1018
    /* If not in-place conversion, then release. */
1019
35.3k
    if (des_data != src_data) {
1020
34.9k
        gs_free_object(ctx->memory, output->data,
1021
34.9k
            "pdf14_transform_color_buffer");
1022
34.9k
        output->data = des_data;
1023
        /* Note, this is needed for case where we did a put image, as the
1024
           resulting transformed buffer may not be a full page. */
1025
34.9k
        output->rect.p.x = x0;
1026
34.9k
        output->rect.p.y = y0;
1027
34.9k
        output->rect.q.x = x0 + width;
1028
34.9k
        output->rect.q.y = y0 + height;
1029
34.9k
    }
1030
35.3k
    return output;
1031
35.3k
}
1032
1033
/* This is a routine to do memset's but with 16 bit values.
1034
 * Note, that we still take bytes, NOT "num values to set".
1035
 * We assume dest is 16 bit aligned. We assume that bytes is
1036
 * a multiple of 2. */
1037
static void gs_memset16(byte *dest_, uint16_t value, int bytes)
1038
0
{
1039
0
    uint16_t *dest = (uint16_t *)(void *)dest_;
1040
0
    uint32_t v;
1041
0
    if (bytes < 0)
1042
0
        return;
1043
0
    if (((intptr_t)dest) & 2) {
1044
0
        *dest++ = value;
1045
0
        bytes--;
1046
0
        if (bytes == 0)
1047
0
            return;
1048
0
    }
1049
0
    v = value | (value<<16);
1050
0
    bytes -= 2;
1051
0
    while (bytes > 0) {
1052
0
        *(uint32_t *)dest = v;
1053
0
        dest += 2;
1054
0
        bytes -= 4;
1055
0
    }
1056
0
    bytes += 2;
1057
0
    if (bytes & 2) {
1058
0
        *dest = value;
1059
0
    }
1060
0
}
1061
1062
static pdf14_buf*
1063
pdf14_transform_color_buffer_no_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1064
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1065
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1066
    bool deep, bool endian_swap, int num_channels_to_lose)
1067
32.9k
{
1068
32.9k
    if (deep)
1069
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1070
0
            des_profile, x0, y0, width, height, did_alloc, false, true, endian_swap, num_channels_to_lose);
1071
32.9k
    else
1072
32.9k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1073
32.9k
            des_profile, x0, y0, width, height, did_alloc, false, false, endian_swap, num_channels_to_lose);
1074
32.9k
}
1075
1076
static pdf14_buf*
1077
pdf14_transform_color_buffer_with_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1078
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1079
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1080
    bool deep, bool endian_swap)
1081
2.41k
{
1082
2.41k
    if (deep)
1083
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1084
0
            des_profile, x0, y0, width, height, did_alloc, true, true, endian_swap, false);
1085
2.41k
    else
1086
2.41k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1087
2.41k
            des_profile, x0, y0, width, height, did_alloc, true, false, endian_swap, false);
1088
2.41k
}
1089
1090
/**
1091
 * pdf14_buf_new: Allocate a new PDF 1.4 buffer.
1092
 * @n_chan: Number of pixel channels including alpha, but not including
1093
 * shape, group alpha, or tags.
1094
 *
1095
 * Return value: Newly allocated buffer, or NULL on failure.
1096
 **/
1097
static  pdf14_buf *
1098
pdf14_buf_new(gs_int_rect *rect, bool has_tags, bool has_alpha_g,
1099
              bool has_shape, bool idle, int n_chan, int num_spots,
1100
              gs_memory_t *memory, bool deep)
1101
6.86M
{
1102
1103
    /* Note that alpha_g is the alpha for the GROUP */
1104
    /* This is distinct from the alpha that may also exist */
1105
    /* for the objects within the group.  Hence it can introduce */
1106
    /* yet another plane */
1107
1108
6.86M
    pdf14_buf *result;
1109
6.86M
    int64_t rowstride = ((size_t)((rect->q.x - rect->p.x + 3) & -4))<<deep;
1110
6.86M
    int64_t height = (rect->q.y - rect->p.y);
1111
6.86M
    int n_planes = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0) +
1112
6.86M
                   (has_tags ? 1 : 0);
1113
6.86M
    size_t planestride;
1114
#if ARCH_SIZEOF_SIZE_T <= 4
1115
    int64_t dsize = rowstride * height * n_planes;
1116
1117
    if (dsize > max_size_t)
1118
        return NULL;
1119
#endif
1120
1121
6.86M
    result = gs_alloc_struct(memory, pdf14_buf, &st_pdf14_buf,
1122
6.86M
                             "pdf14_buf_new");
1123
6.86M
    if (result == NULL)
1124
0
        return result;
1125
1126
6.86M
    result->memory = memory;
1127
6.86M
    result->backdrop = NULL;
1128
6.86M
    result->saved = NULL;
1129
6.86M
    result->isolated = false;
1130
6.86M
    result->knockout = false;
1131
6.86M
    result->has_alpha_g = has_alpha_g;
1132
6.86M
    result->has_shape = has_shape;
1133
6.86M
    result->has_tags = has_tags;
1134
6.86M
    result->rect = *rect;
1135
6.86M
    result->n_chan = n_chan;
1136
6.86M
    result->n_planes = n_planes;
1137
6.86M
    result->rowstride = rowstride;
1138
6.86M
    result->transfer_fn = NULL;
1139
6.86M
    result->is_ident = true;
1140
6.86M
    result->matte_num_comps = 0;
1141
6.86M
    result->matte = NULL;
1142
6.86M
    result->mask_stack = NULL;
1143
6.86M
    result->idle = idle;
1144
6.86M
    result->mask_id = 0;
1145
6.86M
    result->num_spots = num_spots;
1146
6.86M
    result->deep = deep;
1147
6.86M
    result->page_group = false;
1148
6.86M
    result->group_color_info = NULL;
1149
6.86M
    result->group_popped = false;
1150
1151
6.86M
    if (idle || height <= 0) {
1152
        /* Empty clipping - will skip all drawings. */
1153
3.59M
        result->planestride = 0;
1154
3.59M
        result->data = 0;
1155
3.59M
    } else {
1156
3.27M
        planestride = rowstride * height;
1157
3.27M
        result->planestride = planestride;
1158
3.27M
        result->data = gs_alloc_bytes(memory,
1159
3.27M
                                      planestride * n_planes + CAL_SLOP,
1160
3.27M
                                      "pdf14_buf_new");
1161
3.27M
        if (result->data == NULL) {
1162
0
            gs_free_object(memory, result, "pdf14_buf_new");
1163
0
            return NULL;
1164
0
        }
1165
3.27M
        if (has_alpha_g) {
1166
531k
            int alpha_g_plane = n_chan + (has_shape ? 1 : 0);
1167
            /* Memsetting by 0, so this copes with the deep case too */
1168
531k
            memset(result->data + alpha_g_plane * planestride, 0, planestride);
1169
531k
        }
1170
3.27M
        if (has_tags) {
1171
0
            int tags_plane = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0);
1172
            /* Memsetting by 0, so this copes with the deep case too */
1173
0
            memset (result->data + tags_plane * planestride,
1174
0
                    GS_UNTOUCHED_TAG, planestride);
1175
0
        }
1176
3.27M
    }
1177
    /* Initialize dirty box with an invalid rectangle (the reversed rectangle).
1178
     * Any future drawing will make it valid again, so we won't blend back
1179
     * more than we need. */
1180
6.86M
    result->dirty.p.x = rect->q.x;
1181
6.86M
    result->dirty.p.y = rect->q.y;
1182
6.86M
    result->dirty.q.x = rect->p.x;
1183
6.86M
    result->dirty.q.y = rect->p.y;
1184
6.86M
    return result;
1185
6.86M
}
1186
1187
static  void
1188
pdf14_buf_free(pdf14_buf *buf)
1189
6.86M
{
1190
6.86M
    pdf14_group_color_t *group_color_info = buf->group_color_info;
1191
6.86M
    gs_memory_t *memory = buf->memory;
1192
1193
6.86M
    if (buf->mask_stack && buf->mask_stack->rc_mask)
1194
6.86M
        rc_decrement(buf->mask_stack->rc_mask, "pdf14_buf_free");
1195
1196
6.86M
    gs_free_object(memory, buf->mask_stack, "pdf14_buf_free");
1197
6.86M
    gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free");
1198
6.86M
    gs_free_object(memory, buf->matte, "pdf14_buf_free");
1199
6.86M
    gs_free_object(memory, buf->data, "pdf14_buf_free");
1200
1201
13.7M
    while (group_color_info) {
1202
6.86M
       if (group_color_info->icc_profile != NULL) {
1203
6.86M
           gsicc_adjust_profile_rc(group_color_info->icc_profile, -1, "pdf14_buf_free");
1204
6.86M
       }
1205
6.86M
       buf->group_color_info = group_color_info->previous;
1206
6.86M
       gs_free_object(memory, group_color_info, "pdf14_buf_free");
1207
6.86M
       group_color_info = buf->group_color_info;
1208
6.86M
    }
1209
1210
6.86M
    gs_free_object(memory, buf->backdrop, "pdf14_buf_free");
1211
6.86M
    gs_free_object(memory, buf, "pdf14_buf_free");
1212
6.86M
}
1213
1214
static void
1215
rc_pdf14_maskbuf_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
1216
2.96M
{
1217
    /* Ending the mask buffer. */
1218
2.96M
    pdf14_rcmask_t *rcmask = (pdf14_rcmask_t * ) ptr_in;
1219
    /* free the pdf14 buffer. */
1220
2.96M
    if ( rcmask->mask_buf != NULL ){
1221
346k
        pdf14_buf_free(rcmask->mask_buf);
1222
346k
    }
1223
2.96M
    gs_free_object(mem, rcmask, "rc_pdf14_maskbuf_free");
1224
2.96M
}
1225
1226
static  pdf14_rcmask_t *
1227
pdf14_rcmask_new(gs_memory_t *memory)
1228
2.96M
{
1229
2.96M
    pdf14_rcmask_t *result;
1230
1231
2.96M
    result = gs_alloc_struct(memory, pdf14_rcmask_t, &st_pdf14_rcmask,
1232
2.96M
                             "pdf14_maskbuf_new");
1233
2.96M
    if (result == NULL)
1234
0
        return NULL;
1235
2.96M
    rc_init_free(result, memory, 1, rc_pdf14_maskbuf_free);
1236
2.96M
    result->mask_buf = NULL;
1237
2.96M
    result->memory = memory;
1238
2.96M
    return result;
1239
2.96M
}
1240
1241
static  pdf14_ctx *
1242
pdf14_ctx_new(gx_device *dev, bool deep)
1243
1.96M
{
1244
1.96M
    pdf14_ctx *result;
1245
1.96M
    gs_memory_t *memory = dev->memory->stable_memory;
1246
1247
1.96M
    result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx, "pdf14_ctx_new");
1248
1.96M
    if (result == NULL)
1249
0
        return result;
1250
1.96M
    result->stack = NULL;
1251
1.96M
    result->mask_stack = pdf14_mask_element_new(memory);
1252
1.96M
    result->mask_stack->rc_mask = pdf14_rcmask_new(memory);
1253
1.96M
    result->memory = memory;
1254
1.96M
    result->smask_depth = 0;
1255
1.96M
    result->smask_blend = false;
1256
1.96M
    result->deep = deep;
1257
1.96M
    result->base_color = NULL;
1258
1.96M
    return result;
1259
1.96M
}
1260
1261
static  void
1262
pdf14_ctx_free(pdf14_ctx *ctx)
1263
1.96M
{
1264
1.96M
    pdf14_buf *buf, *next;
1265
1266
1.96M
    if (ctx->base_color) {
1267
1.13M
       gsicc_adjust_profile_rc(ctx->base_color->icc_profile, -1, "pdf14_ctx_free");
1268
1.13M
        gs_free_object(ctx->memory, ctx->base_color, "pdf14_ctx_free");
1269
1.13M
    }
1270
1.96M
    if (ctx->mask_stack) {
1271
        /* A mask was created but was not used in this band. */
1272
799k
        rc_decrement(ctx->mask_stack->rc_mask, "pdf14_ctx_free");
1273
799k
        gs_free_object(ctx->memory, ctx->mask_stack, "pdf14_ctx_free");
1274
799k
    }
1275
3.70M
    for (buf = ctx->stack; buf != NULL; buf = next) {
1276
1.74M
        next = buf->saved;
1277
1.74M
        pdf14_buf_free(buf);
1278
1.74M
    }
1279
1.96M
    gs_free_object (ctx->memory, ctx, "pdf14_ctx_free");
1280
1.96M
}
1281
1282
/**
1283
 * pdf14_find_backdrop_buf: Find backdrop buffer.
1284
 *
1285
 * Return value: Backdrop buffer for current group operation, or NULL
1286
 * if backdrop is fully transparent.
1287
 **/
1288
static  pdf14_buf *
1289
pdf14_find_backdrop_buf(pdf14_ctx *ctx, bool *is_backdrop)
1290
1.85M
{
1291
    /* Our new buffer is buf */
1292
1.85M
    pdf14_buf *buf = ctx->stack;
1293
1294
1.85M
    *is_backdrop = false;
1295
1296
1.85M
    if (buf != NULL) {
1297
        /* If the new buffer is isolated there is no backdrop */
1298
1.85M
        if (buf->isolated) return NULL;
1299
1300
        /* If the previous buffer is a knockout group
1301
           then we need to use its backdrop as the backdrop. If
1302
           it was isolated then that back drop was NULL */
1303
531k
        if (buf->saved != NULL && buf->saved->knockout) {
1304
            /* Per the spec, if we have a non-isolated group
1305
               in a knockout group the non-isolated group
1306
               uses the backdrop of its parent group (the knockout group)
1307
               as its own backdrop.  The non-isolated group must
1308
               go through the standard re-composition operation
1309
               to avoid the double application of the backdrop */
1310
28
            *is_backdrop = true;
1311
28
            return buf->saved;
1312
28
        }
1313
        /* This should be the non-isolated case where its parent is
1314
           not a knockout */
1315
531k
        if (buf->saved != NULL) {
1316
531k
            return buf->saved;
1317
531k
        }
1318
531k
    }
1319
0
    return NULL;
1320
1.85M
}
1321
1322
static pdf14_group_color_t*
1323
pdf14_make_base_group_color(gx_device* dev)
1324
1.13M
{
1325
1.13M
    pdf14_device* pdev = (pdf14_device*)dev;
1326
1.13M
    pdf14_group_color_t* group_color;
1327
1.13M
    bool deep = pdev->ctx->deep;
1328
1.13M
    bool has_tags = device_encodes_tags(dev);
1329
1330
1.13M
    if_debug0m('v', dev->memory, "[v]pdf14_make_base_group_color\n");
1331
1332
1.13M
    group_color = gs_alloc_struct(pdev->ctx->memory,
1333
1.13M
        pdf14_group_color_t, &st_pdf14_clr,
1334
1.13M
        "pdf14_make_base_group_color");
1335
1336
1.13M
    if (group_color == NULL)
1337
0
        return NULL;
1338
1.13M
    memset(group_color, 0, sizeof(pdf14_group_color_t));
1339
1340
1.13M
    group_color->num_std_colorants = pdev->num_std_colorants;
1341
1.13M
    group_color->blend_procs = pdev->blend_procs;
1342
1.13M
    group_color->polarity = pdev->color_info.polarity;
1343
1.13M
    group_color->num_components = pdev->color_info.num_components - has_tags;
1344
1.13M
    group_color->isadditive = pdev->ctx->additive;
1345
1.13M
    group_color->unpack_procs = pdev->pdf14_procs;
1346
1.13M
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
1347
1.13M
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
1348
1.13M
    group_color->depth = pdev->color_info.depth;
1349
1.13M
    group_color->decode = dev_proc(pdev, decode_color);
1350
1.13M
    group_color->encode = dev_proc(pdev, encode_color);
1351
1.13M
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
1352
1.13M
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
1353
1.13M
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
1354
1.13M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1355
1.13M
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
1356
1.13M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1357
1.13M
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
1358
1.13M
    group_color->icc_profile =
1359
1.13M
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1360
1.13M
    gsicc_adjust_profile_rc(group_color->icc_profile, 1, "pdf14_make_base_group_color");
1361
1362
1.13M
    return group_color;
1363
1.13M
}
1364
1365
/* This wil create the first buffer when we have
1366
   either the first drawing operation or transparency
1367
   group push.  At that time, the color space in which
1368
   we are going to be doing the alpha blend will be known. */
1369
static int
1370
pdf14_initialize_ctx(gx_device* dev, const gs_gstate* pgs)
1371
1.03G
{
1372
1.03G
    pdf14_device *pdev = (pdf14_device *)dev;
1373
1.03G
    bool has_tags = device_encodes_tags(dev);
1374
1.03G
    int n_chan = pdev->color_info.num_components - has_tags;
1375
1.03G
    bool additive = pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE;
1376
1.03G
    int num_spots = pdev->ctx->num_spots;
1377
1.03G
    pdf14_buf* buf;
1378
1.03G
    gs_memory_t* memory = dev->memory->stable_memory;
1379
1380
    /* Check for a blank idle group as a base group */
1381
1.03G
    if (pdev->ctx->stack != NULL && pdev->ctx->stack->group_popped &&
1382
1.71k
        pdev->ctx->stack->idle) {
1383
0
        pdf14_buf_free(pdev->ctx->stack);
1384
0
        pdev->ctx->stack = NULL;
1385
0
    }
1386
1387
1.03G
    if (pdev->ctx->stack != NULL)
1388
1.02G
        return 0;
1389
1390
1.03G
    if_debug2m('v', dev->memory, "[v]pdf14_initialize_ctx: width = %d, height = %d\n",
1391
857k
        dev->width, dev->height);
1392
1393
857k
    buf = pdf14_buf_new(&(pdev->ctx->rect), has_tags, false, false, false, n_chan + 1,
1394
857k
        num_spots, memory, pdev->ctx->deep);
1395
857k
    if (buf == NULL) {
1396
0
        return gs_error_VMerror;
1397
0
    }
1398
857k
    if_debug5m('v', memory,
1399
857k
        "[v]base buf: %d x %d, %d color channels, %d planes, deep=%d\n",
1400
857k
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes, pdev->ctx->deep);
1401
1402
857k
    memset(buf->data, 0, buf->planestride * (buf->n_planes - !!has_tags));
1403
857k
    buf->saved = NULL;
1404
857k
    pdev->ctx->stack = buf;
1405
857k
    pdev->ctx->additive = additive;
1406
1407
    /* Every buffer needs group color information including the base
1408
       one that is created for when we have no group */
1409
857k
    buf->group_color_info = gs_alloc_struct(pdev->memory->stable_memory,
1410
857k
            pdf14_group_color_t, &st_pdf14_clr, "pdf14_initialize_ctx");
1411
857k
    if (buf->group_color_info == NULL)
1412
0
        return gs_error_VMerror;
1413
1414
857k
    if (pgs != NULL)
1415
452k
        buf->group_color_info->get_cmap_procs = pgs->get_cmap_procs;
1416
405k
    else
1417
405k
        buf->group_color_info->get_cmap_procs = pdf14_get_cmap_procs;
1418
1419
857k
    buf->group_color_info->group_color_mapping_procs =
1420
857k
        dev_proc(pdev, get_color_mapping_procs);
1421
857k
    buf->group_color_info->group_color_comp_index =
1422
857k
        dev_proc(pdev, get_color_comp_index);
1423
857k
    buf->group_color_info->blend_procs = pdev->blend_procs;
1424
857k
    buf->group_color_info->polarity = pdev->color_info.polarity;
1425
857k
    buf->group_color_info->num_components = pdev->color_info.num_components - has_tags;
1426
857k
    buf->group_color_info->isadditive = pdev->ctx->additive;
1427
857k
    buf->group_color_info->unpack_procs = pdev->pdf14_procs;
1428
857k
    buf->group_color_info->depth = pdev->color_info.depth;
1429
857k
    buf->group_color_info->max_color = pdev->color_info.max_color;
1430
857k
    buf->group_color_info->max_gray = pdev->color_info.max_gray;
1431
857k
    buf->group_color_info->encode = dev_proc(pdev, encode_color);
1432
857k
    buf->group_color_info->decode = dev_proc(pdev, decode_color);
1433
857k
    memcpy(&(buf->group_color_info->comp_bits), &(pdev->color_info.comp_bits),
1434
857k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1435
857k
    memcpy(&(buf->group_color_info->comp_shift), &(pdev->color_info.comp_shift),
1436
857k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1437
857k
    buf->group_color_info->previous = NULL;  /* used during clist writing */
1438
857k
    buf->group_color_info->icc_profile =
1439
857k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1440
857k
    if (buf->group_color_info->icc_profile != NULL)
1441
857k
        gsicc_adjust_profile_rc(buf->group_color_info->icc_profile, 1, "pdf14_initialize_ctx");
1442
1443
857k
    return 0;
1444
857k
}
1445
1446
static pdf14_group_color_t*
1447
pdf14_clone_group_color_info(gx_device* pdev, pdf14_group_color_t* src)
1448
49.5k
{
1449
49.5k
    pdf14_group_color_t* des = gs_alloc_struct(pdev->memory->stable_memory,
1450
49.5k
        pdf14_group_color_t, &st_pdf14_clr, "pdf14_clone_group_color_info");
1451
49.5k
    if (des == NULL)
1452
0
        return NULL;
1453
1454
49.5k
    memcpy(des, src, sizeof(pdf14_group_color_t));
1455
49.5k
    if (des->icc_profile != NULL)
1456
49.5k
        gsicc_adjust_profile_rc(des->icc_profile, 1, "pdf14_clone_group_color_info");
1457
49.5k
    des->previous = NULL;  /* used during clist writing for state stack */
1458
1459
49.5k
    return des;
1460
49.5k
}
1461
1462
static  int
1463
pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect, bool isolated,
1464
                              bool knockout, uint16_t alpha, uint16_t shape, uint16_t opacity,
1465
                              gs_blend_mode_t blend_mode, bool idle, uint mask_id,
1466
                              int numcomps, bool cm_back_drop, bool shade_group,
1467
                              cmm_profile_t *group_profile, cmm_profile_t *tos_profile,
1468
                              pdf14_group_color_t* group_color, gs_gstate *pgs,
1469
                              gx_device *dev)
1470
4.99M
{
1471
4.99M
    pdf14_buf *tos = ctx->stack;
1472
4.99M
    pdf14_buf *buf, * pdf14_backdrop;
1473
4.99M
    bool has_shape = false;
1474
4.99M
    bool is_backdrop;
1475
4.99M
    int num_spots;
1476
1477
4.99M
    if_debug1m('v', ctx->memory,
1478
4.99M
               "[v]pdf14_push_transparency_group, idle = %d\n", idle);
1479
1480
4.99M
    if (tos != NULL)
1481
4.10M
        has_shape = tos->has_shape || tos->knockout;
1482
1483
4.99M
    if (ctx->smask_depth > 0)
1484
5.85k
        num_spots = 0;
1485
4.98M
    else
1486
4.98M
        num_spots = ctx->num_spots;
1487
1488
1489
4.99M
    buf = pdf14_buf_new(rect, ctx->has_tags, !isolated, has_shape, idle, numcomps + 1,
1490
4.99M
                        num_spots, ctx->memory, ctx->deep);
1491
4.99M
    if (buf == NULL)
1492
0
        return_error(gs_error_VMerror);
1493
1494
4.99M
    if_debug4m('v', ctx->memory,
1495
4.99M
        "[v]base buf: %d x %d, %d color channels, %d planes\n",
1496
4.99M
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes);
1497
4.99M
    buf->isolated = isolated;
1498
4.99M
    buf->knockout = knockout;
1499
4.99M
    buf->alpha = alpha;
1500
4.99M
    buf->shape = shape;
1501
4.99M
    buf->opacity = opacity;
1502
4.99M
    buf->blend_mode = blend_mode;
1503
4.99M
    buf->mask_id = mask_id;
1504
4.99M
    buf->mask_stack = ctx->mask_stack; /* Save because the group rendering may
1505
                                          set up another (nested) mask. */
1506
4.99M
    ctx->mask_stack = NULL; /* Clean the mask field for rendering this group.
1507
                            See pdf14_pop_transparency_group how to handle it. */
1508
4.99M
    buf->saved = tos;
1509
4.99M
    buf->group_color_info = group_color;
1510
1511
4.99M
    if (tos == NULL)
1512
886k
        buf->page_group = true;
1513
1514
4.99M
    ctx->stack = buf;
1515
4.99M
    if (buf->data == NULL)
1516
3.13M
        return 0;
1517
1.85M
    if (idle)
1518
0
        return 0;
1519
1.85M
    pdf14_backdrop = pdf14_find_backdrop_buf(ctx, &is_backdrop);
1520
1521
    /* Initializes buf->data with the backdrop or as opaque */
1522
1.85M
    if (pdf14_backdrop == NULL || (is_backdrop && pdf14_backdrop->backdrop == NULL)) {
1523
        /* Note, don't clear out tags set by pdf14_buf_new == GS_UNKNOWN_TAG */
1524
        /* Memsetting by 0, so this copes with the deep case too */
1525
1.32M
        memset(buf->data, 0, buf->planestride *
1526
1.32M
                                          (buf->n_chan +
1527
1.32M
                                           (buf->has_shape ? 1 : 0) +
1528
1.32M
                                           (buf->has_alpha_g ? 1 : 0)));
1529
1.32M
    } else {
1530
531k
        if (!cm_back_drop) {
1531
531k
            pdf14_preserve_backdrop(buf, pdf14_backdrop, is_backdrop
1532
#if RAW_DUMP
1533
                                    , ctx->memory
1534
#endif
1535
531k
                                    );
1536
531k
        } else {
1537
            /* We must have an non-isolated group with a mismatch in color spaces.
1538
                In this case, we can't just copy the buffer but must CM it */
1539
0
            pdf14_preserve_backdrop_cm(buf, group_profile, pdf14_backdrop, tos_profile,
1540
0
                                        ctx->memory, pgs, dev, is_backdrop);
1541
0
        }
1542
531k
    }
1543
1544
    /* If our new group is a non-isolated knockout group, we have to maintain
1545
       a copy of the backdrop in case we are drawing nonisolated groups on top of the
1546
       knockout group. They have to always blend with the groups backdrop
1547
       not what is currently drawn in the group. Selection of the backdrop
1548
       depends upon the properties of the parent group. For example, if
1549
       the parent itself is a knockout group we actually
1550
       need to blend with its backdrop. This could be NULL if the parent was
1551
       an isolated knockout group. */
1552
1.85M
    if (buf->knockout && pdf14_backdrop != NULL) {
1553
62.7k
        buf->backdrop = gs_alloc_bytes(ctx->memory,
1554
62.7k
                                       buf->planestride * buf->n_planes + CAL_SLOP,
1555
62.7k
                                       "pdf14_push_transparency_group");
1556
62.7k
        if (buf->backdrop == NULL) {
1557
0
            return gs_throw(gs_error_VMerror, "Knockout backdrop allocation failed");
1558
0
        }
1559
1560
62.7k
        memcpy(buf->backdrop, buf->data,
1561
62.7k
               buf->planestride * buf->n_planes);
1562
1563
#if RAW_DUMP
1564
        /* Dump the current buffer to see what we have. */
1565
        dump_raw_buffer(ctx->memory,
1566
            ctx->stack->rect.q.y - ctx->stack->rect.p.y,
1567
            ctx->stack->rowstride >> buf->deep, buf->n_planes,
1568
            ctx->stack->planestride, ctx->stack->rowstride,
1569
            "KnockoutBackDrop", buf->backdrop, buf->deep);
1570
        global_index++;
1571
#endif
1572
62.7k
    }
1573
#if RAW_DUMP
1574
    /* Dump the current buffer to see what we have. */
1575
    dump_raw_buffer(ctx->memory,
1576
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1577
                    ctx->stack->rowstride>>buf->deep, ctx->stack->n_planes,
1578
                    ctx->stack->planestride, ctx->stack->rowstride,
1579
                    "TransGroupPush", ctx->stack->data, buf->deep);
1580
    global_index++;
1581
#endif
1582
1.85M
    return 0;
1583
1.85M
}
1584
1585
static  int
1586
pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx,
1587
    const pdf14_nonseparable_blending_procs_t * pblend_procs,
1588
    int tos_num_color_comp, cmm_profile_t *curr_icc_profile, gx_device *dev)
1589
4.99M
{
1590
4.99M
    pdf14_buf *tos = ctx->stack;
1591
4.99M
    pdf14_buf *nos = tos->saved;
1592
4.99M
    pdf14_mask_t *mask_stack = tos->mask_stack;
1593
4.99M
    pdf14_buf *maskbuf;
1594
4.99M
    int x0, x1, y0, y1;
1595
4.99M
    int nos_num_color_comp;
1596
4.99M
    bool no_icc_match;
1597
4.99M
    pdf14_device *pdev = (pdf14_device *)dev;
1598
4.99M
    bool overprint = pdev->overprint;
1599
4.99M
    gx_color_index drawn_comps = pdev->drawn_comps_stroke | pdev->drawn_comps_fill;
1600
4.99M
    bool has_matte = false;
1601
4.99M
    int code = 0;
1602
1603
#ifdef DEBUG
1604
    pdf14_debug_mask_stack_state(ctx);
1605
#endif
1606
4.99M
    if (mask_stack == NULL) {
1607
2.78M
        maskbuf = NULL;
1608
2.78M
    }
1609
2.20M
    else {
1610
2.20M
        maskbuf = mask_stack->rc_mask->mask_buf;
1611
2.20M
    }
1612
1613
4.99M
    if (maskbuf != NULL && maskbuf->matte != NULL)
1614
8.16k
        has_matte = true;
1615
1616
    /* Check if this is our last buffer, if yes, there is nothing to
1617
       compose to.  Keep this buffer until we have the put image.
1618
       If we have another group push, this group must be destroyed.
1619
       This only occurs sometimes when at clist creation time
1620
       push_shfill_group occured and nothing was drawn in this group.
1621
       There is also the complication if we have a softmask.  There
1622
       are two approaches to this problem.  Apply the softmask during
1623
       the put image or handle it now.  I choose the later as the
1624
       put_image code is already way to complicated. */
1625
4.99M
    if (nos == NULL && maskbuf == NULL) {
1626
885k
        tos->group_popped = true;
1627
885k
        return 0;
1628
885k
    }
1629
1630
    /* Here is the case with the soft mask.  Go ahead and create a new
1631
       target buffer (nos) with the same color information etc, but blank
1632
       and go ahead and do the blend with the softmask so that it gets applied. */
1633
4.10M
    if (nos == NULL && maskbuf != NULL) {
1634
0
        nos = pdf14_buf_new(&(tos->rect), ctx->has_tags, !tos->isolated, tos->has_shape,
1635
0
            tos->idle, tos->n_chan, tos->num_spots, ctx->memory, ctx->deep);
1636
0
        if (nos == NULL) {
1637
0
            code = gs_error_VMerror;
1638
0
            goto exit;
1639
0
        }
1640
1641
0
        if_debug4m('v', ctx->memory,
1642
0
            "[v] special buffer for softmask application: %d x %d, %d color channels, %d planes\n",
1643
0
            nos->rect.q.x, nos->rect.q.y, nos->n_chan, nos->n_planes);
1644
1645
0
        nos->dirty = tos->dirty;
1646
0
        nos->isolated = tos->isolated;
1647
0
        nos->knockout = tos->knockout;
1648
0
        nos->alpha = 65535;
1649
0
        nos->shape = 65535;
1650
0
        nos->opacity = 65535;
1651
0
        nos->blend_mode = tos->blend_mode;
1652
0
        nos->mask_id = tos->mask_id;
1653
0
        nos->group_color_info = pdf14_clone_group_color_info(dev, tos->group_color_info);
1654
1655
0
        if (nos->data != NULL)
1656
0
            memset(nos->data, 0,
1657
0
                   nos->planestride * (nos->n_chan +
1658
0
                                       (nos->has_shape ? 1 : 0) +
1659
0
                                       (nos->has_alpha_g ? 1 : 0)));
1660
0
    }
1661
1662
    /* Before we get started, lets see if we have somehow gotten into
1663
       what should be an impossible situation where the group color
1664
       information does not match the buffer color information. This
1665
       can occur is there were memory issues that have perhaps blown
1666
       away information, or in the example of Bug 705197 the PDF interpreter
1667
       reuses a pattern during a circular reference causing an aliasing
1668
       of two nested patterns, one of which has a softmask. The change in
1669
       the buffer size of the inner one blows away the buffer of the
1670
       outer one leading to a mismatch of color spaces. Here
1671
       we can at least catch the case when the color space sizes have
1672
       changed and avoid buffer over-runs that would occur when we try
1673
       to do the group composition */
1674
4.10M
    if (nos->n_chan - 1 != nos->group_color_info->num_components ||
1675
4.10M
        tos->n_chan - 1 != tos_num_color_comp)
1676
0
        return_error(gs_error_Fatal);
1677
1678
4.10M
    nos_num_color_comp = nos->group_color_info->num_components - tos->num_spots;
1679
4.10M
    tos_num_color_comp = tos_num_color_comp - tos->num_spots;
1680
1681
    /* Sanitise the dirty rectangles, in case some of the drawing routines
1682
     * have made them overly large. */
1683
4.10M
    rect_intersect(tos->dirty, tos->rect);
1684
4.10M
    rect_intersect(nos->dirty, nos->rect);
1685
    /* dirty = the marked bbox. rect = the entire bounds of the buffer. */
1686
    /* Everything marked on tos that fits onto nos needs to be merged down. */
1687
4.10M
    y0 = max(tos->dirty.p.y, nos->rect.p.y);
1688
4.10M
    y1 = min(tos->dirty.q.y, nos->rect.q.y);
1689
4.10M
    x0 = max(tos->dirty.p.x, nos->rect.p.x);
1690
4.10M
    x1 = min(tos->dirty.q.x, nos->rect.q.x);
1691
4.10M
    if (ctx->mask_stack) {
1692
        /* This can occur when we have a situation where we are ending out of
1693
           a group that has internal to it a soft mask and another group.
1694
           The soft mask left over from the previous trans group pop is put
1695
           into ctx->masbuf, since it is still active if another trans group
1696
           push occurs to use it.  If one does not occur, but instead we find
1697
           ourselves popping from a parent group, then this softmask is no
1698
           longer needed.  We will rc_decrement and set it to NULL. */
1699
66
        rc_decrement(ctx->mask_stack->rc_mask, "pdf14_pop_transparency_group");
1700
66
        if (ctx->mask_stack->rc_mask == NULL ){
1701
66
            gs_free_object(ctx->memory, ctx->mask_stack, "pdf14_pop_transparency_group");
1702
66
        }
1703
66
        ctx->mask_stack = NULL;
1704
66
    }
1705
4.10M
    ctx->mask_stack = mask_stack;  /* Restore the mask saved by pdf14_push_transparency_group. */
1706
4.10M
    tos->mask_stack = NULL;        /* Clean the pointer sinse the mask ownership is now passed to ctx. */
1707
4.10M
    if (tos->idle)
1708
3.08M
        goto exit;
1709
1.01M
    if (maskbuf != NULL && maskbuf->data == NULL && maskbuf->alpha == 255)
1710
0
        goto exit;
1711
1712
#if RAW_DUMP
1713
    /* Dump the current buffer to see what we have. */
1714
    dump_raw_buffer(ctx->memory,
1715
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1716
                    ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1717
                    ctx->stack->planestride, ctx->stack->rowstride,
1718
                    "aaTrans_Group_Pop", ctx->stack->data, ctx->stack->deep);
1719
    global_index++;
1720
#endif
1721
/* Note currently if a pattern space has transparency, the ICC profile is not used
1722
   for blending purposes.  Instead we rely upon the gray, rgb, or cmyk parent space.
1723
   This is partially due to the fact that pdf14_pop_transparency_group and
1724
   pdf14_push_transparnecy_group have no real ICC interaction and those are the
1725
   operations called in the tile transparency code.  Instead we may want to
1726
   look at pdf14_begin_transparency_group and pdf14_end_transparency group which
1727
   is where all the ICC information is handled.  We will return to look at that later */
1728
1.01M
    if (nos->group_color_info->icc_profile != NULL) {
1729
1.01M
        no_icc_match = !gsicc_profiles_equal(nos->group_color_info->icc_profile, curr_icc_profile);
1730
1.01M
    } else {
1731
        /* Let the other tests make the decision if we need to transform */
1732
0
        no_icc_match = false;
1733
0
    }
1734
    /* If the color spaces are different and we actually did do a swap of
1735
       the procs for color */
1736
1.01M
    if ((nos->group_color_info->group_color_mapping_procs != NULL &&
1737
1.01M
        nos_num_color_comp != tos_num_color_comp) || no_icc_match) {
1738
11.7k
        if (x0 < x1 && y0 < y1) {
1739
9.89k
            pdf14_buf *result;
1740
9.89k
            bool did_alloc; /* We don't care here */
1741
1742
9.89k
            if (has_matte) {
1743
2.41k
                result = pdf14_transform_color_buffer_with_matte(pgs, ctx, dev,
1744
2.41k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1745
2.41k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1746
2.41k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false);
1747
2.41k
                has_matte = false;
1748
7.48k
            } else {
1749
7.48k
                result = pdf14_transform_color_buffer_no_matte(pgs, ctx, dev,
1750
7.48k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1751
7.48k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1752
7.48k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false, false);
1753
7.48k
            }
1754
9.89k
            if (result == NULL) {
1755
                /* Clean up and return error code */
1756
0
                code = gs_error_unknownerror;
1757
0
                goto exit;
1758
0
            }
1759
1760
#if RAW_DUMP
1761
            /* Dump the current buffer to see what we have. */
1762
            dump_raw_buffer(ctx->memory,
1763
                            ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1764
                            ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_chan,
1765
                            ctx->stack->planestride, ctx->stack->rowstride,
1766
                            "aCMTrans_Group_ColorConv", ctx->stack->data,
1767
                            ctx->stack->deep);
1768
#endif
1769
             /* compose. never do overprint in this case */
1770
9.89k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1771
9.89k
                 nos->group_color_info->isadditive,
1772
9.89k
                 nos->group_color_info->blend_procs,
1773
9.89k
                 has_matte, false, drawn_comps, ctx->memory, dev);
1774
9.89k
        }
1775
1.00M
    } else {
1776
        /* Group color spaces are the same.  No color conversions needed */
1777
1.00M
        if (x0 < x1 && y0 < y1)
1778
646k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1779
646k
                                ctx->additive, pblend_procs, has_matte, overprint,
1780
646k
                                drawn_comps, ctx->memory, dev);
1781
1.00M
    }
1782
4.10M
exit:
1783
4.10M
    ctx->stack = nos;
1784
    /* We want to detect the cases where we have luminosity soft masks embedded
1785
       within one another.  The "alpha" channel really needs to be merged into
1786
       the luminosity channel in this case.  This will occur during the mask pop */
1787
4.10M
    if (ctx->smask_depth > 0 && maskbuf != NULL) {
1788
        /* Set the trigger so that we will blend if not alpha. Since
1789
           we have softmasks embedded in softmasks */
1790
1.38k
        ctx->smask_blend = true;
1791
1.38k
    }
1792
4.10M
    if_debug1m('v', ctx->memory, "[v]pop buf, idle=%d\n", tos->idle);
1793
4.10M
    pdf14_buf_free(tos);
1794
4.10M
    if (code < 0)
1795
0
        return_error(code);
1796
4.10M
    return 0;
1797
4.10M
}
1798
1799
/*
1800
 * Create a transparency mask that will be used as the mask for
1801
 * the next transparency group that is created afterwards.
1802
 * The sequence of calls is:
1803
 * push_mask, draw the mask, pop_mask, push_group, draw the group, pop_group
1804
 */
1805
static  int
1806
pdf14_push_transparency_mask(pdf14_ctx *ctx, gs_int_rect *rect, uint16_t bg_alpha,
1807
                             byte *transfer_fn, bool is_ident, bool idle,
1808
                             bool replacing, uint mask_id,
1809
                             gs_transparency_mask_subtype_t subtype,
1810
                             int numcomps, int Background_components,
1811
                             const float Background[], int Matte_components,
1812
                             const float Matte[], const float GrayBackground,
1813
                             pdf14_group_color_t* group_color)
1814
1.01M
{
1815
1.01M
    pdf14_buf *buf;
1816
1.01M
    int i;
1817
1818
1.01M
    if_debug2m('v', ctx->memory,
1819
1.01M
               "[v]pdf14_push_transparency_mask, idle=%d, replacing=%d\n",
1820
1.01M
               idle, replacing);
1821
1.01M
    ctx->smask_depth += 1;
1822
1823
1.01M
    if (ctx->stack == NULL) {
1824
0
        return_error(gs_error_VMerror);
1825
0
    }
1826
1827
    /* An optimization to consider is that if the SubType is Alpha
1828
       then we really should only be allocating the alpha band and
1829
       only draw with that channel.  Current architecture makes that
1830
       a bit tricky.  We need to create this based upon the size of
1831
       the color space + an alpha channel. NOT the device size
1832
       or the previous ctx size */
1833
    /* A mask doesn't worry about tags */
1834
1.01M
    buf = pdf14_buf_new(rect, false, false, false, idle, numcomps + 1, 0,
1835
1.01M
                        ctx->memory, ctx->deep);
1836
1.01M
    if (buf == NULL)
1837
0
        return_error(gs_error_VMerror);
1838
1.01M
    buf->alpha = bg_alpha;
1839
1.01M
    buf->is_ident = is_ident;
1840
    /* fill in, but these values aren't really used */
1841
1.01M
    buf->isolated = true;
1842
1.01M
    buf->knockout = false;
1843
1.01M
    buf->shape = 0xffff;
1844
1.01M
    buf->blend_mode = BLEND_MODE_Normal;
1845
1.01M
    buf->transfer_fn = transfer_fn;
1846
1.01M
    buf->matte_num_comps = Matte_components;
1847
1.01M
    buf->group_color_info = group_color;
1848
1849
1.01M
    if (Matte_components) {
1850
8.16k
        buf->matte = (uint16_t *)gs_alloc_bytes(ctx->memory, Matte_components * sizeof(uint16_t) + CAL_SLOP,
1851
8.16k
                                                "pdf14_push_transparency_mask");
1852
8.16k
        if (buf->matte == NULL)
1853
0
            return_error(gs_error_VMerror);
1854
32.6k
        for (i = 0; i < Matte_components; i++) {
1855
24.4k
            buf->matte[i] = (uint16_t) floor(Matte[i] * 65535.0 + 0.5);
1856
24.4k
        }
1857
8.16k
    }
1858
1.01M
    buf->mask_id = mask_id;
1859
    /* If replacing=false, we start the mask for an image with SMask.
1860
       In this case the image's SMask temporary replaces the
1861
       mask of the containing group. Save the containing droup's mask
1862
       in buf->mask_stack */
1863
1.01M
    buf->mask_stack = ctx->mask_stack;
1864
1.01M
    if (buf->mask_stack){
1865
254k
        rc_increment(buf->mask_stack->rc_mask);
1866
254k
    }
1867
#if RAW_DUMP
1868
    /* Dump the current buffer to see what we have. */
1869
    if (ctx->stack->planestride > 0 ){
1870
        dump_raw_buffer(ctx->memory,
1871
                        ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1872
                        ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1873
                        ctx->stack->planestride, ctx->stack->rowstride,
1874
                        "Raw_Buf_PreSmask", ctx->stack->data, ctx->stack->deep);
1875
        global_index++;
1876
    }
1877
#endif
1878
1.01M
    buf->saved = ctx->stack;
1879
1.01M
    ctx->stack = buf;
1880
    /* Soft Mask related information so we know how to
1881
       compute luminosity when we pop the soft mask */
1882
1.01M
    buf->SMask_SubType = subtype;
1883
1.01M
    if (buf->data != NULL) {
1884
        /* We need to initialize it to the BC if it existed */
1885
        /* According to the spec, the CS has to be the same */
1886
        /* If the back ground component is black, then don't bother
1887
           with this.  Since we are forcing the rendering to gray
1888
           earlier now, go ahead and just use the GrayBackGround color
1889
           directly. */
1890
556k
        if ( Background_components && GrayBackground != 0.0 ) {
1891
214
            if (buf->deep) {
1892
0
                uint16_t gray = (uint16_t) (65535.0 * GrayBackground);
1893
0
                gs_memset16(buf->data, gray, buf->planestride);
1894
                /* If we have a background component that was not black, then we
1895
                   need to set the alpha for this mask as if we had drawn in the
1896
                   entire soft mask buffer */
1897
0
                gs_memset16(buf->data + buf->planestride, 65535,
1898
0
                            buf->planestride *(buf->n_chan - 1));
1899
214
            } else {
1900
214
                unsigned char gray = (unsigned char) (255.0 * GrayBackground);
1901
214
                memset(buf->data, gray, buf->planestride);
1902
                /* If we have a background component that was not black, then we
1903
                   need to set the alpha for this mask as if we had drawn in the
1904
                   entire soft mask buffer */
1905
214
                memset(buf->data + buf->planestride, 255,
1906
214
                       buf->planestride * (buf->n_chan - 1));
1907
214
            }
1908
556k
        } else {
1909
            /* Compose mask with opaque background */
1910
556k
            memset(buf->data, 0, buf->planestride * buf->n_chan);
1911
556k
        }
1912
556k
    }
1913
1.01M
    return 0;
1914
1.01M
}
1915
1916
static void pdf14_free_mask_stack(pdf14_ctx *ctx, gs_memory_t *memory)
1917
253k
{
1918
253k
    pdf14_mask_t *mask_stack = ctx->mask_stack;
1919
1920
253k
    if (mask_stack->rc_mask != NULL) {
1921
1.30k
        pdf14_mask_t *curr_mask = mask_stack;
1922
1.30k
        pdf14_mask_t *old_mask;
1923
2.61k
        while (curr_mask != NULL) {
1924
            /* Force to decrement until free */
1925
2.95k
            while (curr_mask->rc_mask != NULL)
1926
1.64k
                rc_decrement(curr_mask->rc_mask, "pdf14_free_mask_stack");
1927
1.30k
            old_mask = curr_mask;
1928
1.30k
            curr_mask = curr_mask->previous;
1929
1.30k
            gs_free_object(old_mask->memory, old_mask, "pdf14_free_mask_stack");
1930
1.30k
        }
1931
252k
    } else {
1932
252k
        gs_free_object(memory, mask_stack, "pdf14_free_mask_stack");
1933
252k
    }
1934
253k
    ctx->mask_stack = NULL;
1935
253k
}
1936
1937
static  int
1938
pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev)
1939
1.01M
{
1940
1.01M
    pdf14_buf* tos = ctx->stack;
1941
1.01M
    pdf14_buf* nos = tos->saved;
1942
1.01M
    byte *new_data_buf;
1943
1.01M
    int icc_match;
1944
1.01M
    cmm_profile_t *des_profile = nos->group_color_info->icc_profile; /* If set, this should be a gray profile */
1945
1.01M
    cmm_profile_t *src_profile;
1946
1.01M
    gsicc_rendering_param_t rendering_params;
1947
1.01M
    gsicc_link_t *icc_link;
1948
1.01M
    gsicc_rendering_param_t render_cond;
1949
1.01M
    cmm_dev_profile_t *dev_profile;
1950
1.01M
    int code = 0;
1951
1952
1.01M
    dev_proc(dev, get_profile)(dev,  &dev_profile);
1953
1.01M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &src_profile,
1954
1.01M
                          &render_cond);
1955
1.01M
    ctx->smask_depth -= 1;
1956
    /* icc_match == -1 means old non-icc code.
1957
       icc_match == 0 means use icc code
1958
       icc_match == 1 mean no conversion needed */
1959
1.01M
    if (des_profile != NULL && src_profile != NULL ) {
1960
1.01M
        icc_match = gsicc_profiles_equal(des_profile, src_profile);
1961
1.01M
    } else {
1962
0
        icc_match = -1;
1963
0
    }
1964
1.01M
    if_debug1m('v', ctx->memory, "[v]pdf14_pop_transparency_mask, idle=%d\n",
1965
1.01M
               tos->idle);
1966
1.01M
    ctx->stack = tos->saved;
1967
1.01M
    tos->saved = NULL;  /* To avoid issues with GC */
1968
1.01M
    if (tos->mask_stack) {
1969
        /* During the soft mask push, the mask_stack was copied (not moved) from
1970
           the ctx to the tos mask_stack. We are done with this now so it is safe to
1971
           just set to NULL.  However, before we do that we must perform
1972
           rc decrement to match the increment that occured was made.  Also,
1973
           if this is the last ref count of the rc_mask, we should free the
1974
           buffer now since no other groups need it. */
1975
252k
        rc_decrement(tos->mask_stack->rc_mask,
1976
252k
                     "pdf14_pop_transparency_mask(tos->mask_stack->rc_mask)");
1977
252k
        if (tos->mask_stack->rc_mask) {
1978
252k
            if (tos->mask_stack->rc_mask->rc.ref_count == 1){
1979
252k
                rc_decrement(tos->mask_stack->rc_mask,
1980
252k
                            "pdf14_pop_transparency_mask(tos->mask_stack->rc_mask)");
1981
252k
            }
1982
252k
        }
1983
252k
        tos->mask_stack = NULL;
1984
252k
    }
1985
1.01M
    if (tos->data == NULL ) {
1986
        /* This can occur in clist rendering if the soft mask does
1987
           not intersect the current band.  It would be nice to
1988
           catch this earlier and just avoid creating the structure
1989
           to begin with.  For now we need to delete the structure
1990
           that was created.  Only delete if the alpha value is 65535 */
1991
456k
        if ((tos->alpha == 65535 && tos->is_ident) ||
1992
456k
            (!tos->is_ident && (tos->transfer_fn[tos->alpha>>8] == 255))) {
1993
7.57k
            pdf14_buf_free(tos);
1994
7.57k
            if (ctx->mask_stack != NULL) {
1995
3.54k
                pdf14_free_mask_stack(ctx, ctx->memory);
1996
3.54k
            }
1997
449k
        } else {
1998
            /* Assign as mask buffer */
1999
449k
            if (ctx->mask_stack != NULL) {
2000
137k
                pdf14_free_mask_stack(ctx, ctx->memory);
2001
137k
            }
2002
449k
            ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2003
449k
            ctx->mask_stack->rc_mask = pdf14_rcmask_new(ctx->memory);
2004
449k
            ctx->mask_stack->rc_mask->mask_buf = tos;
2005
449k
        }
2006
456k
        ctx->smask_blend = false;  /* just in case */
2007
556k
    } else {
2008
        /* If we are already in the source space then there is no reason
2009
           to do the transformation */
2010
        /* Lets get this to a monochrome buffer and map it to a luminance only value */
2011
        /* This will reduce our memory.  We won't reuse the existing one, due */
2012
        /* Due to the fact that on certain systems we may have issues recovering */
2013
        /* the data after a resize */
2014
556k
        new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride + CAL_SLOP,
2015
556k
                                        "pdf14_pop_transparency_mask");
2016
556k
        if (new_data_buf == NULL)
2017
0
            return_error(gs_error_VMerror);
2018
        /* Initialize with 0.  Need to do this since in Smask_Luminosity_Mapping
2019
           we won't be filling everything during the remap if it had not been
2020
           written into by the PDF14 fill rect */
2021
556k
        memset(new_data_buf, 0, tos->planestride);
2022
        /* If the subtype was alpha, then just grab the alpha channel now
2023
           and we are all done */
2024
556k
        if (tos->SMask_SubType == TRANSPARENCY_MASK_Alpha) {
2025
41.5k
            ctx->smask_blend = false;  /* not used in this case */
2026
41.5k
            smask_copy(tos->rect.q.y - tos->rect.p.y,
2027
41.5k
                       (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2028
41.5k
                       tos->rowstride,
2029
41.5k
                       (tos->data)+tos->planestride, new_data_buf);
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, 1,
2035
                            tos->planestride, tos->rowstride,
2036
                            "SMask_Pop_Alpha(Mask_Plane1)",tos->data,
2037
                            tos->deep);
2038
            global_index++;
2039
#endif
2040
515k
        } else {
2041
515k
            if (icc_match == 1 || tos->n_chan == 2) {
2042
#if RAW_DUMP
2043
                /* Dump the current buffer to see what we have. */
2044
                dump_raw_buffer(ctx->memory,
2045
                                tos->rect.q.y-tos->rect.p.y,
2046
                                tos->rowstride>>tos->deep, tos->n_planes,
2047
                                tos->planestride, tos->rowstride,
2048
                                "SMask_Pop_Lum(Mask_Plane0)",tos->data,
2049
                                tos->deep);
2050
                global_index++;
2051
#endif
2052
                /* There is no need to color convert.  Data is already gray scale.
2053
                   We just need to copy the gray plane.  However it is
2054
                   possible that the soft mask could have a soft mask which
2055
                   would end us up with some alpha blending information
2056
                   (Bug691803). In fact, according to the spec, the alpha
2057
                   blending has to occur.  See FTS test fts_26_2601.pdf
2058
                   for an example of this.  Softmask buffer is intialized
2059
                   with BG values.  It would be nice to keep track if buffer
2060
                   ever has a alpha value not 1 so that we could detect and
2061
                   avoid this blend if not needed. */
2062
515k
                smask_blend(tos->data, tos->rect.q.x - tos->rect.p.x,
2063
515k
                            tos->rect.q.y - tos->rect.p.y, tos->rowstride,
2064
515k
                            tos->planestride, tos->deep);
2065
#if RAW_DUMP
2066
                /* Dump the current buffer to see what we have. */
2067
                dump_raw_buffer(ctx->memory,
2068
                                tos->rect.q.y-tos->rect.p.y,
2069
                                tos->rowstride>>tos->deep, 1,
2070
                                tos->planestride, tos->rowstride,
2071
                                "SMask_Pop_Lum_Post_Blend",tos->data,
2072
                                tos->deep);
2073
                global_index++;
2074
#endif
2075
515k
                smask_copy(tos->rect.q.y - tos->rect.p.y,
2076
515k
                           (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2077
515k
                           tos->rowstride, tos->data, new_data_buf);
2078
515k
            } else {
2079
0
                if ( icc_match == -1 ) {
2080
                    /* The slow old fashioned way */
2081
0
                    smask_luminosity_mapping(tos->rect.q.y - tos->rect.p.y ,
2082
0
                        tos->rect.q.x - tos->rect.p.x,tos->n_chan,
2083
0
                        tos->rowstride, tos->planestride,
2084
0
                        tos->data,  new_data_buf, ctx->additive, tos->SMask_SubType,
2085
0
                        tos->deep
2086
#if RAW_DUMP
2087
                        , ctx->memory
2088
#endif
2089
0
                        );
2090
0
                } else {
2091
                    /* ICC case where we use the CMM */
2092
                    /* Request the ICC link for the transform that we will need to use */
2093
0
                    rendering_params.black_point_comp = gsBLACKPTCOMP_OFF;
2094
0
                    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
2095
0
                    rendering_params.override_icc = false;
2096
0
                    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
2097
0
                    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;
2098
0
                    rendering_params.cmm = gsCMM_DEFAULT;
2099
0
                    icc_link = gsicc_get_link_profile(pgs, dev, des_profile,
2100
0
                        src_profile, &rendering_params, pgs->memory, false);
2101
0
                    code = smask_icc(dev, tos->rect.q.y - tos->rect.p.y,
2102
0
                              tos->rect.q.x - tos->rect.p.x, tos->n_chan,
2103
0
                              tos->rowstride, tos->planestride,
2104
0
                              tos->data, new_data_buf, icc_link, tos->deep);
2105
                    /* Release the link */
2106
0
                    gsicc_release_link(icc_link);
2107
0
                }
2108
0
            }
2109
515k
        }
2110
        /* Free the old object, NULL test was above */
2111
556k
        gs_free_object(ctx->memory, tos->data, "pdf14_pop_transparency_mask");
2112
556k
        tos->data = new_data_buf;
2113
        /* Data is single channel now */
2114
556k
        tos->n_chan = 1;
2115
556k
        tos->n_planes = 1;
2116
        /* Assign as reference counted mask buffer */
2117
556k
        if (ctx->mask_stack != NULL) {
2118
            /* In this case, the source file is wacky as it already had a
2119
               softmask and now is getting a replacement. We need to clean
2120
               up the softmask stack before doing this free and creating
2121
               a new stack. Bug 693312 */
2122
112k
            pdf14_free_mask_stack(ctx, ctx->memory);
2123
112k
        }
2124
556k
        ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2125
556k
        if (ctx->mask_stack == NULL)
2126
0
            return gs_note_error(gs_error_VMerror);
2127
556k
        ctx->mask_stack->rc_mask = pdf14_rcmask_new(ctx->memory);
2128
556k
        if (ctx->mask_stack->rc_mask == NULL)
2129
0
            return gs_note_error(gs_error_VMerror);
2130
556k
        ctx->mask_stack->rc_mask->mask_buf = tos;
2131
556k
    }
2132
1.01M
    return code;
2133
1.01M
}
2134
2135
static pdf14_mask_t *
2136
pdf14_mask_element_new(gs_memory_t *memory)
2137
2.96M
{
2138
2.96M
    pdf14_mask_t *result;
2139
2140
2.96M
    result = gs_alloc_struct(memory, pdf14_mask_t, &st_pdf14_mask,
2141
2.96M
                             "pdf14_mask_element_new");
2142
2.96M
    if (result == NULL)
2143
0
        return NULL;
2144
    /* Get the reference counted mask */
2145
2.96M
    result->rc_mask = NULL;
2146
2.96M
    result->previous = NULL;
2147
2.96M
    result->memory = memory;
2148
2.96M
    return result;
2149
2.96M
}
2150
2151
static int
2152
pdf14_push_transparency_state(gx_device *dev, gs_gstate *pgs)
2153
0
{
2154
    /* We need to push the current soft mask.  We need to
2155
       be able to recover it if we draw a new one and
2156
       then obtain a Q operation ( a pop ) */
2157
2158
0
    pdf14_device *pdev = (pdf14_device *)dev;
2159
0
    pdf14_ctx *ctx = pdev->ctx;
2160
0
    pdf14_mask_t *new_mask;
2161
2162
0
    if_debug0m('v', ctx->memory, "pdf14_push_transparency_state\n");
2163
    /* We need to push the current mask buffer   */
2164
    /* Allocate a new element for the stack.
2165
       Don't do anything if there is no mask present.*/
2166
0
    if (ctx->mask_stack != NULL) {
2167
0
        new_mask = pdf14_mask_element_new(ctx->memory);
2168
        /* Duplicate and make the link */
2169
0
        new_mask->rc_mask = ctx->mask_stack->rc_mask;
2170
0
        rc_increment(new_mask->rc_mask);
2171
0
        new_mask->previous = ctx->mask_stack;
2172
0
        ctx->mask_stack = new_mask;
2173
0
    }
2174
#ifdef DEBUG
2175
    pdf14_debug_mask_stack_state(pdev->ctx);
2176
#endif
2177
0
    return 0;
2178
0
}
2179
2180
static int
2181
pdf14_pop_transparency_state(gx_device *dev, gs_gstate *pgs)
2182
5.66M
{
2183
    /* Pop the soft mask.  It is no longer needed. Likely due to
2184
       a Q that has occurred. */
2185
5.66M
    pdf14_device *pdev = (pdf14_device *)dev;
2186
5.66M
    pdf14_ctx *ctx = pdev->ctx;
2187
5.66M
    pdf14_mask_t *old_mask;
2188
2189
5.66M
    if_debug0m('v', ctx->memory, "pdf14_pop_transparency_state\n");
2190
    /* rc decrement the current link after we break it from
2191
       the list, then free the stack element.  Don't do
2192
       anything if there is no mask present. */
2193
5.66M
    if (ctx->mask_stack != NULL) {
2194
1.02M
        old_mask = ctx->mask_stack;
2195
1.02M
        ctx->mask_stack = ctx->mask_stack->previous;
2196
1.02M
        if (old_mask->rc_mask) {
2197
1.02M
            rc_decrement(old_mask->rc_mask, "pdf14_pop_transparency_state");
2198
1.02M
        }
2199
1.02M
        gs_free_object(old_mask->memory, old_mask, "pdf14_pop_transparency_state");
2200
        /* We need to have some special handling here for when we have nested
2201
           soft masks.  There may be a copy in the stack that we may need to
2202
           adjust. */
2203
1.02M
        if (ctx->smask_depth > 0) {
2204
1.24k
            if (ctx->stack != NULL && ctx->stack->mask_stack != NULL) {
2205
1.07k
                ctx->stack->mask_stack = ctx->mask_stack;
2206
1.07k
            }
2207
1.24k
        }
2208
1.02M
    }
2209
#ifdef DEBUG
2210
    pdf14_debug_mask_stack_state(pdev->ctx);
2211
#endif
2212
5.66M
    return 0;
2213
5.66M
}
2214
2215
static  int
2216
pdf14_open(gx_device *dev)
2217
1.96M
{
2218
1.96M
    pdf14_device *pdev = (pdf14_device *)dev;
2219
2220
    /* If we are reenabling the device dont create a new ctx. Bug 697456 */
2221
1.96M
    if (pdev->ctx == NULL) {
2222
1.96M
        bool has_tags = device_encodes_tags(dev);
2223
1.96M
        int bits_per_comp = (dev->color_info.depth / dev->color_info.num_components);
2224
1.96M
        pdev->ctx = pdf14_ctx_new(dev, bits_per_comp > 8);
2225
1.96M
        if (pdev->ctx == NULL)
2226
0
            return_error(gs_error_VMerror);
2227
2228
1.96M
        pdev->ctx->rect.p.x = 0;
2229
1.96M
        pdev->ctx->rect.p.y = 0;
2230
1.96M
        pdev->ctx->rect.q.x = dev->width;
2231
1.96M
        pdev->ctx->rect.q.y = dev->height;
2232
1.96M
        pdev->ctx->has_tags = has_tags;
2233
1.96M
        pdev->ctx->num_spots = pdev->color_info.num_components - has_tags - pdev->num_std_colorants;
2234
        /* This can happen because pdev->num_std_colorants is not updated when pdev->color_info.num_components
2235
         * is. I am not sure how to fix that. */
2236
1.96M
        if (pdev->ctx->num_spots < 0)
2237
0
            pdev->ctx->num_spots = 0;
2238
1.96M
        pdev->ctx->additive = (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE);
2239
1.96M
    }
2240
1.96M
    pdev->free_devicen = true;
2241
1.96M
    pdev->text_group = PDF14_TEXTGROUP_NO_BT;
2242
1.96M
    return 0;
2243
1.96M
}
2244
2245
static const gx_cm_color_map_procs pdf14_DeviceCMYKspot_procs = {
2246
    pdf14_gray_cs_to_cmyk_cm, pdf14_rgb_cs_to_cmyk_cm, pdf14_cmyk_cs_to_cmyk_cm
2247
};
2248
2249
static const gx_cm_color_map_procs pdf14_DeviceRGBspot_procs = {
2250
    pdf14_gray_cs_to_rgbspot_cm, pdf14_rgb_cs_to_rgbspot_cm, pdf14_cmyk_cs_to_rgbspot_cm
2251
};
2252
2253
static const gx_cm_color_map_procs pdf14_DeviceGrayspot_procs = {
2254
    pdf14_gray_cs_to_grayspot_cm, pdf14_rgb_cs_to_grayspot_cm, pdf14_cmyk_cs_to_grayspot_cm
2255
};
2256
2257
static const gx_cm_color_map_procs *
2258
pdf14_cmykspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2259
9.49M
{
2260
9.49M
    *tdev = dev;
2261
9.49M
    return &pdf14_DeviceCMYKspot_procs;
2262
9.49M
}
2263
2264
static const gx_cm_color_map_procs *
2265
pdf14_rgbspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2266
17.8M
{
2267
17.8M
    *tdev = dev;
2268
17.8M
    return &pdf14_DeviceRGBspot_procs;
2269
17.8M
}
2270
2271
static const gx_cm_color_map_procs *
2272
pdf14_grayspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2273
87
{
2274
87
    *tdev = dev;
2275
87
    return &pdf14_DeviceGrayspot_procs;
2276
87
}
2277
2278
static void
2279
be_rev_cpy(uint16_t *dst,const uint16_t *src,int n)
2280
0
{
2281
0
    for (; n != 0; n--) {
2282
0
        uint16_t in = *src++;
2283
0
        ((byte *)dst)[0] = in>>8;
2284
0
        ((byte *)dst)[1] = in;
2285
0
        dst++;
2286
0
    }
2287
0
}
2288
2289
/* Used to pass along information about the buffer created by the
2290
   pdf14 device.  This is used by the pattern accumulator when the
2291
   pattern contains transparency.  Note that if free_device is true then
2292
   we need to go ahead and get the buffer data copied and free up the
2293
   device.  This only occurs at the end of a pattern accumulation operation */
2294
int
2295
pdf14_get_buffer_information(const gx_device * dev,
2296
                             gx_pattern_trans_t *transbuff, gs_memory_t *mem,
2297
                             bool free_device)
2298
68.5k
{
2299
68.5k
    const pdf14_device * pdev = (pdf14_device *)dev;
2300
68.5k
    pdf14_buf *buf;
2301
68.5k
    gs_int_rect rect;
2302
68.5k
    int x1,y1,width,height;
2303
2304
68.5k
    if ( pdev->ctx == NULL){
2305
0
        return 0;  /* this can occur if the pattern is a clist */
2306
0
    }
2307
#ifdef DEBUG
2308
    pdf14_debug_mask_stack_state(pdev->ctx);
2309
#endif
2310
68.5k
    buf = pdev->ctx->stack;
2311
68.5k
    rect = buf->rect;
2312
68.5k
    transbuff->buf = (free_device ? NULL : buf);
2313
68.5k
    x1 = min(pdev->width, rect.q.x);
2314
68.5k
    y1 = min(pdev->height, rect.q.y);
2315
68.5k
    width = x1 - rect.p.x;
2316
68.5k
    height = y1 - rect.p.y;
2317
2318
68.5k
    transbuff->n_chan    = buf->n_chan;
2319
68.5k
    transbuff->has_tags  = buf->has_tags;
2320
68.5k
    transbuff->has_shape = buf->has_shape;
2321
68.5k
    transbuff->width     = buf->rect.q.x - buf->rect.p.x;
2322
68.5k
    transbuff->height    = buf->rect.q.y - buf->rect.p.y;
2323
68.5k
    transbuff->deep      = buf->deep;
2324
2325
68.5k
    if (width <= 0 || height <= 0 || buf->data == NULL) {
2326
14.8k
        transbuff->planestride = 0;
2327
14.8k
        transbuff->rowstride = 0;
2328
14.8k
        return 0;
2329
14.8k
    }
2330
2331
53.7k
    if (free_device) {
2332
18.9k
        transbuff->pdev14 = NULL;
2333
18.9k
        transbuff->rect = rect;
2334
18.9k
        if ((width < transbuff->width) || (height < transbuff->height)) {
2335
            /* If the bbox is smaller than the whole buffer than go ahead and
2336
               create a new one to use.  This can occur if we drew in a smaller
2337
               area than was specified by the transparency group rect. */
2338
0
            intptr_t rowstride = ((width + 3) & -4)<<buf->deep;
2339
0
            intptr_t planestride = rowstride * height;
2340
0
            int k, j;
2341
0
            byte *buff_ptr_src, *buff_ptr_des;
2342
2343
0
            transbuff->planestride = planestride;
2344
0
            transbuff->rowstride = rowstride;
2345
0
            transbuff->transbytes =
2346
0
                         gs_alloc_bytes(mem,
2347
0
                                        planestride *
2348
0
                                                (buf->n_chan +
2349
0
                                                 buf->has_tags ? 1 : 0) + CAL_SLOP,
2350
0
                                        "pdf14_get_buffer_information");
2351
0
            if (transbuff->transbytes == NULL)
2352
0
                return gs_error_VMerror;
2353
2354
0
            transbuff->mem = mem;
2355
0
            if (transbuff->deep) {
2356
0
                for (j = 0; j < transbuff->n_chan; j++) {
2357
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2358
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2359
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2360
0
                    for (k = 0; k < height; k++) {
2361
0
                        be_rev_cpy((uint16_t *)buff_ptr_des, (const uint16_t *)buff_ptr_src, rowstride>>1);
2362
0
                        buff_ptr_des += rowstride;
2363
0
                        buff_ptr_src += buf->rowstride;
2364
0
                    }
2365
0
                }
2366
0
            } else {
2367
0
                for (j = 0; j < transbuff->n_chan; j++) {
2368
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2369
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2370
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2371
0
                    for (k = 0; k < height; k++) {
2372
0
                        memcpy(buff_ptr_des, buff_ptr_src, rowstride);
2373
0
                        buff_ptr_des += rowstride;
2374
0
                        buff_ptr_src += buf->rowstride;
2375
0
                    }
2376
0
                }
2377
0
            }
2378
2379
18.9k
        } else {
2380
            /* The entire buffer is used.  Go ahead and grab the pointer and
2381
               clear the pointer in the pdf14 device data buffer so it is not
2382
               freed when we close the device */
2383
18.9k
            transbuff->planestride = buf->planestride;
2384
18.9k
            transbuff->rowstride = buf->rowstride;
2385
18.9k
            transbuff->transbytes = buf->data;
2386
18.9k
            transbuff->mem = buf->memory;
2387
18.9k
            buf->data = NULL;  /* So that the buffer is not freed */
2388
18.9k
            if (transbuff->deep) {
2389
                /* We have the data in native endian. We need it in big endian. Do an in-place conversion. */
2390
                /* FIXME: This is a nop on big endian machines. Is the compiler smart enough to spot that? */
2391
0
                uint16_t *buff_ptr;
2392
0
                int j, k, z;
2393
0
                intptr_t rowstride = transbuff->rowstride>>1;
2394
0
                intptr_t planestride = transbuff->planestride;
2395
0
                for (j = 0; j < transbuff->n_chan; j++) {
2396
0
                    buff_ptr = (uint16_t *)(transbuff->transbytes + j * planestride);
2397
0
                    for (k = 0; k < height; k++) {
2398
0
                        for (z = 0; z < width; z++) {
2399
0
                            uint16_t in = buff_ptr[z];
2400
0
                            ((byte *)(&buff_ptr[z]))[0] = in>>8;
2401
0
                            ((byte *)(&buff_ptr[z]))[1] = in;
2402
0
                        }
2403
0
                        buff_ptr += rowstride;
2404
0
                    }
2405
0
                }
2406
0
            }
2407
18.9k
        }
2408
#if RAW_DUMP
2409
        /* Dump the buffer that should be going into the pattern */;
2410
        dump_raw_buffer_be(buf->memory,
2411
                           height, width, transbuff->n_chan,
2412
                           transbuff->planestride, transbuff->rowstride,
2413
                           "pdf14_pattern_buff", transbuff->transbytes,
2414
                           transbuff->deep);
2415
        global_index++;
2416
#endif
2417
        /* Go ahead and free up the pdf14 device */
2418
18.9k
        dev_proc(dev, close_device)((gx_device *)dev);
2419
34.7k
    } else {
2420
        /* Here we are coming from one of the fill image / pattern / mask
2421
           operations */
2422
34.7k
        transbuff->pdev14 = dev;
2423
34.7k
        transbuff->planestride = buf->planestride;
2424
34.7k
        transbuff->rowstride = buf->rowstride;
2425
34.7k
        transbuff->transbytes = buf->data;
2426
34.7k
        transbuff->mem = buf->memory;
2427
34.7k
        transbuff->rect = rect;
2428
#if RAW_DUMP
2429
    /* Dump the buffer that should be going into the pattern */;
2430
        dump_raw_buffer(buf->memory,
2431
                        height, width, buf->n_chan,
2432
                        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2433
                        "pdf14_pattern_buff",
2434
                        buf->data,
2435
                        transbuff->deep);
2436
        global_index++;
2437
#endif
2438
34.7k
    }
2439
53.7k
    return 0;
2440
53.7k
}
2441
2442
typedef void(*blend_image_row_proc_t) (const byte *gs_restrict buf_ptr,
2443
    intptr_t planestride, int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf);
2444
2445
2446
static int
2447
pdf14_put_image_color_convert(const pdf14_device* dev, gs_gstate* pgs, cmm_profile_t* src_profile,
2448
                        cmm_dev_profile_t* dev_target_profile, pdf14_buf** buf,
2449
                        byte** buf_ptr, bool was_blended, int x, int y, int width, int height, int num_channels_to_lose)
2450
25.4k
{
2451
25.4k
    pdf14_buf* cm_result = NULL;
2452
25.4k
    cmm_profile_t* des_profile;
2453
25.4k
    gsicc_rendering_param_t render_cond;
2454
25.4k
    bool did_alloc;
2455
25.4k
    bool endian_swap;
2456
2457
25.4k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_target_profile, &des_profile,
2458
25.4k
        &render_cond);
2459
2460
#if RAW_DUMP
2461
#if !ARCH_IS_BIG_ENDIAN
2462
    if (was_blended && (*buf)->deep)
2463
      dump_raw_buffer_be(dev->ctx->memory,
2464
          height, width, (*buf)->n_planes, (*buf)->planestride,
2465
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2466
    else
2467
#endif
2468
      dump_raw_buffer(dev->ctx->memory,
2469
          height, width, (*buf)->n_planes, (*buf)->planestride,
2470
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2471
    global_index++;
2472
#endif
2473
2474
    /* If we are doing a 16 bit buffer it will be big endian if we have already done the
2475
       blend, otherwise it will be native endian. GS expects its 16bit buffers to be BE
2476
       but for sanity pdf14 device maintains 16bit buffers in native format.  The CMM
2477
       will need to know if it is dealing with native or BE data. */
2478
25.4k
    if (was_blended && (*buf)->deep) {
2479
        /* Data is in BE.  If we are in a LE machine, CMM will need to swap for
2480
           color conversion */
2481
#if ARCH_IS_BIG_ENDIAN
2482
        endian_swap = false;
2483
#else
2484
0
        endian_swap = true;
2485
0
#endif
2486
25.4k
    } else {
2487
        /* Data is in native format. No swap needed for CMM */
2488
25.4k
        endian_swap = false;
2489
25.4k
    }
2490
2491
25.4k
    cm_result = pdf14_transform_color_buffer_no_matte(pgs, dev->ctx, (gx_device*) dev, *buf,
2492
25.4k
        *buf_ptr, src_profile, des_profile, x, y, width,
2493
25.4k
        height, &did_alloc, (*buf)->deep, endian_swap, num_channels_to_lose);
2494
2495
25.4k
    if (cm_result == NULL)
2496
0
        return_error(gs_error_VMerror);
2497
2498
    /* Update */
2499
25.4k
    *buf = cm_result;
2500
2501
    /* Make sure our buf_ptr is pointing to the proper location */
2502
25.4k
    if (did_alloc)
2503
25.4k
        *buf_ptr = cm_result->data;  /* Note the lack of offset */
2504
2505
#if RAW_DUMP
2506
    dump_raw_buffer(dev->ctx->memory,
2507
        height, width, (*buf)->n_planes, (*buf)->planestride,
2508
        (*buf)->rowstride, "pdf14_put_image_color_convert_post", *buf_ptr, (*buf)->deep);
2509
    global_index++;
2510
#endif
2511
25.4k
    return 0;
2512
25.4k
}
2513
2514
/**
2515
 * pdf14_put_image: Put rendered image to target device.
2516
 * @pdev: The PDF 1.4 rendering device.
2517
 * @pgs: State for image draw operation.
2518
 * @target: The target device.
2519
 *
2520
 * Puts the rendered image in @pdev's buffer to @target. This is called
2521
 * as part of the sequence of popping the PDF 1.4 device filter.
2522
 *
2523
 * Return code: negative on error.
2524
 **/
2525
static  int
2526
pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
2527
1.77M
{
2528
1.77M
    const pdf14_device * pdev = (pdf14_device *)dev;
2529
1.77M
    int code;
2530
1.77M
    gs_image1_t image;
2531
1.77M
    gx_image_enum_common_t *info;
2532
1.77M
    pdf14_buf *buf = pdev->ctx->stack;
2533
1.77M
    gs_int_rect rect;
2534
1.77M
    int y;
2535
1.77M
    int num_comp;
2536
1.77M
    byte *linebuf, *linebuf_unaligned;
2537
1.77M
    gs_color_space *pcs;
2538
1.77M
    int x1, y1, width, height;
2539
1.77M
    byte *buf_ptr;
2540
1.77M
    int num_rows_left;
2541
1.77M
    cmm_profile_t* src_profile = NULL;
2542
1.77M
    cmm_profile_t* des_profile = NULL;
2543
1.77M
    cmm_dev_profile_t *pdf14dev_profile;
2544
1.77M
    cmm_dev_profile_t *dev_target_profile;
2545
1.77M
    uint16_t bg;
2546
1.77M
    bool has_tags = device_encodes_tags(dev);
2547
1.77M
    bool deep = pdev->ctx->deep;
2548
1.77M
    intptr_t planestride;
2549
1.77M
    intptr_t rowstride;
2550
1.77M
    blend_image_row_proc_t blend_row;
2551
1.77M
    bool color_mismatch = false;
2552
1.77M
    bool supports_alpha = false;
2553
1.77M
    int i;
2554
1.77M
    int alpha_offset, tag_offset;
2555
1.77M
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
2556
1.77M
    int rendering_intent_saved;
2557
1.77M
    int additive;
2558
2559
    /* Nothing was ever drawn. */
2560
1.77M
    if (buf == NULL)
2561
169k
        return 0;
2562
2563
1.60M
    additive = buf->group_color_info->isadditive;
2564
2565
1.60M
    src_profile = buf->group_color_info->icc_profile;
2566
2567
1.60M
    num_comp = buf->n_chan - 1;
2568
1.60M
    rect = buf->rect;
2569
1.60M
    planestride = buf->planestride;
2570
1.60M
    rowstride = buf->rowstride;
2571
2572
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
2573
       potential problem. Bug 694190 */
2574
1.60M
    if (buf->saved != NULL) {
2575
126
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
2576
126
    }
2577
1.60M
    if_debug0m('v', dev->memory, "[v]pdf14_put_image\n");
2578
1.60M
    rect_intersect(rect, buf->dirty);
2579
1.60M
    x1 = min(pdev->width, rect.q.x);
2580
1.60M
    y1 = min(pdev->height, rect.q.y);
2581
1.60M
    width = x1 - rect.p.x;
2582
1.60M
    height = y1 - rect.p.y;
2583
#ifdef DUMP_TO_PNG
2584
    dump_planar_rgba(pdev->memory, buf);
2585
#endif
2586
1.60M
    if (width <= 0 || height <= 0 || buf->data == NULL)
2587
312k
        return 0;
2588
1.29M
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
2589
2590
    /* Check that target is OK.  From fuzzing results the target could have been
2591
       destroyed, for e.g if it were a pattern accumulator that was closed
2592
       prematurely (Bug 694154).  We should always be able to to get an ICC
2593
       profile from the target. */
2594
1.29M
    code = dev_proc(target, get_profile)(target,  &dev_target_profile);
2595
1.29M
    if (code < 0)
2596
0
        return code;
2597
1.29M
    if (dev_target_profile == NULL)
2598
0
        return gs_throw_code(gs_error_Fatal);
2599
2600
1.29M
    if (src_profile == NULL) {
2601
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
2602
0
        if (code < 0) {
2603
0
            return code;
2604
0
        }
2605
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2606
0
    }
2607
2608
    /* Check if we have a color conversion issue */
2609
1.29M
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2610
1.29M
    if (!gsicc_profiles_equal(des_profile, src_profile))
2611
215k
        color_mismatch = true;
2612
2613
    /* Check if target supports alpha */
2614
1.29M
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
2615
1.29M
    code = 0;
2616
2617
#if RAW_DUMP
2618
    dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2619
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2620
        "pre_final_blend", buf_ptr, deep);
2621
#endif
2622
2623
    /* Note. The logic below will need a little rework if we ever
2624
       have a device that has tags and alpha support */
2625
1.29M
    if (supports_alpha) {
2626
0
        if (!color_mismatch) {
2627
0
            alpha_offset = num_comp;
2628
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2629
2630
0
            for (i = 0; i < buf->n_planes; i++)
2631
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2632
0
            for (; i < target->color_info.num_components; i++)
2633
0
                buf_ptrs[i] = 0;
2634
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2635
0
                rect.p.x, rect.p.y, width, height,
2636
0
                rowstride, alpha_offset,
2637
0
                tag_offset);
2638
            /* Right now code has number of rows written */
2639
0
        } else {
2640
            /* In this case, just color convert and maintain alpha.  This is a case
2641
               where we either either blend in the right color space and have no
2642
               alpha for the output device or hand back the wrong color space with
2643
               alpha data.  We choose the later. */
2644
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
2645
0
                dev_target_profile, &buf, &buf_ptr, false, rect.p.x, rect.p.y,
2646
0
                width, height, false);
2647
0
            if (code < 0)
2648
0
                return code;
2649
2650
            /* reset */
2651
0
            rowstride = buf->rowstride;
2652
0
            planestride = buf->planestride;
2653
0
            num_comp = buf->n_chan - 1;
2654
0
            alpha_offset = num_comp;
2655
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2656
2657
            /* And then out */
2658
0
            for (i = 0; i < buf->n_planes; i++)
2659
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2660
0
            for (; i < target->color_info.num_components; i++)
2661
0
                buf_ptrs[i] = 0;
2662
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2663
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2664
0
                tag_offset);
2665
            /* Right now code has number of rows written */
2666
0
        }
2667
1.29M
    } else if (has_tags) {
2668
        /* We are going out to a device that supports tags */
2669
0
        if (deep) {
2670
0
            gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
2671
0
                buf->planestride, num_comp, additive, false);
2672
0
        } else {
2673
0
            gx_blend_image_buffer(buf_ptr, width, height, rowstride,
2674
0
                buf->planestride, num_comp, additive);
2675
0
        }
2676
2677
#if RAW_DUMP
2678
        dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2679
            pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2680
            "post_final_blend", buf_ptr, deep);
2681
#endif
2682
2683
        /* Take care of color issues */
2684
0
        if (color_mismatch) {
2685
            /* In this case, just color convert and maintain alpha.  This is a case
2686
               where we either either blend in the right color space and have no
2687
               alpha for the output device or hand back the wrong color space with
2688
               alpha data.  We choose the later. */
2689
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
2690
0
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, false);
2691
0
            if (code < 0)
2692
0
                return code;
2693
2694
#if RAW_DUMP
2695
            dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2696
                pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2697
                "final_color_manage", buf_ptr, deep);
2698
            global_index++;
2699
#endif
2700
0
        }
2701
2702
        /* reset */
2703
0
        rowstride = buf->rowstride;
2704
0
        planestride = buf->planestride;
2705
0
        num_comp = buf->n_chan - 1;
2706
0
        alpha_offset = 0;  /* It is there but this indicates we have done the blend */
2707
0
        tag_offset = buf->has_tags ? buf->n_chan : 0;
2708
2709
        /* And then out */
2710
0
        for (i = 0; i < buf->n_planes; i++)
2711
0
            buf_ptrs[i] = buf_ptr + i * planestride;
2712
0
        for (; i < target->color_info.num_components; i++)
2713
0
            buf_ptrs[i] = 0;
2714
0
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2715
0
            rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2716
0
            tag_offset);
2717
        /* Right now code has number of rows written */
2718
2719
0
    }
2720
2721
    /* If code > 0 then put image worked.  Let it finish and then exit */
2722
1.29M
    if (code > 0) {
2723
        /* We processed some or all of the rows.  Continue until we are done */
2724
0
        num_rows_left = height - code;
2725
0
        while (num_rows_left > 0) {
2726
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2727
0
                                                rect.p.x, rect.p.y + code, width,
2728
0
                                                num_rows_left, rowstride,
2729
0
                                                alpha_offset, tag_offset);
2730
0
            num_rows_left = num_rows_left - code;
2731
0
        }
2732
0
        return 0;
2733
0
    }
2734
2735
    /* Target device did not support alpha or tags.
2736
     * Set color space in preparation for sending an image.
2737
     * color conversion will occur after blending with through
2738
     * the begin typed image work flow.
2739
     */
2740
2741
1.29M
    planestride = buf->planestride;
2742
1.29M
    rowstride = buf->rowstride;
2743
1.29M
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
2744
1.29M
    if (code < 0)
2745
0
        return code;
2746
    /* Need to set this to avoid color management during the image color render
2747
       operation.  Exception is for the special case when the destination was
2748
       CIELAB.  Then we need to convert from default RGB to CIELAB in the put
2749
       image operation.  That will happen here as we should have set the profile
2750
       for the pdf14 device to RGB and the target will be CIELAB.  In addition,
2751
       the case when we have a blend color space that is different than the
2752
       target device color space */
2753
1.29M
    pcs->cmm_icc_profile_data = src_profile;
2754
2755
    /* pcs takes a reference to the profile data it just retrieved. */
2756
1.29M
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_image");
2757
1.29M
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
2758
1.29M
    gs_image_t_init_adjust(&image, pcs, false);
2759
1.29M
    image.ImageMatrix.xx = (float)width;
2760
1.29M
    image.ImageMatrix.yy = (float)height;
2761
1.29M
    image.Width = width;
2762
1.29M
    image.Height = height;
2763
1.29M
    image.BitsPerComponent = deep ? 16 : 8;
2764
1.29M
    image.ColorSpace = pcs;
2765
1.29M
    ctm_only_writable(pgs).xx = (float)width;
2766
1.29M
    ctm_only_writable(pgs).xy = 0;
2767
1.29M
    ctm_only_writable(pgs).yx = 0;
2768
1.29M
    ctm_only_writable(pgs).yy = (float)height;
2769
1.29M
    ctm_only_writable(pgs).tx = (float)rect.p.x;
2770
1.29M
    ctm_only_writable(pgs).ty = (float)rect.p.y;
2771
    /* Make sure that the relative colorimetric rendering intent is
2772
       used for this image. */
2773
1.29M
    rendering_intent_saved = pgs->renderingintent;
2774
1.29M
    pgs->renderingintent = gsRELATIVECOLORIMETRIC;
2775
1.29M
    code = dev_proc(target, begin_typed_image) (target,
2776
1.29M
                                                pgs, NULL,
2777
1.29M
                                                (gs_image_common_t *)&image,
2778
1.29M
                                                NULL, NULL, NULL,
2779
1.29M
                                                pgs->memory, &info);
2780
1.29M
    pgs->renderingintent = rendering_intent_saved;
2781
1.29M
    if (code < 0) {
2782
0
        rc_decrement_only_cs(pcs, "pdf14_put_image");
2783
0
        return code;
2784
0
    }
2785
#if RAW_DUMP
2786
    /* Dump the current buffer to see what we have. */
2787
    dump_raw_buffer(pdev->ctx->memory,
2788
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
2789
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
2790
                    pdev->ctx->stack->n_planes,
2791
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2792
                    "pdF14_putimage", pdev->ctx->stack->data, deep);
2793
    dump_raw_buffer(pdev->ctx->memory,
2794
                    height, width, buf->n_planes,
2795
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2796
                    "PDF14_PUTIMAGE_SMALL", buf_ptr, deep);
2797
    global_index++;
2798
    clist_band_count++;
2799
#endif
2800
    /* Allocate on 32-byte border for AVX CMYK case. Four byte overflow for RGB case */
2801
    /* 28 byte overflow for AVX CMYK case. */
2802
1.29M
#define SSE_ALIGN 32
2803
1.29M
#define SSE_OVERFLOW 28
2804
1.29M
    linebuf_unaligned = gs_alloc_bytes(pdev->memory, width * (num_comp<<deep) + SSE_ALIGN + SSE_OVERFLOW, "pdf14_put_image");
2805
1.29M
    if (linebuf_unaligned == NULL)
2806
0
        return gs_error_VMerror;
2807
1.29M
    linebuf = linebuf_unaligned + ((-(intptr_t)linebuf_unaligned) & (SSE_ALIGN-1));
2808
2809
1.29M
    blend_row = deep ? gx_build_blended_image_row16 :
2810
1.29M
                       gx_build_blended_image_row;
2811
#ifdef WITH_CAL
2812
    blend_row = cal_get_blend_row(pdev->memory->gs_lib_ctx->core->cal_ctx,
2813
                                  blend_row, num_comp, deep);
2814
#endif
2815
2816
1.29M
    bg = additive ? (deep ? 65535 : 255) : 0;
2817
14.4M
    for (y = 0; y < height; y++) {
2818
13.1M
        gx_image_plane_t planes;
2819
13.1M
        int rows_used;
2820
2821
13.1M
        blend_row(buf_ptr, buf->planestride, width, num_comp, bg, linebuf);
2822
13.1M
        planes.data = linebuf;
2823
13.1M
        planes.data_x = 0;
2824
13.1M
        planes.raster = width * num_comp;
2825
13.1M
        info->procs->plane_data(info, &planes, 1, &rows_used);
2826
        /* todo: check return value */
2827
13.1M
        buf_ptr += buf->rowstride;
2828
13.1M
    }
2829
1.29M
    gs_free_object(pdev->memory, linebuf_unaligned, "pdf14_put_image");
2830
1.29M
    info->procs->end_image(info, true);
2831
    /* This will also decrement the device profile */
2832
1.29M
    rc_decrement_only_cs(pcs, "pdf14_put_image");
2833
1.29M
    return code;
2834
1.29M
}
2835
2836
/* Overprint simulation with spots.  Collapse to CMYK */
2837
static void
2838
template_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2839
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2840
    cmyk_composite_map *map, bool keep_alpha)
2841
0
{
2842
0
    int comp_num;
2843
0
    uint cyan, magenta, yellow, black;
2844
0
    cmyk_composite_map *cmyk_map_entry;
2845
0
    int x, y;
2846
0
    intptr_t position;
2847
0
    byte comp, a;
2848
2849
0
    for (y = 0; y < height; y++) {
2850
0
        position = y * rowstride;
2851
0
        for (x = 0; x < width; x++) {
2852
0
            a = buf_ptr[position + planestride * num_comp];
2853
0
            if (a != 0) {
2854
0
                cyan = buf_ptr[position] * frac_1;
2855
0
                magenta = buf_ptr[position + planestride] * frac_1;
2856
0
                yellow = buf_ptr[position + planestride * 2] * frac_1;
2857
0
                black = buf_ptr[position + planestride * 3] * frac_1;
2858
0
                cmyk_map_entry = &(map[4]);
2859
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2860
0
                    comp = buf_ptr[position + planestride * comp_num];
2861
0
                    cyan += cmyk_map_entry->c * comp;
2862
0
                    magenta += cmyk_map_entry->m * comp;
2863
0
                    yellow += cmyk_map_entry->y * comp;
2864
0
                    black += cmyk_map_entry->k * comp;
2865
0
                    cmyk_map_entry++;
2866
0
                }
2867
0
                cyan /= frac_1;
2868
0
                magenta /= frac_1;
2869
0
                yellow /= frac_1;
2870
0
                black /= frac_1;
2871
2872
0
                if (cyan > 255)
2873
0
                    cyan = 255;
2874
0
                if (magenta > 255)
2875
0
                    magenta = 255;
2876
0
                if (yellow > 255)
2877
0
                    yellow = 255;
2878
0
                if (black > 255)
2879
0
                    black = 255;
2880
2881
0
                buf_ptr[position] = cyan;
2882
0
                buf_ptr[position + planestride] = magenta;
2883
0
                buf_ptr[position + planestride * 2] = yellow;
2884
0
                buf_ptr[position + planestride * 3] = black;
2885
0
            }
2886
0
            if (keep_alpha) {
2887
                /* Move the alpha and tag data */
2888
0
                buf_ptr[position + planestride * 4] = a;
2889
0
                if (tag_offset > 0) {
2890
0
                    buf_ptr[position + planestride * 5] =
2891
0
                        buf_ptr[position + planestride * tag_offset];
2892
0
                }
2893
0
            } else {
2894
                /* Remove alpha but keep tags */
2895
0
                if (tag_offset > 0) {
2896
0
                    buf_ptr[position + planestride * 4] =
2897
0
                        buf_ptr[position + planestride * tag_offset];
2898
0
                }
2899
2900
0
            }
2901
0
            position += 1;
2902
0
        }
2903
0
    }
2904
0
}
2905
2906
static void
2907
template_spots_to_cmyk_16(byte *buf_ptr_, int width, int height, intptr_t rowstride,
2908
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2909
    cmyk_composite_map *map, bool keep_alpha)
2910
0
{
2911
0
    int comp_num;
2912
0
    ulong cyan, magenta, yellow, black;
2913
0
    cmyk_composite_map *cmyk_map_entry;
2914
0
    int x, y;
2915
0
    intptr_t position;
2916
0
    ulong comp, a;
2917
0
    uint16_t *buf_ptr = (uint16_t *)(void *)buf_ptr_;
2918
2919
    /* planestride and rowstride are in bytes, and we want them in shorts */
2920
0
    planestride >>= 1;
2921
0
    rowstride >>= 1;
2922
2923
0
    for (y = 0; y < height; y++) {
2924
0
        position = y * rowstride;
2925
0
        for (x = 0; x < width; x++) {
2926
0
            a = buf_ptr[position + planestride * num_comp];
2927
0
            if (a != 0) {
2928
0
                cyan = (ulong)buf_ptr[position] * frac_1_long;
2929
0
                magenta = (ulong)buf_ptr[position + planestride] * frac_1_long;
2930
0
                yellow = (ulong)buf_ptr[position + planestride * 2] * frac_1_long;
2931
0
                black = (ulong)buf_ptr[position + planestride * 3] * frac_1_long;
2932
0
                cmyk_map_entry = &(map[4]);
2933
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2934
0
                    comp = buf_ptr[position + planestride * comp_num];
2935
0
                    cyan += (ulong)cmyk_map_entry->c * comp;
2936
0
                    magenta += (ulong)cmyk_map_entry->m * comp;
2937
0
                    yellow += (ulong)cmyk_map_entry->y * comp;
2938
0
                    black += (ulong)cmyk_map_entry->k * comp;
2939
0
                    cmyk_map_entry++;
2940
0
                }
2941
0
                cyan /= frac_1_long;
2942
0
                magenta /= frac_1_long;
2943
0
                yellow /= frac_1_long;
2944
0
                black /= frac_1_long;
2945
2946
0
                if (cyan > 65535)
2947
0
                    cyan = 65535;
2948
0
                if (magenta > 65535)
2949
0
                    magenta = 65535;
2950
0
                if (yellow > 65535)
2951
0
                    yellow = 65535;
2952
0
                if (black > 65535)
2953
0
                    black = 65535;
2954
2955
#if ARCH_IS_BIG_ENDIAN
2956
                buf_ptr[position] = cyan;
2957
                buf_ptr[position + planestride] = magenta;
2958
                buf_ptr[position + planestride * 2] = yellow;
2959
                buf_ptr[position + planestride * 3] = black;
2960
#else
2961
0
                ((byte *)&buf_ptr[position])[0] = cyan >> 8;
2962
0
                ((byte *)&buf_ptr[position])[1] = cyan;
2963
0
                ((byte *)&buf_ptr[position + planestride])[0] = magenta >> 8;
2964
0
                ((byte *)&buf_ptr[position + planestride])[1] = magenta;
2965
0
                ((byte *)&buf_ptr[position + planestride * 2])[0] = yellow >> 8;
2966
0
                ((byte *)&buf_ptr[position + planestride * 2])[1] = yellow;
2967
0
                ((byte *)&buf_ptr[position + planestride * 3])[0] = black >> 8;
2968
0
                ((byte *)&buf_ptr[position + planestride * 3])[1] = black;
2969
0
#endif
2970
0
            }
2971
            /* Move the alpha and tag data */
2972
#if ARCH_IS_BIG_ENDIAN
2973
            if (keep_alpha) {
2974
                buf_ptr[position + planestride * 4] = a;
2975
                if (tag_offset > 0) {
2976
                    buf_ptr[position + planestride * 5] =
2977
                        buf_ptr[position + planestride * tag_offset];
2978
                }
2979
            } else {
2980
                if (tag_offset > 0) {
2981
                    buf_ptr[position + planestride * 4] =
2982
                        buf_ptr[position + planestride * tag_offset];
2983
                }
2984
            }
2985
#else
2986
0
            if (keep_alpha) {
2987
0
                ((byte *)&buf_ptr[position + planestride * 4])[0] = a >> 8;
2988
0
                ((byte *)&buf_ptr[position + planestride * 4])[1] = a;
2989
0
                if (tag_offset > 0) {
2990
0
                    ((byte *)&buf_ptr[position + planestride * 5])[0] =
2991
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2992
0
                    ((byte *)&buf_ptr[position + planestride * 5])[1] =
2993
0
                        buf_ptr[position + planestride * tag_offset];
2994
0
                }
2995
0
            } else {
2996
0
                if (tag_offset > 0) {
2997
0
                    ((byte *)&buf_ptr[position + planestride * 4])[0] =
2998
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2999
0
                    ((byte *)&buf_ptr[position + planestride * 4])[1] =
3000
0
                        buf_ptr[position + planestride * tag_offset];
3001
0
                }
3002
0
            }
3003
0
#endif
3004
0
            position += 1;
3005
0
        }
3006
0
    }
3007
0
}
3008
3009
static void
3010
pdf14_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
3011
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
3012
    cmyk_composite_map *map, bool keep_alpha, bool deep)
3013
0
{
3014
0
    if (deep) {
3015
0
        if (keep_alpha) {
3016
0
            if (tag_offset > 0) {
3017
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3018
0
                    planestride, num_comp, spot_start, tag_offset,
3019
0
                    map, true);
3020
0
            } else {
3021
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3022
0
                    planestride, num_comp, spot_start, 0,
3023
0
                    map, true);
3024
0
            }
3025
0
        } else {
3026
0
            if (tag_offset > 0) {
3027
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3028
0
                    planestride, num_comp, spot_start, tag_offset,
3029
0
                    map, false);
3030
0
            } else {
3031
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3032
0
                    planestride, num_comp, spot_start, 0,
3033
0
                    map, false);
3034
0
            }
3035
0
        }
3036
0
    } else {
3037
0
        if (keep_alpha) {
3038
0
            if (tag_offset > 0) {
3039
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3040
0
                    planestride, num_comp, spot_start, tag_offset,
3041
0
                    map, true);
3042
0
            } else {
3043
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3044
0
                    planestride, num_comp, spot_start, 0,
3045
0
                    map, true);
3046
0
            }
3047
0
        } else {
3048
0
            if (tag_offset > 0) {
3049
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3050
0
                    planestride, num_comp, spot_start, tag_offset,
3051
0
                    map, false);
3052
0
            } else {
3053
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3054
0
                    planestride, num_comp, spot_start, 0,
3055
0
                    map, false);
3056
0
            }
3057
0
        }
3058
0
    }
3059
0
}
3060
3061
/* This is for the case where we have mixture of spots and additive color.
3062
   For example, RGB + spots or Gray + spots */
3063
static void
3064
pdf14_blend_image_mixed_buffer(byte* buf_ptr, int width, int height, intptr_t rowstride,
3065
    intptr_t planestride, int num_comp, int spot_start)
3066
25.4k
{
3067
25.4k
    int x, y;
3068
25.4k
    intptr_t position;
3069
25.4k
    byte comp, a;
3070
25.4k
    int tmp, comp_num;
3071
3072
271k
    for (y = 0; y < height; y++) {
3073
246k
        position = y * rowstride;
3074
250M
        for (x = 0; x < width; x++) {
3075
250M
            a = buf_ptr[position + planestride * num_comp];
3076
250M
            if ((a + 1) & 0xfe) {
3077
10.3M
                a ^= 0xff;
3078
41.5M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3079
31.1M
                    comp = buf_ptr[position + planestride * comp_num];
3080
31.1M
                    tmp = ((0xff - comp) * a) + 0x80;
3081
31.1M
                    comp += (tmp + (tmp >> 8)) >> 8;
3082
31.1M
                    buf_ptr[position + planestride * comp_num] = comp;
3083
31.1M
                }
3084
10.3M
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3085
0
                    comp = buf_ptr[position + planestride * comp_num];
3086
0
                    tmp = ((-comp) * a) + 0x80;
3087
0
                    comp += (tmp + (tmp >> 8)) >> 8;
3088
0
                    buf_ptr[position + planestride * comp_num] = comp;
3089
0
                }
3090
239M
            } else if (a == 0) {
3091
193M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3092
145M
                    buf_ptr[position + planestride * comp_num] = 0xff;
3093
145M
                }
3094
60.7M
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3095
12.2M
                    buf_ptr[position + planestride * comp_num] = 0;
3096
12.2M
                }
3097
48.4M
            }
3098
250M
            position += 1;
3099
250M
        }
3100
246k
    }
3101
25.4k
}
3102
3103
static void
3104
pdf14_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, intptr_t rowstride,
3105
    intptr_t planestride, int num_comp, int spot_start)
3106
0
{
3107
0
    uint16_t* buf_ptr = (uint16_t*)(void*)buf_ptr_;
3108
0
    int x, y;
3109
0
    intptr_t position;
3110
0
    int comp, a;
3111
0
    int tmp, comp_num;
3112
3113
    /* planestride and rowstride are in bytes, and we want them in shorts */
3114
0
    planestride >>= 1;
3115
0
    rowstride >>= 1;
3116
3117
    /* Note that the input here is native endian, and the output must be in big endian! */
3118
0
    for (y = 0; y < height; y++) {
3119
0
        position = y * rowstride;
3120
0
        for (x = 0; x < width; x++) {
3121
            /* composite RGBA (or CMYKA, etc.) pixel with over solid background */
3122
0
            a = buf_ptr[position + planestride * num_comp];
3123
0
            if (a == 0) {
3124
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3125
0
                    buf_ptr[position + planestride * comp_num] = 0xffff;
3126
0
                }
3127
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3128
0
                    buf_ptr[position + planestride * comp_num] = 0;
3129
0
                }
3130
0
            } else if (a == 0xffff) {
3131
#if ARCH_IS_BIG_ENDIAN
3132
#else
3133
                /* Convert from native -> big endian */
3134
0
                for (comp_num = 0; comp_num < num_comp; comp_num++) {
3135
0
                    comp = buf_ptr[position + planestride * comp_num];
3136
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3137
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3138
0
                }
3139
0
#endif
3140
0
            } else {
3141
0
                a ^= 0xffff;
3142
0
                a += a >> 15; /* a is now 0 to 0x10000 */
3143
0
                a >>= 1; /* We can only use 15 bits as bg-comp has a sign bit we can't lose */
3144
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3145
0
                    comp = buf_ptr[position + planestride * comp_num];
3146
0
                    tmp = ((0xffff - comp) * a) + 0x4000;
3147
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3148
                    /* Store as big endian */
3149
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3150
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3151
0
                }
3152
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3153
0
                    comp = buf_ptr[position + planestride * comp_num];
3154
0
                    tmp = ((0 - comp) * a) + 0x4000;
3155
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3156
                    /* Store as big endian */
3157
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3158
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3159
0
                }
3160
0
            }
3161
0
            position += 1;
3162
0
        }
3163
0
    }
3164
0
}
3165
3166
static int
3167
pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target,
3168
    gs_gstate* pgs, pdf14_buf* buf, intptr_t planestride_in,
3169
    intptr_t rowstride_in, int x0, int y0, int width, int height,
3170
    int num_comp, int additive, bool has_tags, gs_int_rect rect_in,
3171
    gs_separations* pseparations, bool deep)
3172
74.0k
{
3173
74.0k
    pdf14_device* pdev = (pdf14_device*)dev;
3174
74.0k
    int code = 0;
3175
74.0k
    int y;
3176
74.0k
    int num_rows_left;
3177
74.0k
    int i;
3178
74.0k
    gs_int_rect rect = rect_in;
3179
74.0k
    intptr_t planestride = planestride_in;
3180
74.0k
    intptr_t rowstride = rowstride_in;
3181
74.0k
    byte* buf_ptr = NULL;
3182
74.0k
    cmm_profile_t* src_profile = buf->group_color_info->icc_profile;
3183
74.0k
    cmm_profile_t* des_profile = NULL;
3184
74.0k
    cmm_dev_profile_t* dev_target_profile;
3185
74.0k
    cmm_dev_profile_t* pdf14dev_profile;
3186
74.0k
    bool color_mismatch = false;
3187
74.0k
    bool supports_alpha = false;
3188
74.0k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
3189
74.0k
    int alpha_offset = num_comp;
3190
74.0k
    int tag_offset = has_tags ? num_comp + 1 : 0;
3191
74.0k
    gs_color_space *pcs;
3192
74.0k
    gs_image1_t image;
3193
74.0k
    gx_image_enum_common_t *info;
3194
74.0k
    gx_image_plane_t planes[GS_IMAGE_MAX_COMPONENTS];
3195
74.0k
    pdf14_buf *cm_result = NULL;
3196
74.0k
    bool did_alloc;
3197
74.0k
    bool target_sep_device = dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0);
3198
74.0k
    bool has_spots = pdev->ctx->num_spots > 0;
3199
74.0k
    bool blend_spots = !target_sep_device && has_spots;
3200
74.0k
    bool lose_channels = false;
3201
3202
    /* Check if group color space is CMYK based */
3203
74.0k
    code = dev_proc(target, get_profile)(target, &dev_target_profile);
3204
74.0k
    if (code < 0)
3205
0
        return code;
3206
74.0k
    if (dev_target_profile == NULL)
3207
0
        return gs_throw_code(gs_error_Fatal);
3208
3209
74.0k
    if (src_profile == NULL) {
3210
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
3211
0
        if (code < 0) {
3212
0
            return code;
3213
0
        }
3214
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3215
0
    }
3216
3217
    /* If the target device does not support spot colors and we have spot colors
3218
       here due to overprint simulation (blend_spots == true), then we will need to convert the base
3219
       colors to CMYK if it is RGB or Gray so tha we can blend in the spot colors */
3220
74.0k
    if (blend_spots && src_profile->data_cs != gsCMYK) {
3221
3222
0
        cm_result = pdf14_transform_color_buffer_no_matte(pgs, pdev->ctx, (gx_device *)dev, buf,
3223
0
            buf->data, src_profile, pgs->icc_manager->default_cmyk, 0, 0, buf->rect.q.x,
3224
0
            buf->rect.q.y, &did_alloc, buf->deep, false, false);
3225
0
        if (cm_result == NULL)
3226
0
            return_error(gs_error_VMerror);
3227
3228
        /* Update */
3229
0
        buf = cm_result;
3230
0
        src_profile = pgs->icc_manager->default_cmyk;
3231
0
        num_comp = buf->n_chan - 1;
3232
0
        additive = 0;
3233
0
        tag_offset = has_tags ? num_comp + 1 : 0;
3234
0
        alpha_offset = num_comp;
3235
3236
#if RAW_DUMP
3237
        buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3238
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3239
            "convertbase_to_cmyk_for_spot_blend", buf_ptr, deep);
3240
        global_index++;
3241
#endif
3242
0
    }
3243
3244
    /* Fix order map if needed */
3245
347k
    for (i = 0; i < num_comp; i++) {
3246
273k
        pdev->devn_params.separation_order_map[i] = i;
3247
273k
    }
3248
3249
    /* Check if we have a color conversion issue */
3250
74.0k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3251
74.0k
    if (!gsicc_profiles_equal(des_profile, src_profile))
3252
25.4k
        color_mismatch = true;
3253
74.0k
    if (des_profile->data_cs == gsNCHANNEL)
3254
0
        lose_channels = true;
3255
3256
    /* Check if target supports alpha */
3257
74.0k
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
3258
74.0k
    code = 0;
3259
3260
74.0k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3261
3262
    /* Note. The logic below will need a little rework if we ever
3263
       have a device that has tags and alpha support */
3264
74.0k
    if (supports_alpha) {
3265
3266
        /* If doing simulated overprint, Bring the spot color channels into
3267
           CMYK. Data is planar and 16 bit data in native format. */
3268
0
        if (pdev->overprint_sim && pdev->devn_params.page_spot_colors > 0) {
3269
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3270
3271
            /* In the clist case, we need to get equiv spots out of the pseudo-band. */
3272
0
            if (pdev->pclist_device != NULL) {
3273
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3274
3275
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3276
0
                if (code < 0)
3277
0
                    return code;
3278
0
            }
3279
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3280
3281
            /* Now we go to big endian */
3282
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3283
0
                planestride, num_comp, src_profile->num_comps,
3284
0
                tag_offset, cmyk_map, true, deep);
3285
3286
            /* Reset buffer information. We have CMYK+alpha and maybe tags */
3287
0
            buf->n_chan = buf->n_chan - buf->num_spots;
3288
0
            buf->n_planes = buf->n_planes - buf->num_spots;
3289
0
            buf->num_spots = 0;
3290
0
            num_comp = buf->n_chan - 1;
3291
0
            tag_offset = has_tags ? buf->n_planes - 1 : 0; /* Tags at end */
3292
0
        }
3293
3294
0
        if (!color_mismatch) {
3295
0
            for (i = 0; i < buf->n_planes; i++)
3296
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3297
0
            for (; i < target->color_info.num_components; i++)
3298
0
                buf_ptrs[i] = 0;
3299
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3300
0
                rect.p.x, rect.p.y, width, height,
3301
0
                rowstride, alpha_offset, tag_offset);
3302
            /* Right now code has number of rows written */
3303
0
        } else {
3304
            /* In this case, just color convert and maintain alpha.
3305
               This is a case where we either either blend in the
3306
               right color space and have no alpha for the output
3307
               device or hand back the wrong color space with
3308
               alpha data.  We choose the later. */
3309
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
3310
0
                        dev_target_profile, &buf, &buf_ptr, false, rect.p.x,
3311
0
                        rect.p.y, width, height, false);
3312
0
            if (code < 0)
3313
0
                return code;
3314
3315
            /* reset */
3316
0
            rowstride = buf->rowstride;
3317
0
            planestride = buf->planestride;
3318
0
            num_comp = buf->n_chan - 1;
3319
0
            alpha_offset = num_comp;
3320
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3321
3322
            /* And then out */
3323
0
            for (i = 0; i < buf->n_planes; i++)
3324
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3325
0
            for (; i < target->color_info.num_components; i++)
3326
0
                buf_ptrs[i] = 0;
3327
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3328
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
3329
0
                tag_offset);
3330
            /* Right now code has number of rows written.  Writing continues below */
3331
0
        }
3332
74.0k
    } else {
3333
        /* Device could not handle the alpha data (we actually don't have
3334
           a device that does spot colorants and has an alpha channel so
3335
           the above code is untested.  Go ahead and preblend now and then
3336
           color convert if needed */
3337
#if RAW_DUMP
3338
           /* Dump before and after the blend to make sure we are doing that ok */
3339
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3340
            "pre_put_image_blend_image", buf_ptr, deep);
3341
        global_index++;
3342
#endif
3343
3344
74.0k
        if (color_mismatch && (src_profile->data_cs == gsRGB || src_profile->data_cs == gsGRAY)) {
3345
25.4k
            if (deep) {
3346
            /* In this case, we are NOT going to bring the spots into the CMYK
3347
               equivalent colors, since otherwise src_profile would be CMYK based.  So
3348
               16 bit data will be converted now from native endian to big endian during
3349
               the blending process */
3350
0
                pdf14_blend_image_mixed_buffer16(buf_ptr, width, height, rowstride,
3351
0
                    planestride, num_comp, src_profile->num_comps);
3352
25.4k
            } else {
3353
25.4k
                pdf14_blend_image_mixed_buffer(buf_ptr, width, height, rowstride,
3354
25.4k
                    planestride, num_comp, src_profile->num_comps);
3355
25.4k
            }
3356
48.5k
        } else {
3357
48.5k
            if (deep) {
3358
            /* In this case, if blend_spots == true, we will shortly be bringing
3359
               the spot colors to CMYK equivalent colors. It is at that time that
3360
               we will convert from native endian to big endian. In all other
3361
               cases this blending will due to conversion from native to BE */
3362
0
                bool keep_native = (blend_spots == true);
3363
3364
0
                gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
3365
0
                    planestride, num_comp, additive, keep_native);
3366
48.5k
            } else {
3367
48.5k
                gx_blend_image_buffer(buf_ptr, width, height, rowstride,
3368
48.5k
                    planestride, num_comp, additive);
3369
48.5k
            }
3370
48.5k
        }
3371
3372
74.0k
        if (deep && has_tags)
3373
0
        {
3374
            /* We still need to convert the tags from Native to BE */
3375
#if ARCH_IS_BIG_ENDIAN
3376
#else
3377
0
            uint16_t *tags = (uint16_t *)&buf_ptr[tag_offset * planestride];
3378
0
            int i, j;
3379
0
            for (j = 0; j < height; j++)
3380
0
            {
3381
0
                for (i = 0; i < width; i++)
3382
0
                {
3383
0
                    uint16_t tag = *tags++;
3384
0
                    ((byte *)tags)[-2] = tag >> 8;
3385
0
                    ((byte *)tags)[-1] = tag;
3386
0
                }
3387
0
                tags += (buf->rowstride>>1) - width;
3388
0
            }
3389
0
#endif
3390
0
        }
3391
3392
#if RAW_DUMP
3393
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3394
            "post_put_image_blend_image", buf_ptr, deep);
3395
        global_index++;
3396
#endif
3397
3398
        /* If doing simulated overprint and we are not going to a sep device and
3399
           we have spot colors, then bring the spot color channels into CMYK
3400
           (We should have already converted our base color space to CMYK if it was RGB or gray).
3401
           At this point, data is planar and 16 bit data is still in native format. It is
3402
           here that 16 bit data will be converted to BE. Otherwise it will have been converted
3403
           above during the alpha blend operation. */
3404
74.0k
        if (blend_spots) {
3405
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3406
3407
            /* In the clist case, we need to get equiv spots out of the
3408
               pseudo-band. */
3409
0
            if (pdev->pclist_device != NULL) {
3410
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3411
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3412
0
                if (code < 0)
3413
0
                    return code;
3414
0
            }
3415
3416
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3417
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3418
0
                planestride, num_comp, src_profile->num_comps,
3419
0
                tag_offset, cmyk_map, false, deep);
3420
3421
            /* Reset buffer information. We have CMYK and maybe tags */
3422
0
            num_comp = 4;
3423
0
            alpha_offset = 0;
3424
0
            buf->n_chan = buf->n_chan - buf->num_spots - 1;     /* No spots or alpha */
3425
0
            buf->n_planes = buf->n_planes - buf->num_spots - 1; /* No spots or alpha */
3426
0
            tag_offset = has_tags ? buf->n_chan : 0;      /* Tags at end */
3427
0
            buf->num_spots = 0;
3428
3429
#if RAW_DUMP
3430
            dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3431
                "post_put_image_spot_to_cmyk", buf_ptr, deep);
3432
            global_index++;
3433
#endif
3434
0
        }
3435
3436
        /* Map to the destination color space */
3437
74.0k
        if (color_mismatch) {
3438
            /* We started out with the original process colorants, and spots. If we have an
3439
             * nchannel output profile, this can mean that the first few spots might come from
3440
             * that and the rest from the document itself. e.g:
3441
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3442
             * Then we might have a blend space that changes the process colorants:
3443
             *        R, G, B, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3444
             * Now we're about to convert 'RGB' back to 'CMYKII'.
3445
             * If we're not careful, we'll end up with:
3446
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3447
             * so we might need to lose some channels.      ^^^^^^^^^^^^^^^^^^^^^^^^
3448
             */
3449
25.4k
            int num_original_process_colorants = target->color_info.num_components - has_tags - buf->num_spots;
3450
25.4k
            int num_channels_to_lose = lose_channels ? des_profile->num_comps - num_original_process_colorants : 0;
3451
25.4k
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
3452
25.4k
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, num_channels_to_lose);
3453
25.4k
            if (code < 0)
3454
0
                return code;
3455
3456
            /* reset */
3457
25.4k
            rowstride = buf->rowstride;
3458
25.4k
            planestride = buf->planestride;
3459
25.4k
            num_comp = buf->n_chan;
3460
25.4k
            tag_offset = buf->has_tags ? (buf->n_chan - num_channels_to_lose) : 0;
3461
25.4k
        }
3462
3463
#if RAW_DUMP
3464
        /* Dump after the CS transform */
3465
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3466
            "post_put_image_color_convert", buf_ptr, deep);
3467
        global_index++;
3468
        /* clist_band_count++; */
3469
#endif
3470
3471
        /* Try put_image again. This can occur if the
3472
           target, like psdcmyk and tiffsep, support put_image */
3473
74.0k
        alpha_offset = 0;
3474
447k
        for (i = 0; i < buf->n_planes; i++)
3475
373k
            buf_ptrs[i] = buf_ptr + i * planestride;
3476
74.0k
        for (; i < target->color_info.num_components; i++)
3477
0
            buf_ptrs[i] = 0;
3478
74.0k
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3479
74.0k
            rect.p.x, rect.p.y, width, height,
3480
74.0k
            rowstride, alpha_offset, tag_offset);
3481
74.0k
    }
3482
3483
    /* Put image was succesful.  We processed some or all of the rows.
3484
       Continue until we are done */
3485
74.0k
    if (code > 0) {
3486
252
        num_rows_left = height - code;
3487
252
        while (num_rows_left > 0) {
3488
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3489
0
                rect.p.x, rect.p.y + code, width, num_rows_left, rowstride,
3490
0
                alpha_offset, tag_offset);
3491
0
            if (code < 0) {
3492
0
                return code;
3493
0
            }
3494
0
            num_rows_left = num_rows_left - code;
3495
0
        }
3496
252
        return 0;
3497
252
    }
3498
3499
    /* Sep devices all support put_image (tiffsep and psdcmyk)
3500
       as well as those devices that support alpha (pngalpha,
3501
       png16malpha). If we are here, then we are doing an
3502
       overprint simulation on some other device. Image data
3503
       is aleady blended and in device color space. */
3504
73.8k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
3505
73.8k
    if (code < 0)
3506
0
        return code;
3507
3508
    /* Already in destination CS */
3509
73.8k
    pcs->cmm_icc_profile_data = des_profile;
3510
3511
    /* pcs takes a reference to the profile data it just retrieved. */
3512
73.8k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_blended_image_cmykspot");
3513
73.8k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
3514
3515
    /* If we have more components to write out than are in the des_profile,
3516
     * then just using a PCS based on des_profile, will result in us dropping
3517
     * the spot colors.
3518
     * So, if our target supports devn colors, we instead construct a
3519
     * DevN device space with colors names taken from the devn_params, and
3520
     * use that instead. */
3521
73.8k
    if (des_profile->num_comps != target->color_info.num_components &&
3522
2.69k
        dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0))
3523
2.69k
    {
3524
2.69k
        int num_std;
3525
2.69k
        gs_devn_params *devn_params =  dev_proc(target, ret_devn_params)(target);
3526
2.69k
        gs_color_space *pcs2 = pcs;
3527
2.69k
        code = gs_cspace_new_DeviceN(&pcs, target->color_info.num_components,
3528
2.69k
                                     pcs2, pgs->memory->non_gc_memory);
3529
2.69k
        if (code < 0)
3530
0
            return code;
3531
        /* set up a usable DeviceN space with info from the tdev->devn_params */
3532
2.69k
        pcs->params.device_n.use_alt_cspace = false;
3533
2.69k
        num_std = devn_params->num_std_colorant_names;
3534
13.4k
        for (i = 0; i < num_std; i++) {
3535
10.7k
            const char *name = devn_params->std_colorant_names[i];
3536
10.7k
            size_t len = strlen(name);
3537
10.7k
            pcs->params.device_n.names[i] = (char *)gs_alloc_bytes(pgs->memory->non_gc_memory, len + 1, "mem_planar_put_image_very_slow");
3538
10.7k
            if (pcs->params.device_n.names[i] == NULL) {
3539
0
                int j = 0;
3540
0
                for (j = 0;j < i; j++) {
3541
0
                    if (pcs->params.device_n.names[j] != NULL)
3542
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3543
0
                    pcs->params.device_n.names[j] = NULL;
3544
0
                }
3545
0
                return_error(gs_error_VMerror);
3546
0
            }
3547
10.7k
            strcpy(pcs->params.device_n.names[i], name);
3548
10.7k
        }
3549
2.69k
        for (; i < devn_params->separations.num_separations; i++) {
3550
0
            devn_separation_name *name = &devn_params->separations.names[i - num_std];
3551
0
            pcs->params.device_n.names[i] = (char *)gs_alloc_bytes(pgs->memory->non_gc_memory, name->size + 1, "mem_planar_put_image_very_slow");
3552
0
            if (pcs->params.device_n.names[i] == NULL) {
3553
0
                int j = 0;
3554
0
                for (j = 0;j < i; j++) {
3555
0
                    if (pcs->params.device_n.names[j] != NULL)
3556
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3557
0
                    pcs->params.device_n.names[j] = NULL;
3558
0
                }
3559
0
                return_error(gs_error_VMerror);
3560
0
            }
3561
0
            memcpy(pcs->params.device_n.names[i], devn_params->separations.names[i - num_std].data, name->size);
3562
0
            pcs->params.device_n.names[i][name->size] = 0;
3563
0
        }
3564
2.69k
        if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
3565
0
            return code;
3566
0
        }
3567
        /* One last thing -- we need to fudge the pgs->color_component_map */
3568
16.1k
        for (i=0; i < dev->color_info.num_components; i++)
3569
13.4k
            pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
3570
2.69k
    }
3571
3572
73.8k
    gs_image_t_init_adjust(&image, pcs, false);
3573
73.8k
    image.ImageMatrix.xx = (float)width;
3574
73.8k
    image.ImageMatrix.yy = (float)height;
3575
73.8k
    image.Width = width;
3576
73.8k
    image.Height = height;
3577
73.8k
    image.BitsPerComponent = deep ? 16 : 8;
3578
73.8k
    image.ColorSpace = pcs;
3579
73.8k
    image.format = gs_image_format_component_planar;
3580
3581
73.8k
    ctm_only_writable(pgs).xx = (float)width;
3582
73.8k
    ctm_only_writable(pgs).xy = 0;
3583
73.8k
    ctm_only_writable(pgs).yx = 0;
3584
73.8k
    ctm_only_writable(pgs).yy = (float)height;
3585
73.8k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
3586
73.8k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
3587
73.8k
    code = dev_proc(target, begin_typed_image) (target,
3588
73.8k
        pgs, NULL, (gs_image_common_t *)&image,
3589
73.8k
        NULL, NULL, NULL, pgs->memory, &info);
3590
73.8k
    if (code < 0) {
3591
0
        rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3592
0
        return code;
3593
0
    }
3594
#if RAW_DUMP
3595
    /* Dump the current buffer to see what we have. */
3596
    dump_raw_buffer(pdev->ctx->memory,
3597
        pdev->ctx->stack->rect.q.y - pdev->ctx->stack->rect.p.y,
3598
        pdev->ctx->stack->rect.q.x - pdev->ctx->stack->rect.p.x,
3599
        pdev->ctx->stack->n_planes,
3600
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3601
        "put_image_final_big", pdev->ctx->stack->data, deep);
3602
    dump_raw_buffer(pdev->ctx->memory,
3603
        height, width, buf->n_planes,
3604
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3605
        "put_image_final_small", buf_ptr, deep);
3606
    global_index++;
3607
    clist_band_count++;
3608
#endif
3609
3610
397k
    for (i = 0; i < num_comp; i++) {
3611
323k
        planes[i].data = buf_ptr + i * planestride;
3612
323k
        planes[i].data_x = 0;
3613
323k
        planes[i].raster = buf->rowstride;
3614
323k
    }
3615
3616
819k
    for (y = 0; y < height; y++) {
3617
746k
        int rows_used;
3618
3619
746k
        info->procs->plane_data(info, (const gx_image_plane_t*) &planes, 1, &rows_used);
3620
3621
3.99M
        for (i = 0; i < num_comp; i++) {
3622
3.24M
            planes[i].data += buf->rowstride;
3623
3.24M
        }
3624
746k
    }
3625
73.8k
    info->procs->end_image(info, true);
3626
3627
    /* This will also decrement the profile */
3628
73.8k
    rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3629
73.8k
    return code;
3630
73.8k
}
3631
3632
/**
3633
 * pdf14_cmykspot_put_image: Put rendered image to target device.
3634
 * @pdev: The PDF 1.4 rendering device.
3635
 * @pgs: State for image draw operation.
3636
 * @target: The target device.
3637
 *
3638
 * Puts the rendered image in @pdev's buffer to @target. This is called
3639
 * as part of the sequence of popping the PDF 1.4 device filter.
3640
 *
3641
 * Return code: negative on error.
3642
 **/
3643
static  int
3644
pdf14_cmykspot_put_image(gx_device *dev, gs_gstate *pgs, gx_device *target)
3645
153k
{
3646
153k
    pdf14_device *pdev = (pdf14_device *)dev;
3647
153k
    pdf14_buf *buf = pdev->ctx->stack;
3648
153k
    gs_int_rect rect;
3649
153k
    int x1, y1, width, height;
3650
153k
    gs_devn_params *pdevn_params = &pdev->devn_params;
3651
153k
    gs_separations *pseparations = &pdevn_params->separations;
3652
153k
    intptr_t planestride;
3653
153k
    intptr_t rowstride;
3654
153k
    bool deep = pdev->ctx->deep;
3655
153k
    int num_comp;
3656
3657
    /* Nothing was ever drawn. */
3658
153k
    if (buf == NULL)
3659
40.3k
        return 0;
3660
3661
113k
    num_comp = buf->n_chan - 1;
3662
113k
    rect = buf->rect;
3663
113k
    planestride = buf->planestride;
3664
113k
    rowstride = buf->rowstride;
3665
3666
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3667
       potential problem. Bug 694190 */
3668
113k
    if (buf->saved != NULL) {
3669
1
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3670
1
    }
3671
113k
    if_debug0m('v', dev->memory, "[v]pdf14_cmykspot_put_image\n");
3672
113k
    rect_intersect(rect, buf->dirty);
3673
113k
    x1 = min(pdev->width, rect.q.x);
3674
113k
    y1 = min(pdev->height, rect.q.y);
3675
113k
    width = x1 - rect.p.x;
3676
113k
    height = y1 - rect.p.y;
3677
113k
    if (width <= 0 || height <= 0 || buf->data == NULL)
3678
39.3k
        return 0;
3679
3680
#if RAW_DUMP
3681
    /* Dump the current buffer to see what we have. */
3682
    dump_raw_buffer(pdev->ctx->memory,
3683
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
3684
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
3685
                    pdev->ctx->stack->n_planes,
3686
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3687
                    "CMYK_SPOT_PUTIMAGE", pdev->ctx->stack->data,
3688
                    pdev->ctx->stack->deep);
3689
3690
    global_index++;
3691
    clist_band_count++;
3692
#endif
3693
3694
74.0k
    return pdf14_put_blended_image_cmykspot(dev, target, pgs,
3695
74.0k
                      buf, planestride, rowstride,
3696
74.0k
                      rect.p.x, rect.p.y, width, height, num_comp, buf->group_color_info->isadditive,
3697
74.0k
                      buf->has_tags, rect, pseparations, deep);
3698
113k
}
3699
3700
/**
3701
 * pdf14_custom_put_image: Put rendered image to target device.
3702
 * @pdev: The PDF 1.4 rendering device.
3703
 * @pgs: State for image draw operation.
3704
 * @target: The target device.
3705
 *
3706
 * Puts the rendered image in @pdev's buffer to @target. This is called
3707
 * as part of the sequence of popping the PDF 1.4 device filter.
3708
 *
3709
 * Return code: negative on error.
3710
 **/
3711
static  int
3712
pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
3713
0
{
3714
0
    pdf14_device * pdev = (pdf14_device *)dev;
3715
0
    pdf14_buf *buf = pdev->ctx->stack;
3716
0
    bool deep = pdev->ctx->deep;
3717
0
    gs_int_rect rect;
3718
0
    int x0, y0;
3719
0
    intptr_t planestride;
3720
0
    intptr_t rowstride;
3721
0
    int num_comp;
3722
0
    uint16_t bg;
3723
0
    int x1, y1, width, height;
3724
0
    byte *buf_ptr;
3725
3726
    /* Nothing was ever drawn. */
3727
0
    if (buf == NULL)
3728
0
        return 0;
3729
3730
0
    bg = pdev->ctx->additive ? 0xffff : 0;
3731
0
    num_comp = buf->n_chan - 1;
3732
0
    rect = buf->rect;
3733
0
    x0 = rect.p.x;
3734
0
    y0 = rect.p.y;
3735
0
    planestride = buf->planestride;
3736
0
    rowstride = buf->rowstride;
3737
3738
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3739
       potential problem. Bug 694190 */
3740
0
    if (buf->saved != NULL) {
3741
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3742
0
    }
3743
0
    if_debug0m('v', dev->memory, "[v]pdf14_custom_put_image\n");
3744
0
    rect_intersect(rect, buf->dirty);
3745
0
    x1 = min(pdev->width, rect.q.x);
3746
0
    y1 = min(pdev->height, rect.q.y);
3747
0
    width = x1 - rect.p.x;
3748
0
    height = y1 - rect.p.y;
3749
0
    if (width <= 0 || height <= 0 || buf->data == NULL)
3750
0
        return 0;
3751
0
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x)<<deep);
3752
3753
0
    return gx_put_blended_image_custom(target, buf_ptr,
3754
0
                      planestride, rowstride,
3755
0
                      x0, y0, width, height, num_comp, bg, deep);
3756
0
}
3757
3758
/* This is rather nasty: in the event we are interrupted (by an error) between a push and pop
3759
 * of one or more groups, we have to cycle through any ICC profile changes since the push
3760
 * putting everything back how it was, and cleaning up the reference counts.
3761
 */
3762
static void pdf14_cleanup_group_color_profiles (pdf14_device *pdev)
3763
3.96M
{
3764
3.96M
    if (pdev->ctx && pdev->ctx->stack) {
3765
1.74M
        pdf14_buf *buf, *next;
3766
3767
1.74M
        for (buf = pdev->ctx->stack->saved; buf != NULL; buf = next) {
3768
127
            pdf14_group_color_t *group_color_info = buf->group_color_info;
3769
127
            next = buf->saved;
3770
254
            while (group_color_info) {
3771
127
               if (group_color_info->icc_profile != NULL) {
3772
127
                   cmm_profile_t *group_profile;
3773
127
                   gsicc_rendering_param_t render_cond;
3774
127
                   cmm_dev_profile_t *dev_profile;
3775
127
                   int code = dev_proc((gx_device *)pdev, get_profile)((gx_device *)pdev,  &dev_profile);
3776
3777
127
                   if (code >= 0) {
3778
127
                       gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
3779
127
                                             &render_cond);
3780
3781
127
                       gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
3782
127
                                               -1, "pdf14_end_transparency_group");
3783
127
                       pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
3784
127
                           group_color_info->icc_profile;
3785
127
                       group_color_info->icc_profile = NULL;
3786
127
                   }
3787
127
               }
3788
3789
127
               group_color_info = group_color_info->previous;
3790
127
            }
3791
127
        }
3792
1.74M
    }
3793
3.96M
}
3794
3795
static  int
3796
pdf14_close(gx_device *dev)
3797
1.98M
{
3798
1.98M
    pdf14_device *pdev = (pdf14_device *)dev;
3799
3800
1.98M
    pdf14_cleanup_group_color_profiles(pdev);
3801
3802
1.98M
    if (pdev->ctx) {
3803
1.96M
        pdf14_ctx_free(pdev->ctx);
3804
1.96M
        pdev->ctx = NULL;
3805
1.96M
    }
3806
1.98M
    return 0;
3807
1.98M
}
3808
3809
/* This is called when something has gone wrong and the interpreter received a
3810
   stop while in the middle of doing something with the PDF14 device.  We need
3811
   to clean up and end this in a graceful manner */
3812
static int
3813
pdf14_discard_trans_layer(gx_device *dev, gs_gstate * pgs)
3814
0
{
3815
0
    pdf14_device *pdev = (pdf14_device *)dev;
3816
    /* The things that need to be cleaned up */
3817
0
    pdf14_ctx *ctx = pdev->ctx;
3818
0
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
3819
0
    pdf14_group_color_t *group_color = pdev->color_model_stack;
3820
3821
    /* Free up the smask color */
3822
0
    if (smaskcolor != NULL) {
3823
0
        smaskcolor->ref_count = 1;
3824
0
        pdf14_decrement_smask_color(pgs, dev);
3825
0
        pdev->smaskcolor = NULL;
3826
0
    }
3827
3828
    /* Free up the nested color procs and decrement the profiles */
3829
0
    if (group_color != NULL) {
3830
0
        while (group_color->previous != NULL)
3831
0
            pdf14_pop_group_color(dev, pgs);
3832
0
        gs_free_object(dev->memory->stable_memory, group_color, "pdf14_discard_trans_layer");
3833
0
        pdev->color_model_stack = NULL;
3834
0
    }
3835
3836
    /* Start the context clean up */
3837
0
    if (ctx != NULL) {
3838
0
        pdf14_buf *buf, *next;
3839
0
        pdf14_group_color_t *procs, *prev_procs;
3840
3841
0
        if (ctx->mask_stack != NULL) {
3842
0
            pdf14_free_mask_stack(ctx, ctx->memory);
3843
0
        }
3844
3845
        /* Now the stack of buffers */
3846
0
        for (buf = ctx->stack; buf != NULL; buf = next) {
3847
0
            next = buf->saved;
3848
3849
0
            gs_free_object(ctx->memory, buf->transfer_fn, "pdf14_discard_trans_layer");
3850
0
            gs_free_object(ctx->memory, buf->matte, "pdf14_discard_trans_layer");
3851
0
            gs_free_object(ctx->memory, buf->data, "pdf14_discard_trans_layer");
3852
0
            gs_free_object(ctx->memory, buf->backdrop, "pdf14_discard_trans_layer");
3853
            /* During the soft mask push, the mask_stack was copied (not moved) from
3854
               the ctx to the tos mask_stack. We are done with this now so it is safe
3855
               to free this one object */
3856
0
            gs_free_object(ctx->memory, buf->mask_stack, "pdf14_discard_trans_layer");
3857
0
            for (procs = buf->group_color_info; procs != NULL; procs = prev_procs) {
3858
0
                prev_procs = procs->previous;
3859
0
                gs_free_object(ctx->memory, procs, "pdf14_discard_trans_layer");
3860
0
            }
3861
0
            gs_free_object(ctx->memory, buf, "pdf14_discard_trans_layer");
3862
0
        }
3863
        /* Finally the context itself */
3864
0
        gs_free_object(ctx->memory, ctx, "pdf14_discard_trans_layer");
3865
0
        pdev->ctx = NULL;
3866
0
    }
3867
0
    return 0;
3868
0
}
3869
3870
static  int
3871
pdf14_output_page(gx_device * dev, int num_copies, int flush)
3872
0
{
3873
0
    pdf14_device * pdev = (pdf14_device *)dev;
3874
3875
0
    if (pdev->target != NULL)
3876
0
        return (*dev_proc(pdev->target, output_page)) (pdev->target, num_copies, flush);
3877
0
    return 0;
3878
0
}
3879
3880
15.8M
#define COPY_PARAM(p) dev->p = target->p
3881
9.92M
#define COPY_ARRAY_PARAM(p) memcpy(dev->p, target->p, sizeof(dev->p))
3882
3883
static void
3884
copy_tag_setup(gx_device *dev, const gx_device *target)
3885
1.98M
{
3886
1.98M
    bool deep = device_is_deep(target);
3887
1.98M
    int had_tags = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3888
1.98M
    int has_tags = (target->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3889
1.98M
    COPY_PARAM(graphics_type_tag);
3890
1.98M
    if (had_tags && !has_tags)
3891
0
    {
3892
        /* We have just removed a tags plane. Adjust num_components and depth accordingly. */
3893
0
        dev->color_info.num_components--;
3894
0
        dev->color_info.depth -= deep ? 16 : 8;
3895
0
    }
3896
1.98M
    else if (!had_tags && has_tags)
3897
0
    {
3898
        /* We have just added a tags plane. Adjust num_components and depth accordingly. */
3899
0
        dev->color_info.num_components++;
3900
0
        dev->color_info.depth += deep ? 16 : 8;
3901
0
    }
3902
1.98M
}
3903
3904
/*
3905
 * Copy device parameters back from a target.  This copies all standard
3906
 * parameters related to page size and resolution, but not any of the
3907
 * color-related parameters, as the pdf14 device retains its own color
3908
 * handling. This routine is parallel to gx_device_copy_params().
3909
 * Note that it DOES copy the devn_params since these are required to
3910
 * keep agreement with colorant name->number mapping, and don't change
3911
 * with the pdf14 color handling.
3912
 */
3913
static  int
3914
gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target)
3915
1.98M
{
3916
1.98M
    cmm_dev_profile_t *profile_targ;
3917
1.98M
    cmm_dev_profile_t *profile_dev14;
3918
1.98M
    pdf14_device *pdev = (pdf14_device*) dev;
3919
1.98M
    cmm_profile_t *blend_profile = NULL;
3920
1.98M
    int k;
3921
3922
1.98M
    COPY_PARAM(width);
3923
1.98M
    COPY_PARAM(height);
3924
1.98M
    COPY_ARRAY_PARAM(MediaSize);
3925
1.98M
    COPY_ARRAY_PARAM(ImagingBBox);
3926
1.98M
    COPY_PARAM(ImagingBBox_set);
3927
1.98M
    COPY_ARRAY_PARAM(HWResolution);
3928
1.98M
    COPY_ARRAY_PARAM(Margins);
3929
1.98M
    COPY_ARRAY_PARAM(HWMargins);
3930
1.98M
    COPY_PARAM(PageCount);
3931
1.98M
    COPY_PARAM(MaxPatternBitmap);
3932
3933
3934
    /* Supposedly this function isn't supposed to change the color setup of dev.
3935
     * BUT... if we change the tags value, we have to change the color setup to
3936
     * keep it valid. This is because num_components and depth include tags. */
3937
1.98M
    copy_tag_setup(dev, target);
3938
1.98M
    COPY_PARAM(interpolate_control);
3939
1.98M
    COPY_PARAM(non_strict_bounds);
3940
1.98M
    memcpy(&(dev->space_params), &(target->space_params), sizeof(gdev_space_params));
3941
3942
1.98M
    if (dev->icc_struct == NULL) {
3943
1.98M
        dev->icc_struct = gsicc_new_device_profile_array(dev);
3944
1.98M
        if (dev->icc_struct == NULL)
3945
0
            return_error(gs_error_VMerror);
3946
1.98M
        profile_dev14 = dev->icc_struct;
3947
1.98M
        dev_proc((gx_device *) target, get_profile)((gx_device *) target,
3948
1.98M
                                          &(profile_targ));
3949
3950
9.92M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
3951
7.94M
            if (profile_targ->device_profile[k] != NULL) {
3952
1.98M
                gsicc_adjust_profile_rc(profile_targ->device_profile[k], 1, "gs_pdf14_device_copy_params");
3953
1.98M
            }
3954
7.94M
            if (profile_dev14->device_profile[k] != NULL) {
3955
0
                gsicc_adjust_profile_rc(profile_dev14->device_profile[k], -1, "gs_pdf14_device_copy_params");
3956
0
            }
3957
7.94M
            profile_dev14->device_profile[k] = profile_targ->device_profile[k];
3958
7.94M
            profile_dev14->rendercond[k] = profile_targ->rendercond[k];
3959
7.94M
        }
3960
3961
1.98M
        dev->icc_struct->devicegraytok = profile_targ->devicegraytok;
3962
1.98M
        dev->icc_struct->graydetection = profile_targ->graydetection;
3963
1.98M
        dev->icc_struct->pageneutralcolor = profile_targ->pageneutralcolor;
3964
1.98M
        dev->icc_struct->supports_devn = profile_targ->supports_devn;
3965
1.98M
        dev->icc_struct->usefastcolor = profile_targ->usefastcolor;
3966
1.98M
        dev->icc_struct->blacktext = profile_targ->blacktext;
3967
1.98M
        dev->icc_struct->blackvector = profile_targ->blackvector;
3968
1.98M
        dev->icc_struct->blackthresholdL = profile_targ->blackthresholdL;
3969
1.98M
        dev->icc_struct->blackthresholdC = profile_targ->blackthresholdC;
3970
3971
1.98M
        switch (pdev->blend_cs_state) {
3972
1.98M
            case PDF14_BLEND_CS_UNSPECIFIED:
3973
1.98M
            case PDF14_BLEND_CS_TARGET_CIELAB:
3974
                /* PDF14_BLEND_CS_TARGET_CIELAB handled
3975
                   during the device push, when we have
3976
                   access to the pgs */
3977
1.98M
                break;
3978
0
            case PDF14_BLEND_CS_OUTPUTINTENT:
3979
0
                blend_profile = profile_targ->oi_profile;
3980
0
                break;
3981
0
            case PDF14_BLEND_CS_SPECIFIED:
3982
0
                blend_profile = profile_targ->blend_profile;
3983
0
                break;
3984
0
            default:
3985
0
                break;
3986
1.98M
        }
3987
3988
1.98M
        if (blend_profile != NULL) {
3989
            /* Set the device profile to the blend profile. Note only default profile is set */
3990
0
            gsicc_adjust_profile_rc(blend_profile, 1, "gs_pdf14_device_copy_params");
3991
0
            gsicc_adjust_profile_rc(profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "gs_pdf14_device_copy_params");
3992
0
            profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE] = blend_profile;
3993
0
        }
3994
3995
1.98M
        profile_dev14->overprint_control = profile_targ->overprint_control;
3996
1.98M
    }
3997
1.98M
#undef COPY_ARRAY_PARAM
3998
1.98M
#undef COPY_PARAM
3999
1.98M
    return 0;
4000
1.98M
}
4001
4002
/*
4003
 * This is a forwarding version of the put_params device proc.  It is only
4004
 * used when the PDF 1.4 compositor devices are closed.  The routine will
4005
 * check if the target device has closed and, if so, close itself.  The routine
4006
 * also sync the device parameters.
4007
 */
4008
static  int
4009
pdf14_forward_put_params(gx_device * dev, gs_param_list * plist)
4010
0
{
4011
0
    pdf14_device * pdev = (pdf14_device *)dev;
4012
0
    gx_device * tdev = pdev->target;
4013
0
    bool was_open = tdev->is_open;
4014
0
    int code = 0;
4015
4016
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
4017
0
        gx_device_decache_colors(dev);
4018
0
        if (!tdev->is_open) {
4019
0
            code = gs_closedevice(dev);
4020
0
            if (code == 0)
4021
0
                code = was_open ? 1 : 0;   /* target device closed */
4022
0
        }
4023
0
        gx_device_copy_params(dev, tdev);
4024
0
    }
4025
0
    return code;
4026
0
}
4027
4028
/* Function prototypes */
4029
int put_param_pdf14_spot_names(gx_device * pdev,
4030
                gs_separations * pseparations, gs_param_list * plist);
4031
146k
#define PDF14NumSpotColorsParamName "PDF14NumSpotColors"
4032
4033
/*
4034
 * The put_params method for the PDF 1.4 device will check if the
4035
 * target device has closed and, if so, close itself.  Note:  This routine is
4036
 * currently being used by both the pdf14_clist_device and the pdf_device.
4037
 * Please make sure that any changes are either applicable to both devices
4038
 * or clone the routine for each device.
4039
 */
4040
static  int
4041
pdf14_put_params(gx_device * dev, gs_param_list * plist)
4042
0
{
4043
0
    pdf14_device * pdev = (pdf14_device *)dev;
4044
0
    gx_device * tdev = pdev->target;
4045
0
    bool was_open = tdev->is_open;
4046
0
    int code = 0, code2 = 0;
4047
4048
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
4049
0
        gx_device_decache_colors(dev);
4050
0
        if (!tdev->is_open) {
4051
0
            code = gs_closedevice(dev);
4052
0
            if (code == 0)
4053
0
                code = was_open ? 1 : 0;   /* target device closed */
4054
0
        }
4055
0
        code2 = gs_pdf14_device_copy_params(dev, tdev);
4056
0
        if (code2 < 0)
4057
0
            code = code2;
4058
0
    }
4059
0
    return code;
4060
0
}
4061
4062
/*
4063
 * Copy marking related parameters into the PDF 1.4 device structure for use
4064
 * by pdf14_fill_rectangle.
4065
 */
4066
static  void
4067
pdf14_set_marking_params(gx_device *dev, const gs_gstate *pgs)
4068
67.6M
{
4069
67.6M
    pdf14_device * pdev = (pdf14_device *)dev;
4070
4071
67.6M
    if (pgs->alphaisshape) {
4072
1.53M
        pdev->opacity = 1.0;
4073
1.53M
        if (pgs->is_fill_color) {
4074
1.46M
            pdev->shape = pgs->fillconstantalpha;
4075
1.46M
        } else {
4076
62.2k
            pdev->shape = pgs->strokeconstantalpha;
4077
62.2k
        }
4078
66.0M
    } else {
4079
66.0M
        pdev->shape = 1.0;
4080
66.0M
        if (pgs->is_fill_color) {
4081
28.3M
            pdev->opacity = pgs->fillconstantalpha;
4082
37.7M
        } else {
4083
37.7M
            pdev->opacity = pgs->strokeconstantalpha;
4084
37.7M
        }
4085
66.0M
    }
4086
67.6M
    pdev->alpha = pdev->opacity * pdev->shape;
4087
67.6M
    pdev->blend_mode = pgs->blend_mode;
4088
67.6M
    if (pdev->icc_struct->overprint_control != gs_overprint_control_disable) {
4089
67.6M
        pdev->overprint = pgs->overprint;
4090
67.6M
        pdev->stroke_overprint = pgs->stroke_overprint;
4091
67.6M
    } else {
4092
0
        pdev->overprint = false;
4093
0
        pdev->stroke_overprint = false;
4094
0
    }
4095
4096
67.6M
    pdev->fillconstantalpha = pgs->fillconstantalpha;
4097
67.6M
    pdev->strokeconstantalpha = pgs->strokeconstantalpha;
4098
4099
67.6M
    if (pgs->is_fill_color)
4100
29.7M
        pdev->op_state = PDF14_OP_STATE_FILL;
4101
37.8M
    else
4102
37.8M
        pdev->op_state = PDF14_OP_STATE_STROKE;
4103
4104
67.6M
    if_debug6m('v', dev->memory,
4105
67.6M
               "[v]set_marking_params, opacity = %g, shape = %g, bm = %d, op = %d, eop = %d seop = %d\n",
4106
67.6M
               pdev->opacity, pdev->shape, pgs->blend_mode, pgs->overprint, pdev->effective_overprint_mode,
4107
67.6M
               pdev->stroke_effective_op_mode);
4108
67.6M
}
4109
4110
static  void
4111
update_lop_for_pdf14(gs_gstate *pgs, const gx_drawing_color *pdcolor)
4112
47.7M
{
4113
47.7M
    bool hastrans = false;
4114
4115
    /* We'd really rather not have to set the pdf14 bit in the lop, as this
4116
     * makes other operations much slower. We have no option however, if the
4117
     * current colour involves transparency, or if it's anything other than
4118
     * a completely solid (or transparent) operation in the normal blend mode.
4119
     */
4120
47.7M
    if (pdcolor != NULL)
4121
47.7M
    {
4122
47.7M
        if (gx_dc_is_pattern1_color(pdcolor) &&
4123
851k
            gx_pattern1_get_transptr(pdcolor) != NULL) {
4124
19.3k
            hastrans = true;
4125
47.7M
        } else if (gx_dc_is_pattern2_color(pdcolor)) {
4126
            /* FIXME: Here we assume that ALL type 2 patterns are
4127
             * transparent - this test could be better. */
4128
73.3k
            hastrans = true;
4129
73.3k
        }
4130
47.7M
    }
4131
    /* The only idempotent blend modes are Normal, Darken and Lighten.
4132
       This appears to be the only place where this test is done so
4133
       not adding a is_idempotent method */
4134
47.7M
    if ((pgs->blend_mode != BLEND_MODE_Normal &&
4135
196k
        pgs->blend_mode != BLEND_MODE_Darken &&
4136
192k
        pgs->blend_mode != BLEND_MODE_Lighten) ||
4137
47.5M
        (pgs->fillconstantalpha != 1.0) ||
4138
46.5M
        (pgs->strokeconstantalpha != 1.0) ||
4139
46.5M
        (hastrans))
4140
1.35M
    {
4141
        /*
4142
         * The blend operations are not idempotent.  Force non-idempotent
4143
         * filling and stroking operations.
4144
         */
4145
1.35M
        pgs->log_op |= lop_pdf14;
4146
1.35M
    }
4147
47.7M
}
4148
4149
static int
4150
push_shfill_group(pdf14_clist_device *pdev,
4151
                  gs_gstate *pgs,
4152
                  gs_fixed_rect *box)
4153
2.69k
{
4154
2.69k
    gs_transparency_group_params_t params = { 0 };
4155
2.69k
    int code;
4156
2.69k
    gs_rect cb;
4157
2.69k
    gs_gstate fudged_pgs = *pgs;
4158
4159
2.69k
    params.shade_group = true;
4160
4161
    /* gs_begin_transparency_group takes a bbox that it then
4162
     * transforms by ctm. Our bbox has already been transformed,
4163
     * so clear out the ctm. */
4164
2.69k
    fudged_pgs.ctm.xx = 1.0;
4165
2.69k
    fudged_pgs.ctm.xy = 0;
4166
2.69k
    fudged_pgs.ctm.yx = 0;
4167
2.69k
    fudged_pgs.ctm.yy = 1.0;
4168
2.69k
    fudged_pgs.ctm.tx = 0;
4169
2.69k
    fudged_pgs.ctm.ty = 0;
4170
2.69k
    cb.p.x = fixed2int_pixround(box->p.x);
4171
2.69k
    cb.p.y = fixed2int_pixround(box->p.y);
4172
2.69k
    cb.q.x = fixed2int_pixround(box->q.x);
4173
2.69k
    cb.q.y = fixed2int_pixround(box->q.y);
4174
4175
2.69k
    params.Isolated = false;
4176
2.69k
    params.Knockout = true;
4177
2.69k
    params.page_group = false;
4178
2.69k
    params.group_opacity = fudged_pgs.fillconstantalpha;
4179
2.69k
    params.group_shape = 1.0;
4180
2.69k
    code = gs_begin_transparency_group(&fudged_pgs, &params, &cb, PDF14_BEGIN_TRANS_GROUP);
4181
4182
    /* We have the group handle the blendmode and the opacity,
4183
     * and continue with the existing graphics state reset
4184
     * to normal, opaque operation. We could do it the other
4185
     * way around, but this way means that if we push a knockout
4186
     * group for a stroke, and then the code calls back into
4187
     * the fill operation as part of doing the stroking, we don't
4188
     * push another one. */
4189
2.69k
    gs_setblendmode(pgs, BLEND_MODE_Normal);
4190
2.69k
    gs_setfillconstantalpha(pgs, 1.0);
4191
2.69k
    gs_setstrokeconstantalpha(pgs, 1.0);
4192
2.69k
    if (pdev) {
4193
2.69k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
4194
2.69k
        if (code < 0)
4195
0
            return code;
4196
2.69k
    }
4197
4198
2.69k
    return code;
4199
2.69k
}
4200
4201
static int
4202
pop_shfill_group(gs_gstate *pgs)
4203
2.69k
{
4204
2.69k
     return gs_end_transparency_group(pgs);
4205
2.69k
}
4206
4207
static int
4208
pdf14_fill_path(gx_device *dev, const gs_gstate *pgs,
4209
                           gx_path *ppath, const gx_fill_params *params,
4210
                           const gx_drawing_color *pdcolor,
4211
                           const gx_clip_path *pcpath)
4212
38.2M
{
4213
38.2M
    gs_gstate new_pgs = *pgs;
4214
38.2M
    int code = 0;
4215
38.2M
    gs_pattern2_instance_t *pinst = NULL;
4216
38.2M
    int push_group = 0;
4217
4218
38.2M
    code = pdf14_initialize_ctx(dev, pgs);
4219
38.2M
    if (code < 0)
4220
0
        return code;
4221
4222
38.2M
    if (pdcolor == NULL)
4223
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4224
38.2M
    ((pdf14_device *)dev)->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_STROKE;
4225
38.2M
    if (gx_dc_is_pattern1_color(pdcolor)){
4226
959k
        if( gx_pattern1_get_transptr(pdcolor) != NULL ||
4227
910k
            gx_pattern1_clist_has_trans(pdcolor) ){
4228
            /* In this case, we need to push a transparency group
4229
               and tile the pattern color, which is stored in
4230
               a pdf14 device buffer in the ctile object memember
4231
               variable ttrans */
4232
#if RAW_DUMP
4233
            /* Since we do not get a put_image to view what
4234
               we have do it now */
4235
            if (gx_pattern1_get_transptr(pdcolor) != NULL) {
4236
                const pdf14_device * ppatdev14 = (const pdf14_device *)
4237
                                pdcolor->colors.pattern.p_tile->ttrans->pdev14;
4238
                if (ppatdev14 != NULL) {  /* can occur during clist reading */
4239
                    byte *buf_ptr = ppatdev14->ctx->stack->data  +
4240
                        ppatdev14->ctx->stack->rect.p.y *
4241
                        ppatdev14->ctx->stack->rowstride +
4242
                        ppatdev14->ctx->stack->rect.p.x;
4243
                    dump_raw_buffer(ppatdev14->ctx->memory,
4244
                                    (ppatdev14->ctx->stack->rect.q.y -
4245
                                     ppatdev14->ctx->stack->rect.p.y),
4246
                                    (ppatdev14->ctx->stack->rect.q.x -
4247
                                     ppatdev14->ctx->stack->rect.p.x),
4248
                                    ppatdev14->ctx->stack->n_planes,
4249
                                    ppatdev14->ctx->stack->planestride,
4250
                                    ppatdev14->ctx->stack->rowstride,
4251
                                    "Pattern_Fill", buf_ptr,
4252
                                    ppatdev14->ctx->stack->deep);
4253
                    global_index++;
4254
                } else {
4255
                     gx_pattern_trans_t *patt_trans =
4256
                                        pdcolor->colors.pattern.p_tile->ttrans;
4257
                     dump_raw_buffer(patt_trans->mem,
4258
                                     patt_trans->rect.q.y-patt_trans->rect.p.y,
4259
                                     patt_trans->rect.q.x-patt_trans->rect.p.x,
4260
                                     patt_trans->n_chan,
4261
                                     patt_trans->planestride, patt_trans->rowstride,
4262
                                     "Pattern_Fill_clist",
4263
                                     patt_trans->transbytes +
4264
                                         patt_trans->rect.p.y * patt_trans->rowstride +
4265
                                         (patt_trans->rect.p.x<<patt_trans->deep),
4266
                                     patt_trans->deep);
4267
                    global_index++;
4268
                }
4269
            }
4270
#endif
4271
139k
            pdf14_set_marking_params(dev, &new_pgs);
4272
139k
            code = pdf14_tile_pattern_fill(dev, &new_pgs, ppath,
4273
139k
                params, pdcolor, pcpath);
4274
139k
            new_pgs.trans_device = NULL;
4275
139k
            new_pgs.has_transparency = false;
4276
139k
            return code;
4277
139k
        }
4278
959k
    }
4279
38.0M
    if (gx_dc_is_pattern2_color(pdcolor) ||
4280
38.0M
        pdcolor->type == &gx_dc_devn_masked) {
4281
        /* Non-idempotent blends require a transparency
4282
         * group to be pushed because shadings might
4283
         * paint several pixels twice. */
4284
65
        push_group = pgs->fillconstantalpha != 1.0 ||
4285
65
               !blend_is_idempotent(gs_currentblendmode(pgs));
4286
65
        pinst =
4287
65
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
4288
65
        pinst->saved->has_transparency = true;
4289
        /* The transparency color space operations are driven
4290
           by the pdf14 clist writer device.  */
4291
65
        pinst->saved->trans_device = dev;
4292
65
    }
4293
38.0M
    if (push_group) {
4294
0
        gs_fixed_rect box;
4295
0
        if (pcpath)
4296
0
            gx_cpath_outer_box(pcpath, &box);
4297
0
        else
4298
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4299
0
        if (ppath) {
4300
0
            gs_fixed_rect path_box;
4301
4302
0
            gx_path_bbox(ppath, &path_box);
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
        code = push_shfill_group(NULL, &new_pgs, &box);
4314
0
    } else
4315
38.0M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4316
38.0M
    pdf14_set_marking_params(dev, &new_pgs);
4317
38.0M
    if (code >= 0) {
4318
38.0M
        new_pgs.trans_device = dev;
4319
38.0M
        new_pgs.has_transparency = true;
4320
        /* ppath can permissibly be NULL here, if we want to have a
4321
         * shading or a pattern fill the clipping path. This upsets
4322
         * coverity, which is not smart enough to realise that the
4323
         * validity of a NULL ppath depends on the type of pdcolor.
4324
         * We'll mark it as a false positive. */
4325
38.0M
        code = gx_default_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4326
38.0M
        new_pgs.trans_device = NULL;
4327
38.0M
        new_pgs.has_transparency = false;
4328
38.0M
    }
4329
38.0M
    if (code >= 0 && push_group) {
4330
0
        code = pop_shfill_group(&new_pgs);
4331
0
        pdf14_set_marking_params(dev, pgs);
4332
0
    }
4333
38.0M
    if (pinst != NULL){
4334
65
        pinst->saved->trans_device = NULL;
4335
65
    }
4336
38.0M
    return code;
4337
38.2M
}
4338
4339
static  int
4340
pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs,
4341
                             gx_path *ppath, const gx_stroke_params *params,
4342
                             const gx_drawing_color *pdcolor,
4343
                             const gx_clip_path *pcpath)
4344
5.63M
{
4345
5.63M
    gs_gstate new_pgs = *pgs;
4346
5.63M
    int push_group = 0;
4347
5.63M
    int code = 0;
4348
4349
5.63M
    if (pdcolor == NULL)
4350
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4351
4352
5.63M
    code = pdf14_initialize_ctx(dev, pgs);
4353
5.63M
    if (code < 0)
4354
0
        return code;
4355
4356
5.63M
    if (gx_dc_is_pattern2_color(pdcolor)) {
4357
        /* Non-idempotent blends require a transparency
4358
         * group to be pushed because shadings might
4359
         * paint several pixels twice. */
4360
0
        push_group = pgs->strokeconstantalpha != 1.0 ||
4361
0
               !blend_is_idempotent(gs_currentblendmode(pgs));
4362
0
    }
4363
5.63M
    if (push_group) {
4364
0
        gs_fixed_rect box;
4365
0
        if (pcpath)
4366
0
            gx_cpath_outer_box(pcpath, &box);
4367
0
        else
4368
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4369
4370
        /* For fill_path, we accept ppath == NULL to mean
4371
         * fill the entire clipping region. That makes no
4372
         * sense for stroke_path, hence ppath is always non
4373
         * NULL here. */
4374
0
        {
4375
0
            gs_fixed_rect path_box;
4376
0
            gs_fixed_point expansion;
4377
4378
0
            gx_path_bbox(ppath, &path_box);
4379
            /* Expand the path bounding box by the scaled line width. */
4380
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
4381
                /* The expansion is so large it caused a limitcheck. */
4382
0
                path_box.p.x = path_box.p.y = min_fixed;
4383
0
                path_box.q.x = path_box.q.y = max_fixed;
4384
0
            } else {
4385
0
                expansion.x += pgs->fill_adjust.x;
4386
0
                expansion.y += pgs->fill_adjust.y;
4387
                /*
4388
                 * It's theoretically possible for the following computations to
4389
                 * overflow, so we need to check for this.
4390
                 */
4391
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
4392
0
                                path_box.p.x - expansion.x);
4393
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
4394
0
                                path_box.p.y - expansion.y);
4395
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
4396
0
                                path_box.q.x + expansion.x);
4397
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
4398
0
                                path_box.q.y + expansion.y);
4399
0
            }
4400
0
            if (box.p.x < path_box.p.x)
4401
0
                box.p.x = path_box.p.x;
4402
0
            if (box.p.y < path_box.p.y)
4403
0
                box.p.y = path_box.p.y;
4404
0
            if (box.q.x > path_box.q.x)
4405
0
                box.q.x = path_box.q.x;
4406
0
            if (box.q.y > path_box.q.y)
4407
0
                box.q.y = path_box.q.y;
4408
0
        }
4409
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4410
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
4411
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4412
0
    } else
4413
5.63M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4414
5.63M
    pdf14_set_marking_params(dev, &new_pgs);
4415
5.63M
    if (code >= 0) {
4416
5.63M
        PDF14_OP_FS_STATE save_op_state = ((pdf14_device *)dev)->op_state;
4417
4418
5.63M
        ((pdf14_device*)dev)->op_state = PDF14_OP_STATE_STROKE;
4419
5.63M
        code = gx_default_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4420
5.63M
        ((pdf14_device*)dev)->op_state = save_op_state;
4421
5.63M
    }
4422
5.63M
    if (code >= 0 && push_group) {
4423
0
        code = pop_shfill_group(&new_pgs);
4424
0
        pdf14_set_marking_params(dev, pgs);
4425
0
    }
4426
4427
5.63M
    return code;
4428
5.63M
}
4429
4430
/* Pull out steps of transparency updates for fill/stroke
4431
   so that they can be invoked elsewhere (e.g.
4432
   when the abuf device is handling the stroke/fill */
4433
4434
/* Set-up prior to fill operation in fill-stroke */
4435
static int
4436
pdf14_fill_stroke_prefill(gx_device* dev, gs_gstate* pgs, gx_path* ppath,
4437
    const gx_clip_path* pcpath, float fill_alpha, float stroke_alpha,
4438
    gs_blend_mode_t blend_mode, bool* op_ca_eq_CA, bool* path_empty, gs_log2_scale_point path_log2scale)
4439
92.1k
{
4440
92.1k
    int code = 0;
4441
92.1k
    gs_transparency_group_params_t params = { 0 };
4442
92.1k
    gs_fixed_rect clip_bbox;
4443
92.1k
    gs_rect bbox, group_stroke_box;
4444
92.1k
    gs_fixed_rect path_bbox;
4445
92.1k
    int expansion_code;
4446
92.1k
    gs_fixed_point expansion;
4447
92.1k
    pdf14_device* p14dev = (pdf14_device*)dev;
4448
4449
92.1k
    *path_empty = false;
4450
4451
92.1k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
4452
92.0k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
4453
55
        return 0;
4454
4455
    /* The clip box returned here is scaled up by path_log2scale, so we need
4456
     * to scale down by this later. */
4457
92.0k
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
4458
92.0k
    if (code < 0 && code != gs_error_unknownerror)
4459
0
        return code;
4460
4461
92.0k
    if (code == gs_error_unknownerror) {
4462
        /* didn't get clip box from gx_curr_fixed_bbox */
4463
        /* This is NOT scaled by path_log2scale, so allow for the fact we'll be
4464
         * scaling down by this in a moment. */
4465
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
4466
0
        clip_bbox.q.x = int2fixed(dev->width) << path_log2scale.x;
4467
0
        clip_bbox.q.y = int2fixed(dev->height) << path_log2scale.y;
4468
0
    }
4469
    /* pcpath->outer_box is scaled by path_log2scale too. */
4470
92.0k
    if (pcpath)
4471
92.0k
        rect_intersect(clip_bbox, pcpath->outer_box);
4472
4473
    /* expand the ppath using stroke expansion rule, then intersect it */
4474
92.0k
    code = gx_path_bbox(ppath, &path_bbox);
4475
4476
    /* If we are coming from the abuf device, the path has been scaled
4477
       by a factor (see alpha_buffer_init).  Undo the scaling here so
4478
       on the path_bbox so that we get the proper bounding box for our group. */
4479
92.0k
    if (path_log2scale.x != 0 || path_log2scale.y != 0) {
4480
0
        path_bbox.p.x = path_bbox.p.x >> path_log2scale.x;
4481
0
        path_bbox.q.x = path_bbox.q.x >> path_log2scale.x;
4482
0
        path_bbox.p.y = path_bbox.p.y >> path_log2scale.y;
4483
0
        path_bbox.q.y = path_bbox.q.y >> path_log2scale.y;
4484
0
        clip_bbox.p.x = clip_bbox.p.x >> path_log2scale.x;
4485
0
        clip_bbox.q.x = clip_bbox.q.x >> path_log2scale.x;
4486
0
        clip_bbox.p.y = clip_bbox.p.y >> path_log2scale.y;
4487
0
        clip_bbox.q.y = clip_bbox.q.y >> path_log2scale.y;
4488
0
    }
4489
4490
92.0k
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0) {
4491
60.7k
        *path_empty = true;
4492
60.7k
        return 0; /* ignore empty path -- could try to send back a positive code for this but
4493
                     there are simply too many return cases that I can't account for. */
4494
60.7k
    }
4495
31.3k
    if (code < 0)
4496
0
        return code;
4497
4498
31.3k
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
4499
31.3k
    if (expansion_code >= 0) {
4500
28.4k
        path_bbox.p.x -= expansion.x;
4501
28.4k
        path_bbox.p.y -= expansion.y;
4502
28.4k
        path_bbox.q.x += expansion.x;
4503
28.4k
        path_bbox.q.y += expansion.y;
4504
28.4k
    }
4505
31.3k
    rect_intersect(path_bbox, clip_bbox);
4506
31.3k
    bbox.p.x = fixed2float(path_bbox.p.x);
4507
31.3k
    bbox.p.y = fixed2float(path_bbox.p.y);
4508
31.3k
    bbox.q.x = fixed2float(path_bbox.q.x);
4509
31.3k
    bbox.q.y = fixed2float(path_bbox.q.y);
4510
4511
31.3k
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
4512
31.3k
    if (code < 0)
4513
7
        return code;
4514
4515
31.3k
    if (p14dev->overprint != pgs->overprint || p14dev->stroke_overprint != pgs->stroke_overprint) {
4516
0
        p14dev->overprint = pgs->overprint;
4517
0
        p14dev->stroke_overprint = pgs->stroke_overprint;
4518
0
    }
4519
4520
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
4521
31.3k
    if (fill_alpha == stroke_alpha &&
4522
10.4k
        p14dev->overprint && p14dev->stroke_overprint &&
4523
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
4524
4525
        /* Push a non-isolated non-knockout group with alpha = 1.0 and
4526
           compatible overprint mode.  Group will be composited with
4527
           original alpha and blend mode */
4528
0
        *op_ca_eq_CA = true;
4529
0
        params.Isolated = false;
4530
0
        params.group_color_type = UNKNOWN;
4531
0
        params.Knockout = false;
4532
0
        params.page_group = false;
4533
0
        params.group_opacity = 1.0;
4534
0
        params.group_shape = fill_alpha;
4535
4536
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
4537
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4538
0
        if (code < 0)
4539
0
            return code;
4540
4541
        /* Change fill alpha to 1.0 and blend mode to compatible overprint for actual drawing */
4542
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
4543
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4544
4545
31.3k
    } else {
4546
        /* Push a non-isolated knockout group. Do not change the alpha or
4547
            blend modes. Note: we need to draw those that have alpha = 0 */
4548
31.3k
        *op_ca_eq_CA = false;
4549
31.3k
        params.Isolated = false;
4550
31.3k
        params.group_color_type = UNKNOWN;
4551
31.3k
        params.Knockout = true;
4552
31.3k
        params.page_group = false;
4553
31.3k
        params.group_shape = 1.0;
4554
31.3k
        params.group_opacity = 1.0;
4555
4556
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
4557
31.3k
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
4558
31.3k
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4559
31.3k
        if (code < 0)
4560
0
            return code;
4561
4562
        /* restore blend mode for actual drawing in the group */
4563
31.3k
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4564
4565
        /* If we are in an overprint situation, set the blend mode to compatible
4566
            overprint */
4567
31.3k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4568
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4569
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4570
31.3k
    }
4571
31.3k
    p14dev->op_state = PDF14_OP_STATE_FILL;
4572
31.3k
    return code;
4573
31.3k
}
4574
4575
/* Set-up prior to stroke operation in fill-stroke */
4576
static void
4577
pdf14_fill_stroke_prestroke(gx_device* dev, gs_gstate* pgs, float stroke_alpha,
4578
    gs_blend_mode_t blend_mode, bool op_ca_eq_CA)
4579
31.3k
{
4580
31.3k
    pdf14_device* p14dev = (pdf14_device*)dev;
4581
4582
31.3k
    if (op_ca_eq_CA) {
4583
55
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
4584
31.3k
    } else {
4585
31.3k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4586
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4587
0
            (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4588
4589
        /* Note that the stroke can end up doing fill methods */
4590
31.3k
        (void)gs_setfillconstantalpha(pgs, stroke_alpha);
4591
4592
31.3k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->stroke_overprint &&
4593
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4594
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4595
31.3k
    }
4596
31.3k
    p14dev->op_state = PDF14_OP_STATE_STROKE;
4597
31.3k
}
4598
4599
/* Cleanup after the stroke in fill-stroke  */
4600
static int
4601
pdf14_fill_stroke_poststroke(gx_device* dev, gs_gstate* pgs, float fill_alpha, bool op_ca_eq_CA)
4602
31.3k
{
4603
31.3k
    int code;
4604
4605
31.3k
    if (!op_ca_eq_CA) {
4606
        /* Bug 703324 we need to reset the fill constant alpha in the graphics
4607
          * state to the correct saved value. We also need to reset the 'opacity' member of the
4608
          * device, because some device methods (eg fill_masked_image) don't take a graphics
4609
          * state pointer as a parameter and so are unable to set the opacity value themselves.
4610
          * We therefore need to make sure it is set according to the current fill state.
4611
          */
4612
31.3k
        (void)gs_setfillconstantalpha(pgs, fill_alpha);
4613
31.3k
        code = gs_update_trans_marking_params(pgs);
4614
31.3k
        if (code < 0)
4615
0
            return code;
4616
31.3k
        pdf14_set_marking_params(dev, pgs);
4617
31.3k
    }
4618
4619
31.3k
    return 0;
4620
31.3k
}
4621
4622
/* cleanup in fill-stroke  */
4623
static int
4624
pdf14_fill_stroke_cleanup(gx_device* dev, gs_gstate* pgs, float fill_alpha, float stroke_alpha,
4625
    gs_blend_mode_t blend_mode, PDF14_OP_FS_STATE save_op_state)
4626
31.3k
{
4627
31.3k
    pdf14_device* p14dev = (pdf14_device*)dev;
4628
31.3k
    int code2;
4629
31.3k
    int code = 0;
4630
4631
    /* Restore the state */
4632
31.3k
    p14dev->op_state = save_op_state;
4633
31.3k
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4634
31.3k
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
4635
31.3k
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
4636
4637
31.3k
    code2 = gs_end_transparency_group(pgs);
4638
31.3k
    if (code2 < 0) {
4639
        /* At this point things have gone very wrong. We should just shut down */
4640
0
        code = gs_abort_pdf14trans_device(pgs);
4641
0
        return code2;
4642
0
    }
4643
31.3k
    return code;
4644
31.3k
}
4645
4646
static int
4647
pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
4648
    const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill,
4649
    const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke,
4650
    const gx_clip_path *pcpath)
4651
355k
{
4652
355k
    bool op_ca_eq_CA;
4653
355k
    bool path_empty;
4654
355k
    int code;
4655
355k
    float stroke_alpha = cpgs->strokeconstantalpha;
4656
355k
    float fill_alpha = cpgs->fillconstantalpha;
4657
355k
    gs_blend_mode_t blend_mode = cpgs->blend_mode;
4658
355k
    pdf14_device* p14dev = (pdf14_device*)dev;
4659
355k
    PDF14_OP_FS_STATE save_op_state = p14dev->op_state;
4660
355k
    gs_log2_scale_point path_log2scale;
4661
355k
    bool group_needed = true;
4662
355k
    gx_device* curr_pgs_dev = cpgs->device;
4663
4664
355k
    union {
4665
355k
        const gs_gstate* cpgs;
4666
355k
        gs_gstate* pgs;
4667
355k
    } const_breaker;
4668
355k
    gs_gstate* pgs;
4669
4670
    /* Break const just once, neatly */
4671
355k
    const_breaker.cpgs = cpgs;
4672
355k
    pgs = const_breaker.pgs;
4673
355k
    path_log2scale.x = 0;
4674
355k
    path_log2scale.y = 0;
4675
4676
355k
    code = pdf14_initialize_ctx(dev, pgs);
4677
355k
    if (code < 0)
4678
0
        return code;
4679
4680
    /* From looking at what AR is doing, it appears that if alpha is 1 and
4681
     * blend is normal we don't do a group push. Just do the stroke
4682
     * and the fill, even with overprint */
4683
355k
    if (stroke_alpha == 1 && fill_alpha == 1 && blend_mode == BLEND_MODE_Normal)
4684
263k
        group_needed = false;
4685
4686
355k
    if (group_needed) {
4687
92.1k
        pgs->device = dev; /* This is needed due to the gs_trans calls.  This method
4688
                              can be called on the clist writer side when dealing
4689
                              with the abuf/pdf14 interaction. Those calls have to
4690
                              go through the gs_trans API not the gx_trans or pdf14
4691
                              methods.  Perhaps these methods should have a different
4692
                              suffix, but they are static methods here in the pdf14
4693
                              file. */
4694
92.1k
        code = pdf14_fill_stroke_prefill(dev, pgs, ppath, pcpath, fill_alpha, stroke_alpha,
4695
92.1k
            blend_mode, &op_ca_eq_CA, &path_empty, path_log2scale);
4696
92.1k
        pgs->device = curr_pgs_dev;
4697
92.1k
        if (code < 0)
4698
7
            goto cleanup;
4699
92.0k
        if (path_empty)
4700
60.7k
            return 0;
4701
92.0k
    }
4702
4703
294k
    code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
4704
294k
    if (code < 0)
4705
0
        goto cleanup;
4706
4707
294k
    if (group_needed)
4708
31.3k
        pdf14_fill_stroke_prestroke(dev, pgs, stroke_alpha, blend_mode, op_ca_eq_CA);
4709
294k
    gs_swapcolors_quick(pgs);
4710
4711
4712
#if RAW_DUMP
4713
    /* Dump the current buffer to see what we have. */
4714
    dump_raw_buffer(p14dev->ctx->memory,
4715
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4716
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4717
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4718
        "BeforeStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4719
    global_index++;
4720
#endif
4721
4722
294k
    code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
4723
294k
    gs_swapcolors_quick(pgs);
4724
294k
    if (code < 0) {
4725
0
        goto cleanup;
4726
0
    }
4727
4728
#if RAW_DUMP
4729
    /* Dump the current buffer to see what we have. */
4730
    dump_raw_buffer(p14dev->ctx->memory,
4731
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4732
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4733
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4734
        "AfterStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4735
    global_index++;
4736
#endif
4737
294k
    if (group_needed)
4738
31.3k
        code = pdf14_fill_stroke_poststroke(dev, pgs, fill_alpha, op_ca_eq_CA);
4739
4740
294k
cleanup:
4741
294k
    if (group_needed) {
4742
31.3k
        int code1;
4743
31.3k
        pgs->device = dev; /* This is needed due to the gs_trans calls */
4744
31.3k
        code1 = pdf14_fill_stroke_cleanup(dev, pgs, fill_alpha, stroke_alpha, blend_mode,
4745
31.3k
            save_op_state);
4746
31.3k
        if (code1 < 0)
4747
0
            code = code1;
4748
31.3k
        pgs->device = curr_pgs_dev;
4749
31.3k
    }
4750
294k
    return code;
4751
294k
}
4752
4753
static int
4754
pdf14_copy_alpha(gx_device * dev, const byte * data, int data_x,
4755
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4756
                      gx_color_index color, int depth)
4757
0
{
4758
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4759
0
                                  color, NULL, depth, false);
4760
0
}
4761
4762
static int
4763
pdf14_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
4764
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4765
                      const gx_drawing_color *pdcolor, int depth)
4766
0
{
4767
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4768
0
                                  0, pdcolor, depth, true);
4769
0
}
4770
4771
static int
4772
do_pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
4773
                          int aa_raster, gx_bitmap_id id, int x, int y,
4774
                          int w, int h, gx_color_index color,
4775
                          const gx_device_color *pdc, int depth, bool devn)
4776
0
{
4777
0
    const byte *aa_row;
4778
0
    pdf14_device *pdev = (pdf14_device *)dev;
4779
0
    pdf14_buf *buf = pdev->ctx->stack;
4780
0
    int i, j, k;
4781
0
    byte *bline, *line, *dst_ptr, *back_ptr;
4782
0
    byte src[PDF14_MAX_PLANES];
4783
0
    byte dst[PDF14_MAX_PLANES] = { 0 };
4784
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4785
0
    bool additive = pdev->ctx->additive;
4786
0
    intptr_t rowstride = buf->rowstride;
4787
0
    intptr_t planestride = buf->planestride;
4788
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4789
0
    bool has_alpha_g = buf->has_alpha_g;
4790
0
    bool has_shape = buf->has_shape;
4791
0
    bool has_tags = buf->has_tags;
4792
0
    bool knockout = buf->knockout;
4793
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4794
0
        blend_mode == BLEND_MODE_Compatible ||
4795
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4796
0
    int num_chan = buf->n_chan;
4797
0
    int num_comp = num_chan - 1;
4798
0
    intptr_t shape_off = num_chan * planestride;
4799
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4800
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4801
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4802
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
4803
0
                                 pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4804
0
    gx_color_index comps;
4805
0
    byte shape = 0; /* Quiet compiler. */
4806
0
    byte src_alpha;
4807
0
    int alpha2_aa, alpha_aa, sx;
4808
0
    int alpha_aa_act;
4809
0
    int xoff;
4810
0
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
4811
0
    int shift = 8;
4812
0
    bool has_backdrop = buf->backdrop != NULL;
4813
4814
0
    if (buf->data == NULL)
4815
0
        return 0;
4816
0
    aa_row = data;
4817
0
    if (has_tags) {
4818
0
        if (devn)
4819
0
            curr_tag = pdc->tag;
4820
0
        else
4821
0
            curr_tag = (color >> (num_comp*8)) & 0xff;
4822
0
    }
4823
4824
0
    if (devn) {
4825
0
        if (additive) {
4826
0
            for (j = 0; j < num_comp; j++) {
4827
0
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
4828
0
            }
4829
0
        } else {
4830
0
            for (j = 0; j < num_comp; j++) {
4831
0
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
4832
0
            }
4833
0
        }
4834
0
    } else
4835
0
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
4836
0
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
4837
0
    if (has_shape)
4838
0
        shape = (byte)floor (255 * pdev->shape + 0.5);
4839
    /* Limit the area we write to the bounding rectangle for this buffer */
4840
0
    if (x < buf->rect.p.x) {
4841
0
        xoff = data_x + buf->rect.p.x - x;
4842
0
        w += x - buf->rect.p.x;
4843
0
        x = buf->rect.p.x;
4844
0
    } else {
4845
0
        xoff = data_x;
4846
0
    }
4847
0
    if (y < buf->rect.p.y) {
4848
0
      h += y - buf->rect.p.y;
4849
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4850
0
      y = buf->rect.p.y;
4851
0
    }
4852
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
4853
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
4854
    /* Update the dirty rectangle. */
4855
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
4856
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
4857
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
4858
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
4859
4860
    /* composite with backdrop only. */
4861
0
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4862
0
    if (knockout && has_backdrop)
4863
0
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4864
0
    else
4865
0
        bline = line;
4866
4867
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
4868
0
        back_ptr = bline;
4869
0
        dst_ptr = line;
4870
0
        sx = xoff;
4871
0
        for (i = 0; i < w; ++i, ++sx) {
4872
            /* Complement the components for subtractive color spaces */
4873
0
            if (additive) {
4874
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
4875
0
                    dst[k] = back_ptr[k * planestride];
4876
0
            } else { /* Complement the components for subtractive color spaces */
4877
0
                for (k = 0; k < num_comp; ++k)
4878
0
                    dst[k] = 255 - back_ptr[k * planestride];
4879
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
4880
0
            }
4881
            /* Get the aa alpha from the buffer */
4882
0
            switch(depth)
4883
0
            {
4884
0
            case 2:  /* map 0 - 3 to 0 - 255 */
4885
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
4886
0
                break;
4887
0
            case 4:
4888
0
                alpha2_aa = aa_row[sx >> 1];
4889
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
4890
0
                break;
4891
0
            case 8:
4892
0
                alpha_aa = aa_row[sx];
4893
0
                break;
4894
0
            default:
4895
0
                return_error(gs_error_rangecheck);
4896
0
            }
4897
0
            if (alpha_aa != 0) {  /* This does happen */
4898
0
                if (alpha_aa != 255) {
4899
                    /* We have an alpha value from aa */
4900
0
                    alpha_aa_act = alpha_aa;
4901
0
                    if (src_alpha != 255) {
4902
                        /* Need to combine it with the existing alpha */
4903
0
                        int tmp = src_alpha * alpha_aa_act + 0x80;
4904
0
                        alpha_aa_act = (tmp + (tmp >> 8)) >> 8;
4905
0
                    }
4906
                    /* Set our source alpha value appropriately */
4907
0
                    src[num_comp] = alpha_aa_act;
4908
0
                } else {
4909
                    /* We may have to reset this is it was changed as we
4910
                       moved across the row */
4911
0
                    src[num_comp] = src_alpha;
4912
0
                }
4913
0
                if (knockout) {
4914
0
                    if (buf->isolated) {
4915
0
                        art_pdf_knockoutisolated_group_8(dst, src, num_comp);
4916
0
                    } else {
4917
0
                        art_pdf_composite_knockout_8(dst, src, num_comp,
4918
0
                            blend_mode, pdev->blend_procs, pdev);
4919
0
                    }
4920
0
                } else {
4921
0
                    art_pdf_composite_pixel_alpha_8(dst, src, num_comp, blend_mode, num_comp,
4922
0
                                                    pdev->blend_procs, pdev);
4923
0
                }
4924
                /* Complement the results for subtractive color spaces */
4925
0
                if (additive) {
4926
0
                    for (k = 0; k < num_chan; ++k)
4927
0
                        dst_ptr[k * planestride] = dst[k];
4928
0
                } else {
4929
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
4930
0
                        for (k = 0, comps = drawn_comps; comps != 0;
4931
0
                                ++k, comps >>= 1) {
4932
0
                            if ((comps & 0x1) != 0) {
4933
0
                                dst_ptr[k * planestride] = 255 - dst[k];
4934
0
                            }
4935
0
                        }
4936
                        /* The alpha channel */
4937
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4938
0
                    } else {
4939
0
                        for (k = 0; k < num_comp; ++k)
4940
0
                            dst_ptr[k * planestride] = 255 - dst[k];
4941
                        /* The alpha channel */
4942
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4943
0
                    }
4944
0
                }
4945
0
                if (has_alpha_g) {
4946
0
                    int tmp = (255 - back_ptr[alpha_g_off]) * (255 - src[num_comp]) + 0x80;
4947
0
                    dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4948
0
                }
4949
0
                if (has_shape) {
4950
0
                    int tmp = (255 - back_ptr[shape_off]) * (255 - shape) + 0x80;
4951
0
                    dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4952
0
                }
4953
0
                if (has_tags) {
4954
                    /* If alpha is 100% then set to curr_tag, else or */
4955
                    /* other than Normal BM, we always OR */
4956
0
                    if (src[num_comp] == 255 && tag_blend) {
4957
0
                        dst_ptr[tag_off] = curr_tag;
4958
0
                    } else {
4959
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
4960
0
                    }
4961
0
                }
4962
0
            }
4963
0
            ++dst_ptr;
4964
0
            ++back_ptr;
4965
0
        }
4966
0
        line += rowstride;
4967
0
        bline += rowstride;
4968
0
    }
4969
0
    return 0;
4970
0
}
4971
4972
static int
4973
do_pdf14_copy_alpha_color_16(gx_device * dev, const byte * data, int data_x,
4974
                             int aa_raster, gx_bitmap_id id, int x, int y,
4975
                             int w, int h, gx_color_index color,
4976
                             const gx_device_color *pdc, int depth, bool devn)
4977
0
{
4978
0
    const byte *aa_row;
4979
0
    pdf14_device *pdev = (pdf14_device *)dev;
4980
0
    pdf14_buf *buf = pdev->ctx->stack;
4981
0
    int i, j, k;
4982
0
    byte *bline, *line;
4983
0
    uint16_t *dst_ptr, *back_ptr;
4984
0
    uint16_t src[PDF14_MAX_PLANES];
4985
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
4986
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4987
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4988
0
        blend_mode == BLEND_MODE_Compatible ||
4989
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4990
0
    bool additive = pdev->ctx->additive;
4991
0
    intptr_t rowstride = buf->rowstride;
4992
0
    int planestride = buf->planestride;
4993
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4994
0
    bool has_alpha_g = buf->has_alpha_g;
4995
0
    bool has_shape = buf->has_shape;
4996
0
    bool has_tags = buf->has_tags;
4997
0
    bool knockout = buf->knockout;
4998
0
    int num_chan = buf->n_chan;
4999
0
    int num_comp = num_chan - 1;
5000
0
    intptr_t shape_off = num_chan * planestride;
5001
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
5002
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
5003
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
5004
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
5005
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
5006
0
    gx_color_index comps;
5007
0
    uint16_t shape = 0; /* Quiet compiler. */
5008
0
    uint16_t src_alpha;
5009
0
    int alpha2_aa, alpha_aa, sx;
5010
0
    int alpha_aa_act;
5011
0
    int xoff;
5012
0
    bool has_backdrop = buf->backdrop != NULL;
5013
5014
0
    if (buf->data == NULL)
5015
0
        return 0;
5016
0
    aa_row = data;
5017
0
    if (has_tags) {
5018
0
        if (devn)
5019
0
            curr_tag = pdc->tag;
5020
0
        else
5021
0
            curr_tag = (color >> (num_comp*16)) & 0xff;
5022
0
    }
5023
5024
0
    if (devn) {
5025
0
        if (additive) {
5026
0
            for (j = 0; j < num_comp; j++) {
5027
0
                src[j] = pdc->colors.devn.values[j];
5028
0
            }
5029
0
        } else {
5030
0
            for (j = 0; j < num_comp; j++) {
5031
0
                src[j] = 65535 - pdc->colors.devn.values[j];
5032
0
            }
5033
0
        }
5034
0
    } else
5035
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
5036
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
5037
0
    if (has_shape)
5038
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
5039
    /* Limit the area we write to the bounding rectangle for this buffer */
5040
0
    if (x < buf->rect.p.x) {
5041
0
        xoff = data_x + buf->rect.p.x - x;
5042
0
        w += x - buf->rect.p.x;
5043
0
        x = buf->rect.p.x;
5044
0
    } else {
5045
0
        xoff = data_x;
5046
0
    }
5047
0
    if (y < buf->rect.p.y) {
5048
0
      h += y - buf->rect.p.y;
5049
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
5050
0
      y = buf->rect.p.y;
5051
0
    }
5052
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
5053
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
5054
    /* Update the dirty rectangle. */
5055
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
5056
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
5057
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
5058
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
5059
5060
    /* composite with backdrop only. */
5061
0
    line = buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5062
0
    if (knockout && has_backdrop)
5063
0
        bline = buf->backdrop + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5064
0
    else
5065
0
        bline = line;
5066
5067
0
    planestride >>= 1;
5068
0
    rowstride   >>= 1;
5069
0
    alpha_g_off >>= 1;
5070
0
    shape_off   >>= 1;
5071
0
    tag_off     >>= 1;
5072
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
5073
0
        back_ptr = (uint16_t *)(void *)bline;
5074
0
        dst_ptr = (uint16_t *)(void *)line;
5075
0
        sx = xoff;
5076
0
        for (i = 0; i < w; ++i, ++sx) {
5077
            /* Complement the components for subtractive color spaces */
5078
0
            if (additive) {
5079
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
5080
0
                    dst[k] = back_ptr[k * planestride];
5081
0
            } else { /* Complement the components for subtractive color spaces */
5082
0
                for (k = 0; k < num_comp; ++k)
5083
0
                    dst[k] = 65535 - back_ptr[k * planestride];
5084
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
5085
0
            }
5086
            /* Get the aa alpha from the buffer */
5087
0
            switch(depth)
5088
0
            {
5089
0
            case 2:  /* map 0 - 3 to 0 - 255 */
5090
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
5091
0
                break;
5092
0
            case 4:
5093
0
                alpha2_aa = aa_row[sx >> 1];
5094
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
5095
0
                break;
5096
0
            case 8:
5097
0
                alpha_aa = aa_row[sx];
5098
0
                break;
5099
0
            default:
5100
0
                return_error(gs_error_rangecheck);
5101
0
            }
5102
0
            if (alpha_aa != 0) {  /* This does happen */
5103
0
                if (alpha_aa != 255) {
5104
                    /* We have an alpha value from aa */
5105
0
                    alpha_aa_act = alpha_aa * 0x101;
5106
0
                    if (src_alpha != 65535) {
5107
                        /* Need to combine it with the existing alpha */
5108
0
                        int tmp = src_alpha * alpha_aa_act + 0x8000;
5109
0
                        alpha_aa_act = (tmp + (tmp >> 16)) >> 16;
5110
0
                    }
5111
                    /* Set our source alpha value appropriately */
5112
0
                    src[num_comp] = alpha_aa_act;
5113
0
                } else {
5114
                    /* We may have to reset this is it was changed as we
5115
                       moved across the row */
5116
0
                    src[num_comp] = src_alpha;
5117
0
                }
5118
0
                if (knockout) {
5119
0
                    if (buf->isolated) {
5120
0
                        art_pdf_knockoutisolated_group_16(dst, src, num_comp);
5121
0
                    } else {
5122
0
                        art_pdf_composite_knockout_16(dst, src, num_comp,
5123
0
                            blend_mode, pdev->blend_procs, pdev);
5124
0
                    }
5125
0
                } else {
5126
0
                    art_pdf_composite_pixel_alpha_16(dst, src, num_comp, blend_mode, num_comp,
5127
0
                                                     pdev->blend_procs, pdev);
5128
0
                }
5129
                /* Complement the results for subtractive color spaces */
5130
0
                if (additive) {
5131
0
                    for (k = 0; k < num_chan; ++k)
5132
0
                        dst_ptr[k * planestride] = dst[k];
5133
0
                } else {
5134
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
5135
0
                        for (k = 0, comps = drawn_comps; comps != 0;
5136
0
                                ++k, comps >>= 1) {
5137
0
                            if ((comps & 0x1) != 0) {
5138
0
                                dst_ptr[k * planestride] = 65535 - dst[k];
5139
0
                            }
5140
0
                        }
5141
                        /* The alpha channel */
5142
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5143
0
                    } else {
5144
0
                        for (k = 0; k < num_comp; ++k)
5145
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
5146
                        /* The alpha channel */
5147
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5148
0
                    }
5149
0
                }
5150
0
                if (has_alpha_g) {
5151
0
                    int tmp = (65535 - back_ptr[alpha_g_off]) * (65535 - src[num_comp]) + 0x8000;
5152
0
                    dst_ptr[alpha_g_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5153
0
                }
5154
0
                if (has_shape) {
5155
0
                    int tmp = (65535 - back_ptr[shape_off]) * (65535 - shape) + 0x8000;
5156
0
                    dst_ptr[shape_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5157
0
                }
5158
0
                if (has_tags) {
5159
                    /* If alpha is 100% then set to curr_tag, else or */
5160
                    /* other than Normal BM, we always OR */
5161
0
                    if (src[num_comp] == 65535 && tag_blend) {
5162
0
                        dst_ptr[tag_off] = curr_tag;
5163
0
                    } else {
5164
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
5165
0
                    }
5166
0
                }
5167
0
            }
5168
0
            ++dst_ptr;
5169
0
            ++back_ptr;
5170
0
        }
5171
0
        line += rowstride;
5172
0
        bline += rowstride;
5173
0
    }
5174
0
    return 0;
5175
0
}
5176
5177
static int
5178
pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
5179
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
5180
                      gx_color_index color, const gx_device_color *pdc,
5181
                      int depth, bool devn)
5182
0
{
5183
0
    bool deep = device_is_deep(dev);
5184
0
    int code;
5185
5186
0
    code = pdf14_initialize_ctx(dev, NULL);
5187
0
    if (code < 0)
5188
0
        return code;
5189
5190
0
    if (deep)
5191
0
        return do_pdf14_copy_alpha_color_16(dev, data, data_x, aa_raster,
5192
0
                                            id, x, y, w, h,
5193
0
                                            color, pdc, depth, devn);
5194
0
    else
5195
0
        return do_pdf14_copy_alpha_color(dev, data, data_x, aa_raster,
5196
0
                                         id, x, y, w, h,
5197
0
                                         color, pdc, depth, devn);
5198
0
}
5199
5200
static  int
5201
pdf14_fill_mask(gx_device * orig_dev,
5202
                     const byte * data, int dx, int raster, gx_bitmap_id id,
5203
                     int x, int y, int w, int h,
5204
                     const gx_drawing_color * pdcolor, int depth,
5205
                     gs_logical_operation_t lop, const gx_clip_path * pcpath)
5206
29.3M
{
5207
29.3M
    gx_device *dev;
5208
29.3M
    pdf14_device *p14dev = (pdf14_device *)orig_dev;
5209
29.3M
    gx_device_clip cdev;
5210
29.3M
    gx_color_tile *ptile = NULL;
5211
29.3M
    int code = 0;
5212
29.3M
    gs_int_rect group_rect;
5213
29.3M
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5214
29.3M
    bool has_pattern_trans = false;
5215
29.3M
    cmm_dev_profile_t *dev_profile;
5216
5217
29.3M
    if (pdcolor == NULL)
5218
0
        return_error(gs_error_unknownerror);  /* color must be defined */
5219
5220
29.3M
    code = pdf14_initialize_ctx(orig_dev, NULL);
5221
29.3M
    if (code < 0)
5222
0
        return code;
5223
5224
    /* If we are doing a fill with a pattern that has a transparency then
5225
       go ahead and do a push and a pop of the transparency group */
5226
29.3M
    if (gx_dc_is_pattern1_color(pdcolor)) {
5227
0
        if( gx_pattern1_get_transptr(pdcolor) != NULL) {
5228
0
            ptile = pdcolor->colors.pattern.p_tile;
5229
            /* Set up things in the ptile so that we get the proper
5230
               blending etc */
5231
            /* Set the blending procs and the is_additive setting based
5232
               upon the number of channels */
5233
0
            if (ptile->ttrans->n_chan-1 < 4) {
5234
0
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5235
0
                ptile->ttrans->is_additive = true;
5236
0
            } else {
5237
0
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5238
0
                ptile->ttrans->is_additive = false;
5239
0
            }
5240
            /* Set the procs so that we use the proper filling method. */
5241
0
            gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5242
            /* Based upon if the tiles overlap pick the type of rect
5243
               fill that we will want to use */
5244
0
            if (ptile->has_overlap) {
5245
                /* This one does blending since there is tile overlap */
5246
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5247
0
            } else {
5248
                /* This one does no blending since there is no tile overlap */
5249
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5250
0
            }
5251
            /* Push the group */
5252
0
            group_rect.p.x = x;
5253
0
            group_rect.p.y = max(0,y);
5254
0
            group_rect.q.x = x + w;
5255
0
            group_rect.q.y = y + h;
5256
0
            if (!(w <= 0 || h <= 0)) {
5257
5258
0
                pdf14_group_color_t *group_color_info = pdf14_clone_group_color_info((gx_device *) p14dev, p14dev->ctx->stack->group_color_info);
5259
0
                if (group_color_info == NULL)
5260
0
                    return_error(gs_error_VMerror);
5261
5262
0
                code = pdf14_push_transparency_group(p14dev->ctx, &group_rect,
5263
0
                     1, 0, 65535, 65535, 65535, BLEND_MODE_Normal, 0, 0,
5264
0
                     ptile->ttrans->n_chan-1, false, false, NULL, NULL,
5265
0
                     group_color_info, NULL, NULL);
5266
0
                if (code < 0)
5267
0
                    return code;
5268
                /* Set up the output buffer information now that we have
5269
                   pushed the group */
5270
0
                fill_trans_buffer = new_pattern_trans_buff(p14dev->memory);
5271
0
                if (fill_trans_buffer == NULL)
5272
0
                    return_error(gs_error_VMerror);
5273
5274
0
                pdf14_get_buffer_information((gx_device *) p14dev,
5275
0
                                              fill_trans_buffer, NULL, false);
5276
                /* Store this in the appropriate place in pdcolor.  This
5277
                   is released later after the mask fill */
5278
0
                ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5279
0
                has_pattern_trans = true;
5280
0
            }
5281
0
        }
5282
0
    }
5283
29.3M
    if (pcpath != 0) {
5284
3.94M
        gx_make_clip_device_on_stack(&cdev, pcpath, orig_dev);
5285
3.94M
        dev = (gx_device *) & cdev;
5286
3.94M
    } else
5287
25.3M
        dev = orig_dev;
5288
29.3M
    if (depth > 1) {
5289
        /****** CAN'T DO ROP OR HALFTONE WITH ALPHA ******/
5290
0
        code = (*dev_proc(dev, copy_alpha))
5291
0
            (dev, data, dx, raster, id, x, y, w, h,
5292
0
             gx_dc_pure_color(pdcolor), depth);
5293
29.3M
    } else {
5294
29.3M
        code = pdcolor->type->fill_masked(pdcolor, data, dx, raster, id,
5295
29.3M
                                          x, y, w, h, dev, lop, false);
5296
29.3M
    }
5297
29.3M
    if (has_pattern_trans) {
5298
0
        bool has_tags = device_encodes_tags(dev);
5299
0
        if (code >= 0)
5300
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5301
0
        if (code >= 0)
5302
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx,
5303
0
                                                p14dev->blend_procs,
5304
0
                                                p14dev->color_info.num_components - has_tags,
5305
0
                                                dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5306
0
                                                orig_dev);
5307
0
        gs_free_object(p14dev->memory, ptile->ttrans->fill_trans_buffer,
5308
0
                       "pdf14_fill_mask");
5309
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5310
0
    }
5311
29.3M
    if (pcpath != 0)
5312
3.94M
        gx_destroy_clip_device_on_stack(&cdev);
5313
29.3M
    return code;
5314
29.3M
}
5315
5316
5317
5318
/* Used for filling rects when we are doing a fill with a pattern that
5319
   has transparency */
5320
static  int
5321
pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
5322
                        gx_path * ppath, const gx_fill_params * params,
5323
                        const gx_device_color * pdevc,
5324
                        const gx_clip_path * pcpath)
5325
139k
{
5326
139k
    int code;
5327
139k
    gs_gstate *pgs_noconst = (gs_gstate *)pgs; /* Break const. */
5328
139k
    gs_fixed_rect clip_box;
5329
139k
    gs_fixed_rect outer_box;
5330
139k
    pdf14_device * p14dev = (pdf14_device *)pdev;
5331
139k
    gs_int_rect rect;
5332
139k
    gx_clip_rect *curr_clip_rect;
5333
139k
    gx_color_tile *ptile = NULL;
5334
139k
    int k;
5335
139k
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5336
139k
    gs_int_point phase;  /* Needed during clist rendering for band offset */
5337
139k
    int n_chan_tile;
5338
139k
    gx_clip_path cpath_intersection;
5339
139k
    gx_path path_ttrans;
5340
139k
    pdf14_group_color_t *group_color_info;
5341
139k
    bool has_tags = device_encodes_tags(pdev);
5342
5343
139k
    if (ppath == NULL)
5344
0
        return_error(gs_error_unknownerror);  /* should not happen */
5345
139k
    if (pcpath != NULL) {
5346
133k
        code = gx_cpath_init_local_shared_nested(&cpath_intersection, pcpath, ppath->memory, 1);
5347
133k
    } else {
5348
5.90k
        (*dev_proc(pdev, get_clipping_box)) (pdev, &clip_box);
5349
5.90k
        gx_cpath_init_local(&cpath_intersection, ppath->memory);
5350
5.90k
        code = gx_cpath_from_rectangle(&cpath_intersection, &clip_box);
5351
5.90k
    }
5352
139k
    if (code < 0)
5353
0
        return code;
5354
139k
    code = gx_cpath_intersect_with_params(&cpath_intersection, ppath,
5355
139k
                                          params->rule, pgs_noconst, params);
5356
139k
    if (code < 0)
5357
0
        return code;
5358
    /* One (common) case worth optimising for is where we have a pattern that
5359
     * is positioned such that only one repeat of the tile is actually
5360
     * visible. In this case, we can restrict the size of the blending group
5361
     * we need to produce to be that of the actual area of the tile that is
5362
     * used. */
5363
139k
    ptile = pdevc->colors.pattern.p_tile;
5364
139k
    if (ptile->ttrans != NULL)
5365
49.5k
    {
5366
49.5k
        if ((cpath_intersection.outer_box.p.x < 0) ||
5367
49.5k
            (cpath_intersection.outer_box.p.y < 0) ||
5368
49.5k
            (cpath_intersection.outer_box.q.x > int2fixed(ptile->ttrans->width)) ||
5369
18.9k
            (cpath_intersection.outer_box.q.y > int2fixed(ptile->ttrans->height)))
5370
31.1k
        {
5371
            /* More than one repeat of the tile would be visible, so we can't
5372
             * use the optimisation here. (Actually, this test isn't quite
5373
             * right - it actually tests whether more than the '0th' repeat
5374
             * of the tile is visible. A better test would test if just one
5375
             * repeat of the tile was visible, irrespective of which one.
5376
             * This is (hopefully) relatively rare, and would make the code
5377
             * below more complex too, so we're ignoring that for now. If it
5378
             * becomes evident that it's a case that matters we can revisit
5379
             * it.) */
5380
31.1k
        } else {
5381
            /* Only the 0th repeat is visible. Restrict the size further to
5382
             * just the used area of that patch. */
5383
18.4k
            gx_path_init_local(&path_ttrans, ppath->memory);
5384
18.4k
            code = gx_path_add_rectangle(&path_ttrans,
5385
18.4k
                                         int2fixed(ptile->ttrans->rect.p.x),
5386
18.4k
                                         int2fixed(ptile->ttrans->rect.p.y),
5387
18.4k
                                         int2fixed(ptile->ttrans->rect.q.x),
5388
18.4k
                                         int2fixed(ptile->ttrans->rect.q.y));
5389
18.4k
            if (code < 0)
5390
0
                return code;
5391
18.4k
            code = gx_cpath_intersect(&cpath_intersection, &path_ttrans,
5392
18.4k
                                      params->rule, pgs_noconst);
5393
18.4k
            gx_path_free(&path_ttrans, "pdf14_tile_pattern_fill(path_ttrans)");
5394
18.4k
            if (code < 0)
5395
0
                return code;
5396
18.4k
        }
5397
49.5k
    }
5398
    /* Now let us push a transparency group into which we are
5399
     * going to tile the pattern.  */
5400
139k
    if (ppath != NULL) {
5401
139k
        pdf14_device save_pdf14_dev;    /* save area for p14dev */
5402
5403
139k
        gx_cpath_outer_box(&cpath_intersection, &outer_box);
5404
139k
        rect.p.x = fixed2int(outer_box.p.x);
5405
139k
        rect.p.y = fixed2int(outer_box.p.y);
5406
139k
        rect.q.x = fixed2int_ceiling(outer_box.q.x);
5407
139k
        rect.q.y = fixed2int_ceiling(outer_box.q.y);
5408
5409
        /* The color space of this group must be the same as that of the
5410
           tile.  Then when we pop the group, if there is a mismatch between
5411
           the tile color space and the current context we will do the proper
5412
           conversion.  In this way, we ensure that if the tile has any overlapping
5413
           occuring it will be blended in the proper manner i.e in the tile
5414
           underlying color space. */
5415
139k
        if (ptile->cdev == NULL) {
5416
49.5k
            if (ptile->ttrans == NULL)
5417
0
                return_error(gs_error_unknownerror);  /* should not happen */
5418
49.5k
            n_chan_tile = ptile->ttrans->n_chan;
5419
89.5k
        } else {
5420
89.5k
            n_chan_tile = ptile->cdev->common.color_info.num_components+1;
5421
89.5k
        }
5422
139k
        memcpy(&save_pdf14_dev, p14dev, sizeof(pdf14_device));
5423
5424
        /* Transparency handling with patterns confuses me, so some notes...
5425
         *
5426
         * For simple, non-transparent patterns, like you'd get in PS, we've
5427
         * used bitmap tiles. Draw into those tiles, and tile those out multiple
5428
         * times. To cope with unmarked pixels, we have a "transparency" plane
5429
         * (simple on/off) that says whether a pixel is marked or not.
5430
         *
5431
         * For patterns with transparency (but not blending), we can create an
5432
         * isolated transparency group, tile all the bitmap tiles into that, and
5433
         * then blend that back with the required alpha at the end. This works
5434
         * because the alpha values of the individual objects within the tile are
5435
         * recorded in that group.
5436
         *
5437
         * We can't do that for groups that use blending though, as each object
5438
         * in the pattern might use a different blend, and we don't (can't) record
5439
         * the blending mode. An isolated group doesn't even allow us to actually
5440
         * do the blending at all. So, for such patterns (any patterns that sets (or
5441
         * just has a resource that mentions) a non-normal blend mode), we use
5442
         * a pattern clist.
5443
         */
5444
139k
        if (ptile->cdev == NULL) {
5445
49.5k
            group_color_info = pdf14_clone_group_color_info(pdev, p14dev->ctx->stack->group_color_info);
5446
49.5k
            if (group_color_info == NULL)
5447
0
                return gs_error_VMerror;
5448
5449
49.5k
            code = pdf14_push_transparency_group(p14dev->ctx, &rect, 1, 0, (uint16_t)floor(65535 * p14dev->alpha + 0.5),
5450
49.5k
                                                 (uint16_t)floor(65535 * p14dev->shape + 0.5), (uint16_t)floor(65535 * p14dev->opacity + 0.5),
5451
49.5k
                                                 BLEND_MODE_Normal, 0, 0, n_chan_tile - 1, false, false,
5452
49.5k
                                                 NULL, NULL, group_color_info, pgs_noconst, pdev);
5453
49.5k
            if (code < 0)
5454
0
                return code;
5455
49.5k
        }
5456
5457
        /* Set the blending procs and the is_additive setting based
5458
           upon the number of channels */
5459
139k
        if (ptile->cdev == NULL) {
5460
49.5k
            if (n_chan_tile-1 < 4) {
5461
47.4k
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5462
47.4k
                ptile->ttrans->is_additive = true;
5463
47.4k
            } else {
5464
2.12k
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5465
2.12k
                ptile->ttrans->is_additive = false;
5466
2.12k
            }
5467
49.5k
        }
5468
        /* Now lets go through the rect list and fill with the pattern */
5469
        /* First get the buffer that we will be filling */
5470
139k
        if (ptile->cdev == NULL) {
5471
49.5k
            fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5472
49.5k
            if (fill_trans_buffer == NULL) {
5473
0
                p14dev->pclist_device = NULL;
5474
0
                return_error(gs_error_VMerror);
5475
0
            }
5476
49.5k
            pdf14_get_buffer_information(pdev, fill_trans_buffer, NULL, false);
5477
            /* Based upon if the tiles overlap pick the type of rect fill that we will
5478
               want to use */
5479
49.5k
            if (ptile->has_overlap) {
5480
                /* This one does blending since there is tile overlap */
5481
1.24k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5482
48.3k
            } else {
5483
                /* This one does no blending since there is no tile overlap */
5484
48.3k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5485
48.3k
            }
5486
            /* fill the rectangles */
5487
49.5k
            phase.x = pdevc->phase.x;
5488
49.5k
            phase.y = pdevc->phase.y;
5489
49.5k
            if (cpath_intersection.rect_list->list.head != NULL){
5490
1.20k
                curr_clip_rect = cpath_intersection.rect_list->list.head->next;
5491
20.0k
                for( k = 0; k < cpath_intersection.rect_list->list.count && code >= 0; k++){
5492
18.8k
                    if_debug5m('v', pgs->memory,
5493
18.8k
                               "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5494
18.8k
                               curr_clip_rect->xmin, curr_clip_rect->ymin,
5495
18.8k
                               curr_clip_rect->xmax-curr_clip_rect->xmin,
5496
18.8k
                               curr_clip_rect->ymax-curr_clip_rect->ymin, (int)ptile->id);
5497
18.8k
                    code = gx_trans_pattern_fill_rect(curr_clip_rect->xmin, curr_clip_rect->ymin,
5498
18.8k
                                                      curr_clip_rect->xmax, curr_clip_rect->ymax, ptile,
5499
18.8k
                                                      fill_trans_buffer, phase, pdev, pdevc, 1);
5500
18.8k
                    curr_clip_rect = curr_clip_rect->next;
5501
18.8k
                }
5502
48.3k
            } else if (cpath_intersection.rect_list->list.count == 1) {
5503
                /* The case when there is just a single rect */
5504
48.0k
                if_debug5m('v', pgs->memory,
5505
48.0k
                           "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5506
48.0k
                           cpath_intersection.rect_list->list.single.xmin,
5507
48.0k
                           cpath_intersection.rect_list->list.single.ymin,
5508
48.0k
                           cpath_intersection.rect_list->list.single.xmax-
5509
48.0k
                              cpath_intersection.rect_list->list.single.xmin,
5510
48.0k
                           cpath_intersection.rect_list->list.single.ymax-
5511
48.0k
                              cpath_intersection.rect_list->list.single.ymin,
5512
48.0k
                           (int)ptile->id);
5513
48.0k
                code = gx_trans_pattern_fill_rect(cpath_intersection.rect_list->list.single.xmin,
5514
48.0k
                                                  cpath_intersection.rect_list->list.single.ymin,
5515
48.0k
                                                  cpath_intersection.rect_list->list.single.xmax,
5516
48.0k
                                                  cpath_intersection.rect_list->list.single.ymax,
5517
48.0k
                                                  ptile, fill_trans_buffer, phase, pdev, pdevc, 1);
5518
48.0k
            }
5519
89.5k
        } else {
5520
            /* Clist pattern with transparency.  Create a clip device from our
5521
               cpath_intersection.  The above non-clist case could probably be
5522
               done this way too, which will reduce the amount of code here.
5523
               That is for another day though due to time constraints*/
5524
89.5k
            gx_device *dev;
5525
89.5k
            gx_device_clip clipdev;
5526
5527
89.5k
            gx_make_clip_device_on_stack(&clipdev, &cpath_intersection, pdev);
5528
89.5k
            dev = (gx_device *)&clipdev;
5529
89.5k
            phase.x = pdevc->phase.x;
5530
89.5k
            phase.y = pdevc->phase.y;
5531
89.5k
            code = gx_trans_pattern_fill_rect(rect.p.x, rect.p.y, rect.q.x, rect.q.y,
5532
89.5k
                                              ptile, fill_trans_buffer, phase,
5533
89.5k
                                              dev, pdevc, 1);
5534
89.5k
            gx_destroy_clip_device_on_stack(&clipdev);
5535
89.5k
        }
5536
        /* We're done drawing with the pattern, remove the reference to the
5537
         * pattern device
5538
         */
5539
139k
        p14dev->pclist_device = NULL;
5540
139k
        if (code < 0)
5541
0
            return code;
5542
5543
        /* free our buffer object */
5544
139k
        if (fill_trans_buffer != NULL) {
5545
49.5k
            gs_free_object(pgs->memory, fill_trans_buffer, "pdf14_tile_pattern_fill");
5546
49.5k
            ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5547
49.5k
        }
5548
139k
        if (ptile->cdev == NULL) {
5549
            /* pop our transparency group which will force the blending.
5550
               This was all needed for Bug 693498 */
5551
49.5k
            code = pdf14_pop_transparency_group(pgs_noconst, p14dev->ctx,
5552
49.5k
                                                p14dev->blend_procs,
5553
49.5k
                                                p14dev->color_info.num_components - has_tags,
5554
49.5k
                                                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5555
49.5k
                                                pdev);
5556
49.5k
        }
5557
139k
        memcpy(p14dev, &save_pdf14_dev, sizeof(pdf14_device));
5558
139k
        p14dev->pclist_device = NULL;
5559
139k
    }
5560
139k
    gx_cpath_free(&cpath_intersection, "pdf14_tile_pattern_fill");
5561
139k
    return code;
5562
139k
}
5563
5564
/* Useful function that should probably go elsewhere.
5565
 * Call this function to find the topmost pdf14 device in the device chain,
5566
 * or NULL if there is not one.
5567
 */
5568
static pdf14_device *find_pdf14_device(gx_device *dev)
5569
0
{
5570
0
    pdf14_device *pdev;
5571
5572
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, &pdev, sizeof(pdev)) <= 0)
5573
0
        return NULL;
5574
0
    return pdev;
5575
0
}
5576
5577
/* Imager render for pattern transparency filling.  This is just here to catch
5578
   the final flush, at which time we will pop the group and reset a few items */
5579
static  int
5580
pdf14_pattern_trans_render(gx_image_enum * penum, const byte * buffer, int data_x,
5581
                    uint w, int h, gx_device * dev)
5582
0
{
5583
0
    int code;
5584
0
    pdf14_device * p14dev;
5585
0
    const gs_gstate * pgs = penum->pgs;
5586
0
    gx_device_color * pdcolor = (penum->icolor1);
5587
0
    gx_color_tile *ptile = pdcolor->colors.pattern.p_tile;
5588
0
    bool has_tags = device_encodes_tags(dev);
5589
5590
    /* Pass along to the original renderer */
5591
0
    code = (ptile->ttrans->image_render)(penum, buffer, data_x, w, h, dev);
5592
0
    if (code < 0)
5593
0
        return code;
5594
    /* On our final time through here, go ahead and pop the transparency
5595
       group and reset the procs in the device color. And free the fill
5596
       trans buffer object */
5597
0
    if (h == 0 && ptile->trans_group_popped == false) {
5598
0
        p14dev = find_pdf14_device(dev);
5599
5600
0
        if (p14dev->pclist_device == NULL) {
5601
            /* Used if we are on clist writing phase.  Would only
5602
               occur if we somehow failed in high level clist
5603
               image writing */
5604
0
            code = gs_end_transparency_group((gs_gstate *) pgs);
5605
0
        } else {
5606
            /* Used if we are on clist reading phase.  If we had high level
5607
               image in clist */
5608
0
            cmm_dev_profile_t *dev_profile;
5609
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5610
0
            if (code < 0)
5611
0
                return code;
5612
5613
0
            if_debug2m('v', p14dev->ctx->memory,
5614
0
                      "[v*] Popping trans group pattern fill, uid = %ld id = %ld \n",
5615
0
                       ptile->uid.id, ptile->id);
5616
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx, p14dev->blend_procs,
5617
0
                    p14dev->color_info.num_components - has_tags,
5618
0
                    dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5619
0
                    (gx_device *) p14dev);
5620
0
        }
5621
0
        pdcolor->colors.pattern.p_tile->trans_group_popped = true;
5622
0
        gs_free_object(pgs->memory, ptile->ttrans->fill_trans_buffer,
5623
0
                       "pdf14_pattern_trans_render");
5624
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5625
0
    }
5626
0
    return code;
5627
0
}
5628
5629
/* This function is used to get things in place for filling a mask image
5630
   with a pattern that has transparency.  It is used by pdf14_begin_type_image
5631
   and pdf14_clist_begin_type_image */
5632
static int
5633
pdf14_patt_trans_image_fill(gx_device * dev, const gs_gstate * pgs,
5634
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5635
                           const gs_int_rect * prect,
5636
                           const gx_drawing_color * pdcolor,
5637
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5638
                           gx_image_enum_common_t ** pinfo)
5639
0
{
5640
0
    const gs_image_t *pim = (const gs_image_t *)pic;
5641
0
    pdf14_device * p14dev = (pdf14_device *)dev;
5642
0
    gx_color_tile *ptile;
5643
0
    int code;
5644
0
    gs_int_rect group_rect;
5645
0
    gx_image_enum *penum;
5646
0
    gs_rect bbox_in, bbox_out;
5647
0
    gx_pattern_trans_t *fill_trans_buffer;
5648
5649
0
    ptile = pdcolor->colors.pattern.p_tile;
5650
    /* Set up things in the ptile so that we get the proper
5651
       blending etc */
5652
    /* Set the blending procs and the is_additive setting based
5653
       upon the number of channels */
5654
0
    if (ptile->ttrans->n_chan-1 < 4) {
5655
0
        ptile->ttrans->blending_procs = &rgb_blending_procs;
5656
0
        ptile->ttrans->is_additive = true;
5657
0
    } else {
5658
0
        ptile->ttrans->blending_procs = &cmyk_blending_procs;
5659
0
        ptile->ttrans->is_additive = false;
5660
0
    }
5661
    /* Set the blending mode in the ptile based upon the current
5662
       setting in the gs_gstate */
5663
0
    ptile->blending_mode = pgs->blend_mode;
5664
    /* Based upon if the tiles overlap pick the type of rect
5665
       fill that we will want to use */
5666
0
    if (ptile->has_overlap) {
5667
        /* This one does blending since there is tile overlap */
5668
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5669
0
    } else {
5670
        /* This one does no blending since there is no tile overlap */
5671
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5672
0
    }
5673
    /* Set the procs so that we use the proper filling method. */
5674
0
    gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5675
    /* Let the imaging stuff get set up */
5676
0
    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
5677
0
                            prect, pdcolor,pcpath, mem, pinfo);
5678
0
    if (code < 0)
5679
0
        return code;
5680
    /* Now Push the group */
5681
    /* First apply the inverse of the image matrix to our
5682
       image size to get our bounding box. */
5683
0
    bbox_in.p.x = 0;
5684
0
    bbox_in.p.y = 0;
5685
0
    bbox_in.q.x = pim->Width;
5686
0
    bbox_in.q.y = pim->Height;
5687
0
    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
5688
0
                                &bbox_out);
5689
0
    if (code < 0)
5690
0
        return code;
5691
    /* That in turn will get hit by the matrix in the gs_gstate */
5692
0
    code = compute_group_device_int_rect(p14dev, &group_rect,
5693
0
                                            &bbox_out, (gs_gstate *)pgs);
5694
0
    if (code < 0)
5695
0
        return code;
5696
0
    if (!(pim->Width == 0 || pim->Height == 0)) {
5697
0
        if_debug2m('v', p14dev->ctx->memory,
5698
0
                   "[v*] Pushing trans group patt_trans_image_fill, uid = %ld id = %ld \n",
5699
0
                   ptile->uid.id, ptile->id);
5700
5701
0
        code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, 1, 0, 65535, 65535,
5702
0
                                             65535, pgs->blend_mode, 0, 0,
5703
0
                                             ptile->ttrans->n_chan-1, false, false,
5704
0
                                             NULL, NULL, NULL, (gs_gstate *)pgs, dev);
5705
5706
        /* Set up the output buffer information now that we have
5707
           pushed the group */
5708
0
        fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5709
0
        if (fill_trans_buffer == NULL)
5710
0
            return_error(gs_error_VMerror);
5711
5712
0
        pdf14_get_buffer_information(dev, fill_trans_buffer, NULL, false);
5713
5714
        /* Store this in the appropriate place in pdcolor.  This
5715
           is released later in pdf14_pattern_trans_render when
5716
           we are all done with the mask fill */
5717
0
        ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5718
5719
        /* Change the renderer to handle this case so we can catch the
5720
           end.  We will then pop the group and reset the pdcolor proc.
5721
           Keep the base renderer also. */
5722
0
        penum = (gx_image_enum *) *pinfo;
5723
0
        ptile->ttrans->image_render = penum->render;
5724
0
        penum->render = &pdf14_pattern_trans_render;
5725
0
        ptile->trans_group_popped = false;
5726
0
    }
5727
0
    return code;
5728
0
}
5729
5730
static  int
5731
pdf14_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
5732
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5733
                           const gs_int_rect * prect,
5734
                           const gx_drawing_color * pdcolor,
5735
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5736
                           gx_image_enum_common_t ** pinfo)
5737
820k
{
5738
820k
    const gs_image_t *pim = (const gs_image_t *)pic;
5739
820k
    int code;
5740
5741
820k
    code = pdf14_initialize_ctx(dev, pgs);
5742
820k
    if (code < 0)
5743
0
        return code;
5744
5745
    /* If we are filling an image mask with a pattern that has a transparency
5746
       then we need to do some special handling */
5747
820k
    if (pim->ImageMask) {
5748
81
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
5749
0
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
5750
                /* If we are in a final run through here for this case then
5751
                   go ahead and push the transparency group.   Also, update
5752
                   the proc for the pattern color so that we used the
5753
                   appropriate fill operation.  Note that the group
5754
                   is popped and the proc will be reset when we flush the
5755
                   image data.  This is handled in a special pdf14 image
5756
                   renderer which will end up installed for this case.
5757
                   Detect setting of begin_image to gx_no_begin_image.
5758
                   (final recursive call) */
5759
0
                if (dev_proc(dev, begin_typed_image) != gx_default_begin_typed_image) {
5760
0
                    code = pdf14_patt_trans_image_fill(dev, pgs, pmat, pic,
5761
0
                                                prect, pdcolor, pcpath, mem,
5762
0
                                                pinfo);
5763
0
                    return code;
5764
0
                }
5765
0
            }
5766
0
        }
5767
81
    }
5768
820k
    pdf14_set_marking_params(dev, pgs);
5769
820k
    return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor,
5770
820k
                                        pcpath, mem, pinfo);
5771
820k
}
5772
5773
static  void
5774
pdf14_set_params(gs_gstate * pgs,
5775
                 gx_device * dev,
5776
                 const gs_pdf14trans_params_t * pparams)
5777
20.9M
{
5778
20.9M
    if_debug0m('v', dev->memory, "[v]pdf14_set_params\n");
5779
20.9M
    if (pparams->changed & PDF14_SET_BLEND_MODE)
5780
3.81M
        pgs->blend_mode = pparams->blend_mode;
5781
20.9M
    if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
5782
1.95M
        pgs->text_knockout = pparams->text_knockout;
5783
20.9M
    if (pparams->changed & PDF14_SET_AIS)
5784
1.03M
        pgs->alphaisshape = pparams->ais;
5785
20.9M
    if (pparams->changed & PDF14_SET_OVERPRINT)
5786
5.89M
        pgs->overprint = pparams->overprint;
5787
20.9M
    if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
5788
5.87M
        pgs->stroke_overprint = pparams->stroke_overprint;
5789
20.9M
    if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
5790
6.99M
        pgs->fillconstantalpha = pparams->fillconstantalpha;
5791
20.9M
    if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
5792
5.57M
        pgs->strokeconstantalpha = pparams->strokeconstantalpha;
5793
20.9M
    if (pparams->changed & PDF14_SET_FILLSTROKE_STATE) {
5794
5.82M
        gs_swapcolors_quick(pgs);
5795
5.82M
        if (pparams->op_fs_state == PDF14_OP_STATE_STROKE)
5796
2.04M
            pgs->is_fill_color = false;
5797
3.78M
        else
5798
3.78M
            pgs->is_fill_color = true;
5799
5.82M
    }
5800
20.9M
    pdf14_set_marking_params(dev, pgs);
5801
20.9M
}
5802
5803
/*
5804
 * This open_device method for the PDF 1.4 compositor devices is only used
5805
 * when these devices are disabled.  This routine is about as close to
5806
 * a pure "forwarding" open_device operation as is possible. Its only
5807
 * significant function is to ensure that the is_open field of the
5808
 * PDF 1.4 compositor devices matches that of the target device.
5809
 *
5810
 * We assume this procedure is called only if the device is not already
5811
 * open, and that gs_opendevice will take care of the is_open flag.
5812
 */
5813
static  int
5814
pdf14_forward_open_device(gx_device * dev)
5815
0
{
5816
0
    gx_device_forward * pdev = (gx_device_forward *)dev;
5817
0
    gx_device * tdev = pdev->target;
5818
0
    int code;
5819
5820
    /* The PDF 1.4 compositing devices must have a target */
5821
0
    if (tdev == 0)
5822
0
        return_error(gs_error_unknownerror);
5823
0
    if ((code = gs_opendevice(tdev)) >= 0)
5824
0
        gx_device_copy_params(dev, tdev);
5825
0
    return code;
5826
0
}
5827
5828
/*
5829
 * Convert all device procs to be 'forwarding'.  The caller is responsible
5830
 * for setting any device procs that should not be forwarded.
5831
 */
5832
static  void
5833
pdf14_forward_device_procs(gx_device * dev)
5834
1.95M
{
5835
1.95M
    gx_device_forward *pdev = (gx_device_forward *)dev;
5836
1.95M
    pdf14_device *p14dev = (pdf14_device*)dev;
5837
5838
    /* If doing simulated overprint with spot colors
5839
       then makes sure to reset devn setting */
5840
1.95M
    if (p14dev->overprint_sim &&
5841
0
        p14dev->color_info.num_components > 4)
5842
0
        p14dev->icc_struct->supports_devn =
5843
0
            p14dev->target_support_devn;
5844
5845
    /*
5846
     * We are using gx_device_forward_fill_in_procs to set the various procs.
5847
     * This will ensure that any new device procs are also set.  However that
5848
     * routine only changes procs which are NULL.  Thus we start by setting all
5849
     * procs to NULL.
5850
     */
5851
1.95M
    memset(&(pdev->procs), 0, size_of(pdev->procs));
5852
1.95M
    gx_device_forward_fill_in_procs(pdev);
5853
    /*
5854
     * gx_device_forward_fill_in_procs does not forward all procs.
5855
     * Set the remainding procs to also forward.
5856
     */
5857
1.95M
    set_dev_proc(dev, close_device, gx_forward_close_device);
5858
1.95M
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
5859
1.95M
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
5860
1.95M
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
5861
1.95M
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
5862
1.95M
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
5863
1.95M
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
5864
1.95M
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
5865
1.95M
    set_dev_proc(dev, get_profile, gx_forward_get_profile);
5866
1.95M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
5867
    /* These are forwarding devices with minor tweaks. */
5868
1.95M
    set_dev_proc(dev, open_device, pdf14_forward_open_device);
5869
1.95M
    set_dev_proc(dev, put_params, pdf14_forward_put_params);
5870
1.95M
}
5871
5872
/*
5873
 * Disable the PDF 1.4 compositor device.  Once created, the PDF 1.4
5874
 * compositor device is never removed.  (We do not have a remove compositor
5875
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
5876
 * routine implements that action.
5877
 */
5878
int
5879
pdf14_disable_device(gx_device * dev)
5880
1.93M
{
5881
1.93M
    gx_device_forward * pdev = (gx_device_forward *)dev;
5882
5883
1.93M
    if_debug0m('v', dev->memory, "[v]pdf14_disable_device\n");
5884
1.93M
    dev->color_info = pdev->target->color_info;
5885
1.93M
    pdf14_forward_device_procs(dev);
5886
1.93M
    set_dev_proc(dev, composite, pdf14_forward_composite);
5887
1.93M
    return 0;
5888
1.93M
}
5889
5890
/*
5891
 * The default color space for PDF 1.4 blend modes is based upon the process
5892
 * color model of the output device.
5893
 */
5894
static  pdf14_default_colorspace_t
5895
pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum,
5896
                                 pdf14_blend_cs_t *blend_cs_state)
5897
5.38M
{
5898
    /* If a blend color space was specified, then go ahead and use that to
5899
       define the default color space for the blend modes.  Only Gray, RGB
5900
       or CMYK blend color spaces are allowed.  Note we do not allow this
5901
       setting if we are dealing with a separation device. */
5902
5.38M
    cmm_dev_profile_t *dev_profile;
5903
5.38M
    cmm_profile_t *blend_profile = NULL;
5904
5.38M
    pdf14_blend_cs_t temp_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5905
5.38M
    int code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
5906
5.38M
    bool valid_blend_cs = false;
5907
5.38M
    int has_tags = device_encodes_tags(pdev);
5908
5909
5.38M
    *blend_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5910
5911
    /* Are we using a blend color space or the output intent color space? Also
5912
       is there a conflict in the settings. i.e. has someone set a blend color
5913
       space and tried to use the output intent with simulate overprint setting.
5914
    */
5915
5.38M
    if (dev_profile->overprint_control == gs_overprint_control_simulate &&
5916
0
        dev_profile->oi_profile != NULL &&
5917
0
        !gsicc_profiles_equal(dev_profile->oi_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5918
        /* If blend profile is also set, throw a warning about output intent not being used. We have
5919
           possible conflicting command line settings and we will err on using the blend profile
5920
           if one was specified. */
5921
0
        if (dev_profile->blend_profile != NULL &&
5922
0
            !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->oi_profile)) {
5923
0
            blend_profile = dev_profile->blend_profile;
5924
0
            temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5925
0
            emprintf(pdev->memory, "Warning: OI profile not used for blending CS\n");
5926
0
        } else {
5927
            /* All good, use the output intent profile as we have one
5928
               and are doing simulate overprint with a different device
5929
               profile set. */
5930
0
            blend_profile = dev_profile->oi_profile;
5931
0
            temp_cs_state = PDF14_BLEND_CS_OUTPUTINTENT;
5932
0
        }
5933
5.38M
    } else if (dev_profile->blend_profile != NULL &&
5934
0
               !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5935
        /* Blend profile is different than device profile */
5936
0
        blend_profile = dev_profile->blend_profile;
5937
0
        temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5938
0
    }
5939
5940
    /* Make sure any blend color space is valid along with other cond */
5941
5.38M
    if (code == 0 && blend_profile != NULL && !use_pdf14_accum) {
5942
0
        if (!blend_profile->isdevlink &&
5943
0
            !blend_profile->islab &&
5944
0
            (blend_profile->data_cs == gsGRAY ||
5945
0
             blend_profile->data_cs == gsRGB ||
5946
0
             blend_profile->data_cs == gsCMYK)) {
5947
            /* Also, do not allow the use of the blend space when we are pushing
5948
               a pattern pdf14 device.  Those should inherit from the parent */
5949
0
            if (!(gx_device_is_pattern_clist(pdev) ||
5950
0
                  gx_device_is_pattern_accum(pdev))) {
5951
0
                valid_blend_cs = true;
5952
0
            }
5953
0
        }
5954
0
    }
5955
5956
    /* If num components is one, just go ahead and use gray.  This avoids
5957
       issues with additive/subtractive mono color devices  */
5958
5.38M
    if (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ||
5959
4.94M
        pdev->color_info.num_components == 1) {
5960
        /*
5961
        * Note:  We do not allow the SeparationOrder device parameter for
5962
        * additive devices.  Thus we always have 1 colorant for DeviceGray
5963
        * and 3 colorants for DeviceRGB.
5964
        */
5965
4.94M
        if (valid_blend_cs) {
5966
0
            *blend_cs_state = temp_cs_state;
5967
0
            switch (blend_profile->num_comps) {
5968
0
            case 1:
5969
0
                return PDF14_DeviceGray;
5970
0
            case 3:
5971
0
                return PDF14_DeviceRGB;
5972
0
            case 4:
5973
0
                return PDF14_DeviceCMYK;
5974
0
            }
5975
0
        }
5976
4.94M
        if (pdev->color_info.num_components - has_tags == 1)
5977
1.52M
            return PDF14_DeviceGray;
5978
3.42M
        else if (pdev->color_info.num_components - has_tags == 3)
5979
3.42M
            return PDF14_DeviceRGB;
5980
0
        else
5981
0
            return PDF14_DeviceRGBspot;
5982
4.94M
    } else {
5983
        /*
5984
         * Check if the device is CMYK only or CMYK plus spot colors. Note
5985
         * the CMYK plus spot colors will not support the blend color space
5986
         */
5987
435k
        int i, output_comp_num, num_cmyk_used = 0, num_cmyk = 0;
5988
#if CUSTOM_BLENDING_MODE == ALWAYS_USE_CUSTOM_BLENDING
5989
        return PDF14_DeviceCustom;
5990
#endif
5991
        /*
5992
         * Count the number of CMYK process components supported by the output
5993
         * device.
5994
         */
5995
2.17M
        for (i = 0; i < 4; i++) {
5996
1.74M
            const char * pcomp_name = (const char *)DeviceCMYKComponents[i];
5997
5998
1.74M
            output_comp_num = dev_proc(pdev, get_color_comp_index)
5999
1.74M
                (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE_OP);
6000
1.74M
            if (output_comp_num >= 0) {
6001
1.74M
                num_cmyk++;
6002
1.74M
                if (output_comp_num != GX_DEVICE_COLOR_MAX_COMPONENTS)
6003
1.74M
                    num_cmyk_used++;
6004
1.74M
            }
6005
1.74M
        }
6006
        /*
6007
         * Check if the device supports only CMYK.  Otherewise we assume that
6008
         * the output device supports spot colors.  Note:  This algorithm can
6009
         * be fooled if the SeparationOrder device parameter is being used by
6010
         * the output device device to only select CMYK.
6011
         */
6012
435k
        if (num_cmyk_used == 4 && pdev->color_info.num_components == 4
6013
410k
            && pdev->color_info.max_components == 4) {
6014
55.6k
            if (valid_blend_cs) {
6015
0
                *blend_cs_state = temp_cs_state;
6016
0
                switch (blend_profile->num_comps) {
6017
0
                case 1:
6018
0
                    return PDF14_DeviceGray;
6019
0
                case 3:
6020
0
                    return PDF14_DeviceRGB;
6021
0
                case 4:
6022
0
                    return PDF14_DeviceCMYK;
6023
0
                }
6024
0
            }
6025
55.6k
            return PDF14_DeviceCMYK;
6026
55.6k
        }
6027
        /*
6028
         * Check if we should use the 'custom' PDF 1.4 compositor device.
6029
         * This device is only needed for those devices which do not support
6030
         * a basic CMYK process color model.
6031
         */
6032
380k
#if CUSTOM_BLENDING_MODE == AUTO_USE_CUSTOM_BLENDING
6033
380k
        if (num_cmyk != 4)
6034
0
            return PDF14_DeviceCustom;
6035
380k
#endif
6036
        /*
6037
         * Otherewise we use a CMYK plus spot colors for blending.
6038
         */
6039
380k
        if (valid_blend_cs)
6040
0
            *blend_cs_state = temp_cs_state;
6041
380k
        return PDF14_DeviceCMYKspot;
6042
380k
    }
6043
5.38M
}
6044
6045
/*
6046
 * the PDF 1.4 transparency spec says that color space for blending
6047
 * operations can be based upon either a color space specified in the
6048
 * group or a default value based upon the output device.  We are
6049
 * currently only using a color space based upon the device.
6050
 */
6051
static  int
6052
get_pdf14_device_proto(gx_device       *dev,
6053
                       pdf14_device    *pdevproto,
6054
                       gs_gstate       *pgs,
6055
                 const gs_pdf14trans_t *pdf14pct,
6056
                       bool             use_pdf14_accum)
6057
1.96M
{
6058
1.96M
    pdf14_blend_cs_t blend_cs_state;
6059
1.96M
    pdf14_default_colorspace_t dev_cs =
6060
1.96M
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
6061
1.96M
                                                 &blend_cs_state);
6062
1.96M
    bool deep = device_is_deep(dev);
6063
1.96M
    int num_spots = pdf14pct->params.num_spot_colors;
6064
1.96M
    bool has_tags = device_encodes_tags(dev);
6065
6066
    /* overprint overide */
6067
1.96M
    if (pdf14pct->params.overprint_sim_push &&
6068
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
6069
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
6070
0
            dev_cs = PDF14_DeviceCMYKspot;
6071
0
            num_spots = pdf14pct->params.num_spot_colors_int;
6072
0
        } else
6073
0
            dev_cs = PDF14_DeviceCMYK;
6074
0
    }
6075
6076
1.96M
    switch (dev_cs) {
6077
577k
        case PDF14_DeviceGray:
6078
577k
            *pdevproto = gs_pdf14_Gray_device;
6079
577k
            pdevproto->color_info.max_components = 1 + has_tags;
6080
577k
            pdevproto->color_info.num_components =
6081
577k
                                    pdevproto->color_info.max_components + has_tags;
6082
577k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6083
577k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6084
577k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
6085
577k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6086
577k
            pdevproto->sep_device = false;
6087
577k
            break;
6088
1.22M
        case PDF14_DeviceRGB:
6089
1.22M
            *pdevproto = gs_pdf14_RGB_device;
6090
1.22M
            pdevproto->color_info.max_components += has_tags;
6091
1.22M
            pdevproto->color_info.num_components += has_tags;
6092
1.22M
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6093
1.22M
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6094
1.22M
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6095
1.22M
            pdevproto->sep_device = false;
6096
1.22M
            break;
6097
4.38k
        case PDF14_DeviceCMYK:
6098
4.38k
            *pdevproto = gs_pdf14_CMYK_device;
6099
4.38k
            pdevproto->color_info.max_components += has_tags;
6100
4.38k
            pdevproto->color_info.num_components += has_tags;
6101
4.38k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6102
4.38k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6103
4.38k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6104
4.38k
            pdevproto->sep_device = false;
6105
4.38k
            break;
6106
158k
        case PDF14_DeviceCMYKspot:
6107
158k
            *pdevproto = gs_pdf14_CMYKspot_device;
6108
            /* Need to figure out how we want to handle the device profile
6109
               for this case */
6110
            /*
6111
             * The number of components for the PDF14 device is the sum
6112
             * of the process components and the number of spot colors
6113
             * for the page.
6114
             */
6115
158k
            if (num_spots >= 0) {
6116
158k
                pdevproto->color_info.num_components =
6117
158k
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6118
158k
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6119
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6120
158k
                pdevproto->color_info.depth =
6121
158k
                                    pdevproto->color_info.num_components * (8<<deep);
6122
158k
                pdevproto->sep_device = true;
6123
158k
            }
6124
0
            else
6125
0
            {
6126
0
                pdevproto->color_info.max_components += has_tags;
6127
0
                pdevproto->color_info.num_components += has_tags;
6128
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6129
0
            }
6130
158k
            break;
6131
0
        case PDF14_DeviceRGBspot:
6132
0
            *pdevproto = gs_pdf14_RGBspot_device;
6133
            /* Need to figure out how we want to handle the device profile
6134
               for this case */
6135
            /*
6136
             * The number of components for the PDF14 device is the sum
6137
             * of the process components and the number of spot colors
6138
             * for the page.
6139
             */
6140
0
            if (num_spots >= 0) {
6141
0
                pdevproto->color_info.num_components =
6142
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6143
0
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6144
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6145
0
                pdevproto->color_info.depth =
6146
0
                    pdevproto->color_info.num_components * (8 << deep);
6147
0
                pdevproto->sep_device = true;
6148
0
            }
6149
0
            else
6150
0
            {
6151
0
                pdevproto->color_info.max_components += has_tags;
6152
0
                pdevproto->color_info.num_components += has_tags;
6153
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6154
0
            }
6155
0
            break;
6156
0
        case PDF14_DeviceCustom:
6157
            /*
6158
             * We are using the output device's process color model.  The
6159
             * color_info for the PDF 1.4 compositing device needs to match
6160
             * the output device.
6161
             */
6162
0
            *pdevproto = gs_pdf14_custom_device;
6163
0
            pdevproto->color_info = dev->color_info;
6164
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
6165
0
            pdevproto->color_info.depth =
6166
0
                       pdevproto->color_info.num_components * (8<<deep);
6167
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6168
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
6169
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6170
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
6171
0
            break;
6172
0
        default:      /* Should not occur */
6173
0
            return_error(gs_error_rangecheck);
6174
1.96M
    }
6175
1.96M
    pdevproto->initialize_device_procs((gx_device *)pdevproto);
6176
1.96M
    pdevproto->blend_cs_state = blend_cs_state;
6177
1.96M
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
6178
1.96M
    return 0;
6179
1.96M
}
6180
6181
/* When playing back the clist, we need to know if the buffer device is compatible */
6182
/* with the pdf14 compositor that was used when writing the clist. Colorspace and  */
6183
/* depth are critical since these must match when reading back colors.             */
6184
bool
6185
pdf14_ok_to_optimize(gx_device *dev)
6186
3.40M
{
6187
3.40M
    pdf14_blend_cs_t blend_cs_state;
6188
3.40M
    pdf14_default_colorspace_t pdf14_cs =
6189
3.40M
        pdf14_determine_default_blend_cs(dev, false, &blend_cs_state);
6190
3.40M
    gsicc_colorbuffer_t dev_icc_cs;
6191
3.40M
    bool ok = false;
6192
3.40M
    int tag_depth = device_encodes_tags(dev) ? 8 : 0;
6193
3.40M
    cmm_dev_profile_t *dev_profile;
6194
3.40M
    int code = dev_proc(dev, get_profile)(dev,  &dev_profile);
6195
3.40M
    bool deep = device_is_deep(dev);
6196
6197
3.40M
    if (code < 0)
6198
0
        return false;
6199
6200
3.40M
    check_device_compatible_encoding(dev);
6201
6202
3.40M
    if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN_STANDARD)
6203
1.27M
        return false;
6204
6205
2.13M
    dev_icc_cs = dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->data_cs;
6206
    /* If the outputprofile is not "standard" then colors converted to device color */
6207
    /* during clist writing won't match the colors written for the pdf14 clist dev  */
6208
2.13M
    if (!(dev_icc_cs == gsGRAY || dev_icc_cs == gsRGB || dev_icc_cs == gsCMYK))
6209
0
        return false;                           /* can't handle funky output profiles */
6210
6211
2.13M
    switch (pdf14_cs) {
6212
516k
        case PDF14_DeviceGray:
6213
516k
            ok = dev->color_info.max_gray == (deep ? 65535 : 255) && dev->color_info.depth == (8<<deep) + tag_depth;
6214
516k
            break;
6215
1.39M
        case PDF14_DeviceRGB:
6216
1.39M
            ok = dev->color_info.max_color == (deep ? 65535: 255) && dev->color_info.depth == (24<<deep) + tag_depth;
6217
1.39M
            break;
6218
0
        case PDF14_DeviceCMYK:
6219
0
            ok = dev->color_info.max_color == (deep ? 65535 : 255) && dev->color_info.depth == (32<<deep) + tag_depth;
6220
0
            break;
6221
219k
        case PDF14_DeviceCMYKspot:
6222
219k
            ok = false;     /* punt for this case */
6223
219k
            break;
6224
0
        case PDF14_DeviceRGBspot:
6225
0
            ok = false;     /* punt for this case */
6226
0
            break;
6227
0
        case PDF14_DeviceCustom:
6228
            /*
6229
             * We are using the output device's process color model.  The
6230
             * color_info for the PDF 1.4 compositing device needs to match
6231
             * the output device, but it may not have been contone.
6232
             */
6233
0
            ok = dev->color_info.depth == dev->color_info.num_components * (8<<deep) + tag_depth;
6234
0
            break;
6235
0
        default:      /* Should not occur */
6236
0
            ok = false;
6237
2.13M
    }
6238
2.13M
    return ok;
6239
2.13M
}
6240
6241
/*
6242
 * Recreate the PDF 1.4 compositor device.  Once created, the PDF 1.4
6243
 * compositor device is never removed.  (We do not have a remove compositor
6244
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
6245
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
6246
 * again.
6247
 */
6248
static  int
6249
pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs,
6250
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
6251
0
{
6252
0
    pdf14_device * pdev = (pdf14_device *)dev;
6253
0
    gx_device * target = pdev->target;
6254
0
    pdf14_device dev_proto;
6255
0
    bool has_tags = device_encodes_tags(dev);
6256
0
    int code;
6257
0
    bool deep = device_is_deep(dev);
6258
6259
0
    if_debug0m('v', dev->memory, "[v]pdf14_recreate_device\n");
6260
6261
    /*
6262
     * We will not use the entire prototype device but we will set the
6263
     * color related info and the device procs to match the prototype.
6264
     */
6265
0
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
6266
0
                                  pdf14pct, false);
6267
0
    if (code < 0)
6268
0
        return code;
6269
0
    pdev->color_info = dev_proto.color_info;
6270
0
    pdev->pad = target->pad;
6271
0
    pdev->log2_align_mod = target->log2_align_mod;
6272
6273
    /* The prototype has the color setup without tags. If we are
6274
     * using tags, then we need to extend num_components and depth.
6275
     */
6276
0
    if (has_tags) {
6277
0
        pdev->color_info.num_components++;
6278
0
        pdev->color_info.depth = pdev->color_info.num_components * (deep ? 16 : 8);
6279
0
    }
6280
6281
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
6282
0
        pdev->num_planar_planes = dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
6283
0
    else
6284
0
        pdev->num_planar_planes = target->num_planar_planes;
6285
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
6286
6287
0
    if (dev_proto.initialize_device_procs != NULL)
6288
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
6289
0
    pdev->procs = dev_proto.procs;
6290
0
    if (deep) {
6291
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
6292
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
6293
0
    }
6294
0
    if (has_tags) {
6295
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
6296
0
    }
6297
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
6298
0
    gx_device_fill_in_procs((gx_device *)pdev);
6299
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
6300
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
6301
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
6302
0
    check_device_separable(dev);
6303
0
    return dev_proc(pdev, open_device)(dev);
6304
0
}
6305
6306
/*
6307
 * Implement the various operations that can be specified via the PDF 1.4
6308
 * create compositor request.
6309
 */
6310
static  int
6311
gx_update_pdf14_compositor(gx_device * pdev, gs_gstate * pgs,
6312
    const gs_pdf14trans_t * pdf14pct, gs_memory_t * mem )
6313
48.2M
{
6314
48.2M
    pdf14_device *p14dev = (pdf14_device *)pdev;
6315
48.2M
    gs_pdf14trans_params_t params = pdf14pct->params;
6316
48.2M
    int code = 0;
6317
6318
48.2M
    params.idle = pdf14pct->idle;
6319
48.2M
    switch (params.pdf14_op) {
6320
0
        default:      /* Should not occur. */
6321
0
            break;
6322
23.0k
        case PDF14_PUSH_DEVICE:
6323
23.0k
            if (!(params.is_pattern)) {
6324
0
                p14dev->blend_mode = 0;
6325
0
                p14dev->opacity = p14dev->shape = 0.0;
6326
0
                pdf14_recreate_device(mem, pgs, pdev, pdf14pct);
6327
0
            }
6328
23.0k
            break;
6329
0
        case PDF14_ABORT_DEVICE:
6330
            /* Something has gone very wrong.  Let transparency device clean up
6331
               what ever it has allocated and then we are shutting it down */
6332
0
            code = gx_abort_trans_device(pgs, pdev);
6333
0
            if (p14dev->free_devicen) {
6334
0
                devn_free_params(pdev);
6335
0
            }
6336
0
            pdf14_disable_device(pdev);
6337
0
            pdf14_close(pdev);
6338
0
            break;
6339
1.95M
        case PDF14_POP_DEVICE:
6340
1.95M
            if (!(params.is_pattern)) {
6341
1.93M
                if_debug0m('v', pdev->memory,
6342
1.93M
                           "[v]gx_update_pdf14_compositor(PDF14_POP_DEVICE)\n");
6343
1.93M
                pgs->get_cmap_procs = p14dev->save_get_cmap_procs;
6344
1.93M
                gx_set_cmap_procs(pgs, p14dev->target);
6345
                /* Send image out raster data to output device */
6346
1.93M
                {
6347
                    /* Make a copy so we can change the ROP */
6348
1.93M
                    gs_gstate new_pgs = *pgs;
6349
6350
                    /* We don't use the gs_gstate log_op since this is for the */
6351
                    /* clist playback. Putting the image (band in the case of the */
6352
                    /* clist) only needs to use the default ROP to copy the data  */
6353
1.93M
                    new_pgs.log_op = rop3_default;
6354
1.93M
                    code = p14dev->pdf14_procs->put_image(pdev, &new_pgs, p14dev->target);
6355
1.93M
                }
6356
                /* Before we disable the device release any deviceN structures.
6357
                    free_devicen is set if the pdf14 device had inherited its
6358
                    deviceN parameters from the target clist device.  In this
6359
                    case they should not be freed */
6360
1.93M
                if (p14dev->free_devicen) {
6361
1.92M
                    gs_devn_params *devn_params = dev_proc(pdev, ret_devn_params)(pdev);
6362
1.92M
                    if (devn_params) {
6363
1.92M
                        gxdso_spot_info si;
6364
1.92M
                        si.params = devn_params;
6365
1.92M
                        si.equiv = &p14dev->op_pequiv_cmyk_colors;
6366
1.92M
                        (void)dev_proc(p14dev->target, dev_spec_op)(p14dev->target, gxdso_update_spots, &si, sizeof(si));
6367
1.92M
                    }
6368
1.92M
                    devn_free_params(pdev);
6369
1.92M
                }
6370
1.93M
                pdf14_disable_device(pdev);
6371
1.93M
                pdf14_close(pdev);
6372
1.93M
            }
6373
1.95M
            break;
6374
886k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
6375
4.94M
        case PDF14_BEGIN_TRANS_GROUP:
6376
4.94M
            if (p14dev->smask_constructed || p14dev->depth_within_smask)
6377
730k
                p14dev->depth_within_smask++;
6378
4.94M
            p14dev->smask_constructed = 0;
6379
4.94M
            code = gx_begin_transparency_group(pgs, pdev, &params);
6380
4.94M
            break;
6381
4.20M
        case PDF14_END_TRANS_GROUP:
6382
4.20M
            code = gx_end_transparency_group(pgs, pdev);
6383
4.20M
            if (p14dev->depth_within_smask)
6384
729k
                p14dev->depth_within_smask--;
6385
4.20M
            break;
6386
393
        case PDF14_BEGIN_TRANS_TEXT_GROUP:
6387
393
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
6388
0
                p14dev->text_group = PDF14_TEXTGROUP_MISSING_ET;
6389
0
                emprintf(p14dev->memory, "Warning: Text group pushed but no ET found\n");
6390
0
            } else
6391
393
                p14dev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6392
393
            break;
6393
735k
        case PDF14_END_TRANS_TEXT_GROUP:
6394
735k
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED)
6395
734k
                code = gx_end_transparency_group(pgs, pdev);
6396
735k
            p14dev->text_group = PDF14_TEXTGROUP_NO_BT; /* Hit ET */
6397
735k
            break;
6398
8.73M
        case PDF14_BEGIN_TRANS_MASK:
6399
8.73M
            code = gx_begin_transparency_mask(pgs, pdev, &params);
6400
8.73M
            if (code >= 0 && params.subtype != TRANSPARENCY_MASK_None)
6401
1.01M
                p14dev->in_smask_construction++;
6402
8.73M
            break;
6403
1.01M
        case PDF14_END_TRANS_MASK:
6404
1.01M
            code = gx_end_transparency_mask(pgs, pdev, &params);
6405
1.01M
            if (code >= 0) {
6406
1.01M
                p14dev->in_smask_construction--;
6407
1.01M
                if (p14dev->in_smask_construction < 0)
6408
0
                    p14dev->in_smask_construction = 0;
6409
1.01M
                if (p14dev->in_smask_construction == 0)
6410
1.01M
                    p14dev->smask_constructed = 1;
6411
1.01M
            }
6412
1.01M
            break;
6413
20.9M
        case PDF14_SET_BLEND_PARAMS:
6414
20.9M
            pdf14_set_params(pgs, pdev, &pdf14pct->params);
6415
20.9M
            break;
6416
0
        case PDF14_PUSH_TRANS_STATE:
6417
0
            code = gx_push_transparency_state(pgs, pdev);
6418
0
            break;
6419
5.66M
        case PDF14_POP_TRANS_STATE:
6420
5.66M
            code = gx_pop_transparency_state(pgs, pdev);
6421
5.66M
            break;
6422
17.5k
        case PDF14_PUSH_SMASK_COLOR:
6423
17.5k
            code = pdf14_increment_smask_color(pgs, pdev);
6424
17.5k
            break;
6425
17.5k
        case PDF14_POP_SMASK_COLOR:
6426
17.5k
            code = pdf14_decrement_smask_color(pgs, pdev);
6427
17.5k
            break;
6428
48.2M
    }
6429
48.2M
    return code;
6430
48.2M
}
6431
6432
/*
6433
 * The PDF 1.4 compositor is never removed.  (We do not have a 'remove
6434
 * compositor' method.  However the compositor is disabled when we are not
6435
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
6436
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
6437
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
6438
 * to the target.
6439
 */
6440
static  int
6441
pdf14_forward_composite(gx_device * dev, gx_device * * pcdev,
6442
        const gs_composite_t * pct, gs_gstate * pgs,
6443
        gs_memory_t * mem, gx_device *cdev)
6444
2.36k
{
6445
2.36k
    pdf14_device *pdev = (pdf14_device *)dev;
6446
2.36k
    gx_device * tdev = pdev->target;
6447
2.36k
    int code;
6448
6449
2.36k
    *pcdev = dev;
6450
2.36k
    if (gs_is_pdf14trans_compositor(pct)) {
6451
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6452
6453
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
6454
0
            return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6455
0
        return 0;
6456
0
    }
6457
2.36k
    code = dev_proc(tdev, composite)(tdev, pcdev, pct, pgs, mem, cdev);
6458
2.36k
    if (code == 1) {
6459
        /* We have created a new compositor that wrapped tdev. This means
6460
         * that our target should be updated to point to that. */
6461
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
6462
0
        code = 0; /* We have not created a new compositor that wrapped dev. */
6463
0
    }
6464
2.36k
    return code;
6465
2.36k
}
6466
6467
/*
6468
 * The PDF 1.4 compositor can be handled directly, so just set *pcdev = dev
6469
 * and return. Since the gs_pdf14_device only supports the high-level routines
6470
 * of the interface, don't bother trying to handle any other compositor.
6471
 */
6472
static int
6473
pdf14_composite(gx_device * dev, gx_device * * pcdev,
6474
        const gs_composite_t * pct, gs_gstate * pgs,
6475
        gs_memory_t * mem, gx_device *cdev)
6476
306M
{
6477
306M
    pdf14_device *p14dev = (pdf14_device *)dev;
6478
306M
    if (gs_is_pdf14trans_compositor(pct)) {
6479
48.2M
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6480
48.2M
        *pcdev = dev;
6481
        /* cdev, may be the clist reader device which may contain information that
6482
           we will need related to the ICC color spaces that define transparency
6483
           groups.  We want this propogated through all the pdf14 functions.  Store
6484
           a pointer to it in the pdf14 device */
6485
48.2M
        p14dev->pclist_device = cdev;
6486
48.2M
        return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6487
258M
    } else if (gs_is_overprint_compositor(pct)) {
6488
                /* If we had an overprint compositer action, then the
6489
                   color components that were drawn should be updated.
6490
                   The overprint compositor logic and its interactions
6491
                   with the clist is a little odd as it passes uninitialized
6492
                   values around a fair amount.  Hence the forced assignement here.
6493
                   See gx_spot_colors_set_overprint in gscspace for issues... */
6494
258M
                const gs_overprint_t * op_pct = (const gs_overprint_t *) pct;
6495
258M
                gx_color_index drawn_comps;
6496
258M
                PDF14_OP_FS_STATE curr_state = p14dev->op_state;
6497
6498
258M
                p14dev->op_state = op_pct->params.op_state;
6499
258M
                if (p14dev->op_state == PDF14_OP_STATE_NONE) {
6500
129M
                    if (op_pct->params.retain_any_comps) {
6501
827k
                        drawn_comps = op_pct->params.drawn_comps;
6502
128M
                    } else {
6503
                        /* Draw everything. If this parameter was not set, clist does
6504
                           not fill it in.  */
6505
128M
                        drawn_comps = ((gx_color_index)1 << (p14dev->color_info.num_components)) - (gx_color_index)1;
6506
128M
                    }
6507
6508
129M
                    if (op_pct->params.is_fill_color) {
6509
75.7M
                        p14dev->effective_overprint_mode = op_pct->params.effective_opm;
6510
75.7M
                        p14dev->drawn_comps_fill = drawn_comps;
6511
75.7M
                    } else {
6512
53.5M
                        p14dev->stroke_effective_op_mode = op_pct->params.effective_opm;
6513
53.5M
                        p14dev->drawn_comps_stroke = drawn_comps;
6514
53.5M
                    }
6515
                    /* We restore the NONE states as that is used just to force
6516
                       overprint settings in the overprint compositor communication */
6517
129M
                    p14dev->op_state = curr_state;
6518
129M
                }
6519
258M
                *pcdev = dev;
6520
258M
                return 0;
6521
258M
    } else
6522
0
        return gx_no_composite(dev, pcdev, pct, pgs, mem, cdev);
6523
306M
}
6524
6525
static int
6526
pdf14_push_text_group(gx_device *dev, gs_gstate *pgs,
6527
                      gs_blend_mode_t blend_mode, float opacity,
6528
                      float shape, bool is_clist)
6529
4.12k
{
6530
4.12k
    int code;
6531
4.12k
    gs_transparency_group_params_t params = { 0 };
6532
4.12k
    gs_rect bbox = { 0 }; /* Bounding box is set by parent */
6533
4.12k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
6534
4.12k
    float alpha = pgs->fillconstantalpha;
6535
6536
    /* Push a non-isolated knock-out group making sure the opacity and blend
6537
       mode are correct */
6538
4.12k
    params.Isolated = false;
6539
4.12k
    params.Knockout = true;
6540
4.12k
    params.page_group = false;
6541
4.12k
    params.text_group = PDF14_TEXTGROUP_BT_PUSHED;
6542
4.12k
    params.group_opacity = 1.0;
6543
4.12k
    params.group_shape = 1.0;
6544
6545
4.12k
    gs_setfillconstantalpha(pgs, 1.0);
6546
4.12k
    gs_setblendmode(pgs, BLEND_MODE_Normal);
6547
6548
4.12k
    if (is_clist) {
6549
4.12k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6550
4.12k
        if (code < 0)
6551
0
            return code;
6552
4.12k
    }
6553
6554
4.12k
    code = gs_begin_transparency_group(pgs, &params, &bbox, PDF14_BEGIN_TRANS_GROUP);
6555
4.12k
    gs_setfillconstantalpha(pgs, alpha);
6556
4.12k
    gs_setblendmode(pgs, blend_mode);
6557
4.12k
    if (code < 0)
6558
0
        return code;
6559
6560
4.12k
    if (is_clist) {
6561
4.12k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6562
4.12k
    }
6563
4.12k
    return code;
6564
4.12k
}
6565
6566
static  int
6567
pdf14_text_begin(gx_device * dev, gs_gstate * pgs,
6568
                 const gs_text_params_t * text, gs_font * font,
6569
                 const gx_clip_path * pcpath,
6570
                 gs_text_enum_t ** ppenum)
6571
598
{
6572
598
    int code;
6573
598
    gs_text_enum_t *penum;
6574
598
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
6575
598
    float opacity = pgs->fillconstantalpha;
6576
598
    float shape = 1.0;
6577
598
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
6578
598
    pdf14_device *pdev = (pdf14_device*)dev;
6579
598
    bool draw = !(text->operation & TEXT_DO_NONE);
6580
598
    uint text_mode = gs_currenttextrenderingmode(pgs);
6581
598
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
6582
598
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
6583
6584
598
    code = pdf14_initialize_ctx(dev, pgs);
6585
598
    if (code < 0)
6586
0
        return code;
6587
6588
598
    if_debug0m('v', pgs->memory, "[v]pdf14_text_begin\n");
6589
598
    pdf14_set_marking_params(dev, pgs);
6590
598
    code = gx_default_text_begin(dev, pgs, text, font, pcpath, &penum);
6591
598
    if (code < 0)
6592
0
        return code;
6593
6594
    /* We may need to push a non-isolated transparency group if the following
6595
       is true.
6596
       1) We are not currently in one that we pushed for text and we are in
6597
          a BT/ET pair.  This is determined by looking at the pdf14 text_group.
6598
       2) The blend mode is not Normal or the opacity is not 1.0
6599
       3) Text knockout is set to true
6600
       4) We are actually doing a text drawing
6601
6602
       Special note:  If text-knockout is set to false while we are within a
6603
       BT ET pair, we should pop the group.  I need to create a test file for
6604
       this case.  */
6605
6606
       /* Catch case where we already pushed a group and are trying to push another one.
6607
       In that case, we will pop the current one first, as we don't want to be left
6608
       with it. Note that if we have a BT and no other BTs or ETs then this issue
6609
       will not be caught until we do the put_image and notice that the stack is not
6610
       empty. */
6611
598
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
6612
0
        code = gs_end_transparency_group(pgs);
6613
0
        if (code < 0)
6614
0
            return code;
6615
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6616
0
    }
6617
6618
598
    if (gs_currenttextknockout(pgs) && (blend_issue ||
6619
597
         (pgs->fillconstantalpha != 1.0 && text_fill) ||
6620
597
         (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
6621
1
         text_mode != 3 && /* don't bother with invisible text */
6622
1
         pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED)
6623
1
        if (draw) {
6624
1
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape,
6625
1
                false);
6626
1
        }
6627
598
    *ppenum = (gs_text_enum_t *)penum;
6628
598
    return code;
6629
598
}
6630
6631
static  int
6632
pdf14_initialize_device(gx_device *new_dev)
6633
1.96M
{
6634
1.96M
    pdf14_device *pdev = (pdf14_device*)new_dev;
6635
6636
1.96M
    pdev->ctx = NULL;
6637
1.96M
    pdev->color_model_stack = NULL;
6638
1.96M
    pdev->smaskcolor = NULL;
6639
6640
1.96M
    return 0;
6641
1.96M
}
6642
6643
/*
6644
 * Implement copy_mono by filling lots of small rectangles.
6645
 */
6646
static int
6647
pdf14_copy_mono(gx_device * dev,
6648
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
6649
        int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
6650
29.5M
{
6651
29.5M
    const byte *sptr;
6652
29.5M
    const byte *line;
6653
29.5M
    int sbit, first_bit;
6654
29.5M
    int code, sbyte, bit, count;
6655
29.5M
    int run_length, startx, current_bit, bit_value;
6656
29.5M
    gx_color_index current_color;
6657
6658
29.5M
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
6659
29.5M
    line = base + (sourcex >> 3);
6660
29.5M
    sbit = sourcex & 7;
6661
29.5M
    first_bit = 7 - sbit;
6662
6663
    /* Loop through the height of the specified area. */
6664
221M
    while (h-- > 0) {
6665
        /* Set up for the start of each line of the area. */
6666
191M
        sptr = line;
6667
191M
        sbyte = *sptr++;
6668
        /* The +1 here is 'sacrificial', we are going to decrement it by 1 immediately in
6669
         * the loop below so adding 1 means that we don't fall into the bit == 0
6670
         * case and incorrectly read a new byte from the source. This weirdness is because
6671
         * the original code wouold read off the end of the buffer if the number of bits in
6672
         * the raster was an exact multiple of 8. If it was also a multiple of the word
6673
         * size we might read unallocated memory. Moving the 'sbyte = *sptr++' from the end
6674
         * of the loop to the beginning meant we would not read past the end of the buffer
6675
         * because we would drop out of the 'do ... while (count-- > 0)' loop before
6676
         * reading another byte.
6677
         */
6678
191M
        bit = first_bit + 1;
6679
191M
        count = w;
6680
191M
        run_length = 0;
6681
191M
        startx = x;
6682
191M
        current_bit = 0;
6683
191M
        current_color = zero;
6684
6685
        /* Loop across each pixel of a line. */
6686
2.60G
        do {
6687
            /* Move to the next input bit. */
6688
2.60G
            if (bit == 0) {
6689
223M
                bit = 7;
6690
223M
                sbyte = *sptr++;
6691
223M
            }
6692
2.37G
            else
6693
2.37G
                bit--;
6694
2.60G
            bit_value = (sbyte >> bit) & 1;
6695
2.60G
            if (bit_value == current_bit) {
6696
                /* The value did not change, simply increment our run length */
6697
2.13G
                run_length++;
6698
2.13G
            } else {
6699
                /* The value changed, fill the current rectangle. */
6700
472M
                if (run_length != 0) {
6701
451M
                    if (current_color != gx_no_color_index) {
6702
193M
                        code = (*dev_proc(dev, fill_rectangle))
6703
193M
                                (dev, startx, y, run_length, 1, current_color);
6704
193M
                        if (code < 0)
6705
0
                            return code;
6706
193M
                    }
6707
451M
                    startx += run_length;
6708
451M
                }
6709
472M
                run_length = 1;
6710
472M
                current_color = bit_value ? one : zero;
6711
472M
                current_bit = bit_value;
6712
472M
            }
6713
2.60G
        } while (--count > 0);
6714
        /* Fill the last rectangle in the line. */
6715
191M
        if (run_length != 0 && current_color != gx_no_color_index) {
6716
84.7M
            code = (*dev_proc(dev, fill_rectangle))
6717
84.7M
                        (dev, startx, y, run_length, 1, current_color);
6718
84.7M
            if (code < 0)
6719
0
                return code;
6720
84.7M
        }
6721
        /* Move to the next line */
6722
191M
        line += sraster;
6723
191M
        y++;
6724
191M
    }
6725
29.5M
    return 0;
6726
29.5M
}
6727
6728
/* Added to avoid having to go back and forth between fixed and int
6729
   in some of the internal methods used for dealing with tiling
6730
   and devn colors */
6731
static int
6732
pdf14_fill_rectangle_devn(gx_device *dev, int x, int y, int w, int h,
6733
    const gx_drawing_color *pdcolor)
6734
2.44k
{
6735
2.44k
    pdf14_device *pdev = (pdf14_device *)dev;
6736
2.44k
    pdf14_buf *buf;
6737
2.44k
    int code;
6738
6739
2.44k
    fit_fill_xywh(dev, x, y, w, h);
6740
2.44k
    if (w <= 0 || h <= 0)
6741
0
        return 0;
6742
6743
2.44k
    code = pdf14_initialize_ctx(dev, NULL);
6744
2.44k
    if (code < 0)
6745
0
        return code;
6746
2.44k
    buf = pdev->ctx->stack;
6747
6748
2.44k
    if (buf->knockout)
6749
0
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
6750
0
            true);
6751
2.44k
    else
6752
2.44k
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
6753
2.44k
}
6754
6755
/* Step through and do rect fills with the devn colors as
6756
   we hit each transition in the bitmap. It is possible
6757
   that one of the colors is not devn, but is pure and
6758
   is set to gx_no_color_index. This type of mix happens
6759
   for example from tile_clip_fill_rectangle_hl_color */
6760
static int
6761
pdf14_copy_mono_devn(gx_device *dev,
6762
    const byte *base, int sourcex, int sraster,
6763
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6764
    const gx_drawing_color *pdcolor1)
6765
668
{
6766
668
    const byte *sptr;
6767
668
    const byte *line;
6768
668
    int sbit, first_bit;
6769
668
    int code, sbyte, bit, count;
6770
668
    int run_length, startx, current_bit, bit_value;
6771
668
    const gx_drawing_color *current_color;
6772
6773
668
    if ((x | y) < 0) {
6774
0
        if (x < 0) {
6775
0
            w += x;
6776
0
            sourcex -= x;
6777
0
            x = 0;
6778
0
        }
6779
0
        if (y < 0) {
6780
0
            h += y;
6781
0
            base -= (int)(y * sraster);
6782
0
            y = 0;
6783
0
        }
6784
0
    }
6785
668
    if (w > (dev)->width - x)
6786
0
        w = (dev)->width - x;
6787
668
    if (h > (dev)->height - y)
6788
0
        h = (dev)->height - y;
6789
668
    if (w <= 0 || h <= 0)
6790
0
        return 0;
6791
6792
668
    line = base + (sourcex >> 3);
6793
668
    sbit = sourcex & 7;
6794
668
    first_bit = 7 - sbit;
6795
6796
    /* Loop through the height of the specified area. */
6797
2.10k
    while (h-- > 0) {
6798
        /* Set up for the start of each line of the area. */
6799
1.43k
        sptr = line;
6800
1.43k
        sbyte = *sptr++;
6801
1.43k
        bit = first_bit;
6802
1.43k
        count = w;
6803
1.43k
        run_length = 0;
6804
1.43k
        startx = x;
6805
1.43k
        current_bit = 0;
6806
1.43k
        current_color = pdcolor0;
6807
6808
        /* Loop across each pixel of a line. */
6809
15.6k
        do {
6810
15.6k
            bit_value = (sbyte >> bit) & 1;
6811
15.6k
            if (bit_value == current_bit) {
6812
                /* The value did not change, simply increment our run length */
6813
11.3k
                run_length++;
6814
11.3k
            } else {
6815
                /* The value changed, fill the current rectangle. */
6816
4.26k
                if (run_length != 0) {
6817
3.85k
                    if (current_color->type != gx_dc_type_pure &&
6818
1.82k
                        current_color->colors.pure != gx_no_color_index) {
6819
1.82k
                        code = pdf14_fill_rectangle_devn(dev, startx, y,
6820
1.82k
                            run_length, 1, current_color);
6821
1.82k
                        if (code < 0)
6822
0
                            return code;
6823
1.82k
                    }
6824
3.85k
                    startx += run_length;
6825
3.85k
                }
6826
4.26k
                run_length = 1;
6827
4.26k
                current_color = bit_value ? pdcolor1 : pdcolor0;
6828
4.26k
                current_bit = bit_value;
6829
4.26k
            }
6830
6831
            /* Move to the next input bit. */
6832
15.6k
            if (bit == 0) {
6833
1.40k
                bit = 7;
6834
1.40k
                sbyte = *sptr++;
6835
1.40k
            } else
6836
14.2k
                bit--;
6837
15.6k
        } while (--count > 0);
6838
6839
        /* Fill the last rectangle in the line. */
6840
1.43k
        if (run_length != 0 && current_color->type != gx_dc_type_pure &&
6841
619
            current_color->colors.pure != gx_no_color_index) {
6842
619
            code = pdf14_fill_rectangle_devn(dev, startx, y,
6843
619
                run_length, 1, current_color);
6844
619
            if (code < 0)
6845
0
                return code;
6846
619
        }
6847
        /* Move to the next line */
6848
1.43k
        line += sraster;
6849
1.43k
        y++;
6850
1.43k
    }
6851
668
    return 0;
6852
668
}
6853
6854
/* Step through the tiles doing essentially copy_mono but with devn colors */
6855
static int
6856
pdf14_impl_strip_tile_rectangle_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6857
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6858
    const gx_drawing_color *pdcolor1, int px, int py)
6859
668
{   /* Fill the rectangle in chunks. */
6860
668
    int width = tiles->size.x;
6861
668
    int height = tiles->size.y;
6862
668
    int raster = tiles->raster;
6863
668
    int rwidth = tiles->rep_width;
6864
668
    int rheight = tiles->rep_height;
6865
668
    int shift = tiles->shift;
6866
6867
668
    if (rwidth == 0 || rheight == 0)
6868
0
        return_error(gs_error_unregistered);
6869
668
    fit_fill_xy(dev, x, y, w, h);
6870
6871
668
     {
6872
668
        int xoff = (shift == 0 ? px :
6873
668
                px + (y + py) / rheight * tiles->rep_shift);
6874
668
        int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */
6875
0
            (x + xoff) & (rwidth - 1) :
6876
668
            (x + xoff) % rwidth);
6877
668
        int ry = ((rheight & (rheight - 1)) == 0 ? /* power of 2 */
6878
0
            (y + py) & (rheight - 1) :
6879
668
            (y + py) % rheight);
6880
668
        int icw = width - irx;
6881
668
        int ch = height - ry;
6882
668
        byte *row = tiles->data + ry * raster;
6883
668
        int code = 0;
6884
6885
668
        if (ch >= h) {      /* Shallow operation */
6886
668
            if (icw >= w) { /* Just one (partial) tile to transfer. */
6887
668
                code = pdf14_copy_mono_devn(dev, row, irx, raster, x, y,
6888
668
                    w, h, pdcolor0, pdcolor1);
6889
668
                if (code < 0)
6890
0
                    return_error(code);
6891
668
            } else {
6892
0
                int ex = x + w;
6893
0
                int fex = ex - width;
6894
0
                int cx = x + icw;
6895
6896
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6897
0
                    x, y, icw, h, pdcolor0, pdcolor1);
6898
0
                if (code < 0)
6899
0
                    return_error(code);
6900
6901
0
                while (cx <= fex) {
6902
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6903
0
                        width, h, pdcolor0, pdcolor1);
6904
0
                    if (code < 0)
6905
0
                        return_error(code);
6906
0
                    cx += width;
6907
0
                }
6908
0
                if (cx < ex) {
6909
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6910
0
                        ex - cx, h, pdcolor0, pdcolor1);
6911
0
                    if (code < 0)
6912
0
                        return_error(code);
6913
0
                }
6914
0
            }
6915
668
        } else if (icw >= w && shift == 0) {
6916
            /* Narrow operation, no shift */
6917
0
            int ey = y + h;
6918
0
            int fey = ey - height;
6919
0
            int cy = y + ch;
6920
6921
0
            code = pdf14_copy_mono_devn(dev, row, irx, raster,
6922
0
                x, y, w, ch, pdcolor0, pdcolor1);
6923
0
            if (code < 0)
6924
0
                return_error(code);
6925
0
            row = tiles->data;
6926
0
            do {
6927
0
                ch = (cy > fey ? ey - cy : height);
6928
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6929
0
                    x, cy, w, ch, pdcolor0, pdcolor1);
6930
0
                if (code < 0)
6931
0
                    return_error(code);
6932
0
            } while ((cy += ch) < ey);
6933
0
        } else {
6934
            /* Full operation.  If shift != 0, some scan lines */
6935
            /* may be narrow.  We could test shift == 0 in advance */
6936
            /* and use a slightly faster loop, but right now */
6937
            /* we don't bother. */
6938
0
            int ex = x + w, ey = y + h;
6939
0
            int fex = ex - width, fey = ey - height;
6940
0
            int cx, cy;
6941
6942
0
            for (cy = y;;) {
6943
0
                if (icw >= w) {
6944
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6945
0
                        x, cy, w, ch, pdcolor0, pdcolor1);
6946
0
                    if (code < 0)
6947
0
                        return_error(code);
6948
0
                } else {
6949
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6950
0
                        x, cy, icw, ch, pdcolor0, pdcolor1);
6951
0
                    if (code < 0)
6952
0
                        return_error(code);
6953
0
                    cx = x + icw;
6954
0
                    while (cx <= fex) {
6955
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6956
0
                            cx, cy, width, ch, pdcolor0, pdcolor1);
6957
0
                        if (code < 0)
6958
0
                            return_error(code);
6959
0
                        cx += width;
6960
0
                    }
6961
0
                    if (cx < ex) {
6962
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6963
0
                            cx, cy, ex - cx, ch, pdcolor0, pdcolor1);
6964
0
                        if (code < 0)
6965
0
                            return_error(code);
6966
0
                    }
6967
0
                }
6968
0
                if ((cy += ch) >= ey)
6969
0
                    break;
6970
0
                ch = (cy > fey ? ey - cy : height);
6971
0
                if ((irx += shift) >= rwidth)
6972
0
                    irx -= rwidth;
6973
0
                icw = width - irx;
6974
0
                row = tiles->data;
6975
0
            }
6976
0
        }
6977
668
    }
6978
668
    return 0;
6979
668
}
6980
6981
/* pdf14 device supports devn */
6982
static int
6983
pdf14_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6984
    int x, int y, int w, int h,
6985
    const gx_drawing_color *pdcolor0,
6986
    const gx_drawing_color *pdcolor1, int px, int py)
6987
668
{
6988
668
    pdf14_device *pdev = (pdf14_device *)dev;
6989
668
    pdf14_buf *buf;
6990
668
    int num_comp;
6991
668
    int k;
6992
668
    bool same = false;
6993
668
    int code;
6994
6995
668
    code = pdf14_initialize_ctx(dev, NULL);
6996
668
    if (code < 0)
6997
0
        return code;
6998
668
    buf = pdev->ctx->stack;
6999
668
    num_comp = buf->n_chan - 1;
7000
7001
    /* if color0 is identical to color1, do rect fill */
7002
668
    if (pdcolor0->type == gx_dc_type_devn && pdcolor1->type == gx_dc_type_devn) {
7003
0
        same = true;
7004
0
        for (k = 0; k < num_comp; k++) {
7005
0
            if (pdcolor0->colors.devn.values[k] != pdcolor1->colors.devn.values[k]) {
7006
0
                same = false;
7007
0
                break;
7008
0
            }
7009
0
        }
7010
0
    }
7011
7012
668
    if (same) {
7013
0
        code = pdf14_fill_rectangle_devn(dev, x, y, w, h, pdcolor0);
7014
668
    } else {
7015
        /* Go through the tile stepping using code stolen from
7016
           gx_default_strip_tile_rectangle and call the rect fills
7017
           using code stolen from pdf14_copy_mono but using devn
7018
           colors */
7019
668
        code = pdf14_impl_strip_tile_rectangle_devn(dev, tiles,
7020
668
            x, y, w, h, pdcolor0, pdcolor1, px, py);
7021
668
    }
7022
668
    return code;
7023
668
}
7024
7025
/* Used in a few odd cases where the target device is planar and we have
7026
   a planar tile (pattern) and we are copying it into place here */
7027
static int
7028
pdf14_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
7029
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
7030
4.62k
{
7031
4.62k
    pdf14_device *pdev = (pdf14_device *)dev;
7032
4.62k
    pdf14_ctx *ctx;
7033
4.62k
    pdf14_buf *buf;
7034
4.62k
    int xo = x;
7035
4.62k
    int yo = y;
7036
4.62k
    pdf14_buf fake_tos;
7037
4.62k
    int deep;
7038
7039
4.62k
    int code = pdf14_initialize_ctx(dev, NULL);
7040
4.62k
    if (code < 0)
7041
0
        return code;
7042
7043
4.62k
    fit_fill_xywh(dev, x, y, w, h);
7044
4.62k
    if (w <= 0 || h <= 0)
7045
0
        return 0;
7046
7047
4.62k
    ctx = pdev->ctx;
7048
4.62k
    buf = ctx->stack;
7049
4.62k
    deep = ctx->deep;
7050
7051
4.62k
    fake_tos.deep = deep;
7052
4.62k
    fake_tos.alpha = (uint16_t)(0xffff * pdev->alpha + 0.5);
7053
4.62k
    fake_tos.backdrop = NULL;
7054
4.62k
    fake_tos.blend_mode = pdev->blend_mode;
7055
4.62k
    fake_tos.color_space = buf->color_space;
7056
4.62k
    fake_tos.data = (byte *)data + ((data_x - (x - xo))<<deep) - (y - yo) * raster; /* Nasty, cast away of const */
7057
4.62k
    fake_tos.dirty.p.x = x;
7058
4.62k
    fake_tos.dirty.p.y = y;
7059
4.62k
    fake_tos.dirty.q.x = x + w;
7060
4.62k
    fake_tos.dirty.q.y = y + h;
7061
4.62k
    fake_tos.has_alpha_g = 0;
7062
4.62k
    fake_tos.has_shape = 0;
7063
4.62k
    fake_tos.has_tags = 0;
7064
4.62k
    fake_tos.idle = false;
7065
4.62k
    fake_tos.isolated = false;
7066
4.62k
    fake_tos.knockout = false;
7067
4.62k
    fake_tos.mask_id = 0;
7068
4.62k
    fake_tos.mask_stack = NULL;
7069
4.62k
    fake_tos.matte = NULL;
7070
4.62k
    fake_tos.matte_num_comps = 0;
7071
4.62k
    fake_tos.memory = dev->memory;
7072
4.62k
    fake_tos.n_chan = dev->color_info.num_components;
7073
4.62k
    fake_tos.n_planes = dev->color_info.num_components;
7074
4.62k
    fake_tos.num_spots = 0;
7075
4.62k
    fake_tos.group_color_info = NULL;
7076
4.62k
    fake_tos.planestride = raster * (size_t)plane_height;
7077
4.62k
    fake_tos.rect.p.x = x;
7078
4.62k
    fake_tos.rect.p.y = y;
7079
4.62k
    fake_tos.rect.q.x = x + w;
7080
4.62k
    fake_tos.rect.q.y = y + h;
7081
4.62k
    fake_tos.rowstride = raster;
7082
4.62k
    fake_tos.saved = NULL;
7083
4.62k
    fake_tos.shape = 0xffff;
7084
4.62k
    fake_tos.SMask_SubType = TRANSPARENCY_MASK_Alpha;
7085
4.62k
    fake_tos.transfer_fn = NULL;
7086
4.62k
    pdf14_compose_alphaless_group(&fake_tos, buf, x, x+w, y, y+h,
7087
4.62k
                                  pdev->ctx->memory, dev);
7088
4.62k
    return 0;
7089
4.62k
}
7090
7091
static int
7092
pdf14_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
7093
    const gs_gstate *pgs, const gx_drawing_color *pdcolor,
7094
    const gx_clip_path *pcpath)
7095
47.8M
{
7096
47.8M
    pdf14_device *pdev = (pdf14_device *)dev;
7097
47.8M
    pdf14_buf* buf;
7098
47.8M
    int code;
7099
47.8M
    int x = fixed2int(rect->p.x);
7100
47.8M
    int y = fixed2int(rect->p.y);
7101
47.8M
    int w = fixed2int(rect->q.x) - x;
7102
47.8M
    int h = fixed2int(rect->q.y) - y;
7103
7104
47.8M
    fit_fill_xywh(dev, x, y, w, h);
7105
47.8M
    if (w <= 0 || h <= 0)
7106
1.43M
        return 0;
7107
7108
46.3M
    code = pdf14_initialize_ctx(dev, pgs);
7109
46.3M
    if (code < 0)
7110
0
        return code;
7111
46.3M
    buf = pdev->ctx->stack;
7112
7113
46.3M
    if (buf->knockout)
7114
709k
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
7115
709k
                                                   true);
7116
45.6M
    else
7117
45.6M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
7118
46.3M
}
7119
7120
static  int
7121
pdf14_fill_rectangle(gx_device * dev,
7122
                    int x, int y, int w, int h, gx_color_index color)
7123
932M
{
7124
932M
    pdf14_device *pdev = (pdf14_device *)dev;
7125
932M
    pdf14_buf *buf;
7126
932M
    int code;
7127
7128
932M
    fit_fill_xywh(dev, x, y, w, h);
7129
932M
    if (w <= 0 || h <= 0)
7130
31.6M
        return 0;
7131
7132
900M
    code = pdf14_initialize_ctx(dev, NULL);
7133
900M
    if (code < 0)
7134
0
        return code;
7135
7136
900M
    buf = pdev->ctx->stack;
7137
7138
900M
    if (buf->knockout)
7139
4.95M
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, NULL,
7140
4.95M
                                                   false);
7141
895M
    else
7142
895M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, color, NULL, false);
7143
900M
}
7144
7145
static int
7146
pdf14_compute_group_device_int_rect(const gs_matrix *ctm,
7147
                                    const gs_rect *pbbox, gs_int_rect *rect)
7148
5.38M
{
7149
5.38M
    gs_rect dev_bbox;
7150
5.38M
    int code;
7151
7152
5.38M
    code = gs_bbox_transform(pbbox, ctm, &dev_bbox);
7153
5.38M
    if (code < 0)
7154
0
        return code;
7155
5.38M
    rect->p.x = (int)floor(dev_bbox.p.x);
7156
5.38M
    rect->p.y = (int)floor(dev_bbox.p.y);
7157
5.38M
    rect->q.x = (int)ceil(dev_bbox.q.x);
7158
5.38M
    rect->q.y = (int)ceil(dev_bbox.q.y);
7159
    /* Sanity check rect for insane ctms */
7160
5.38M
    if (rect->p.x < 0)
7161
1.26M
        rect->p.x = 0;
7162
5.38M
    if (rect->q.x < rect->p.x)
7163
4.97k
        rect->q.x = rect->p.x;
7164
5.38M
    if (rect->p.y < 0)
7165
4.92M
        rect->p.y = 0;
7166
5.38M
    if (rect->q.y < rect->p.y)
7167
182k
        rect->q.y = rect->p.y;
7168
5.38M
    return 0;
7169
5.38M
}
7170
7171
static  int
7172
compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
7173
                              const gs_rect *pbbox, gs_gstate *pgs)
7174
5.22M
{
7175
5.22M
    int code = pdf14_compute_group_device_int_rect(&ctm_only(pgs), pbbox, rect);
7176
7177
5.22M
    if (code < 0)
7178
0
        return code;
7179
5.22M
    rect_intersect(*rect, pdev->ctx->rect);
7180
    /* Make sure the rectangle is not anomalous (q < p) -- see gsrect.h */
7181
5.22M
    if (rect->q.x < rect->p.x)
7182
19.7k
        rect->q.x = rect->p.x;
7183
5.22M
    if (rect->q.y < rect->p.y)
7184
141k
        rect->q.y = rect->p.y;
7185
5.22M
    return 0;
7186
5.22M
}
7187
7188
static  int
7189
pdf14_begin_transparency_group(gx_device* dev,
7190
    const gs_transparency_group_params_t* ptgp,
7191
    const gs_rect* pbbox,
7192
    gs_gstate* pgs, gs_memory_t* mem)
7193
4.94M
{
7194
4.94M
    pdf14_device* pdev = (pdf14_device*)dev;
7195
4.94M
    float alpha = ptgp->group_opacity * ptgp->group_shape;
7196
4.94M
    gs_int_rect rect;
7197
4.94M
    int code;
7198
4.94M
    bool isolated = ptgp->Isolated;
7199
4.94M
    gs_transparency_color_t group_color_type;
7200
4.94M
    cmm_profile_t* group_profile;
7201
4.94M
    cmm_profile_t* tos_profile;
7202
4.94M
    gsicc_rendering_param_t render_cond;
7203
4.94M
    cmm_dev_profile_t* dev_profile;
7204
4.94M
    bool cm_back_drop = false;
7205
4.94M
    bool new_icc = false;
7206
4.94M
    pdf14_group_color_t* group_color_info;
7207
4.94M
    bool has_tags = device_encodes_tags(dev);
7208
7209
4.94M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7210
4.94M
    if (code < 0)
7211
0
        return code;
7212
4.94M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &tos_profile, &render_cond);
7213
7214
4.94M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
7215
735k
        pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* For immediate mode and clist reading */
7216
735k
    }
7217
7218
4.94M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED)
7219
735k
        rect = pdev->ctx->rect; /* Use parent group for text_group. */
7220
4.20M
    else
7221
4.20M
        code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7222
7223
4.94M
    if (code < 0)
7224
0
        return code;
7225
4.94M
    if_debug5m('v', pdev->memory,
7226
4.94M
        "[v]pdf14_begin_transparency_group, I = %d, K = %d, alpha = %g, bm = %d page_group = %d\n",
7227
4.94M
        ptgp->Isolated, ptgp->Knockout, (double)alpha, pgs->blend_mode, ptgp->page_group);
7228
7229
    /* If the group color is unknown then use the current device profile. */
7230
4.94M
    if (ptgp->group_color_type == UNKNOWN) {
7231
4.02M
        group_color_type = ICC;
7232
4.02M
        group_profile = tos_profile;
7233
4.02M
    }
7234
919k
    else {
7235
919k
        group_color_type = ptgp->group_color_type;
7236
919k
        group_profile = ptgp->iccprofile;
7237
919k
    }
7238
7239
    /* We have to handle case where the profile is in the clist */
7240
4.94M
    if (group_profile == NULL && pdev->pclist_device != NULL) {
7241
        /* Get the serialized data from the clist. */
7242
919k
        gx_device_clist_reader* pcrdev = (gx_device_clist_reader*)(pdev->pclist_device);
7243
919k
        group_profile = gsicc_read_serial_icc((gx_device*)pcrdev, ptgp->icc_hashcode);
7244
919k
        if (group_profile == NULL)
7245
0
            return gs_throw(gs_error_unknownerror, "ICC data not found in clist");
7246
        /* Keep a pointer to the clist device */
7247
919k
        group_profile->dev = (gx_device*)pcrdev;
7248
919k
        new_icc = true;
7249
919k
    }
7250
4.94M
    if (group_profile != NULL) {
7251
        /* If we have a non-isolated group and the color space is different,
7252
            we will need to CM the backdrop. */
7253
4.94M
        if (!gsicc_profiles_equal(group_profile, tos_profile)) {
7254
354k
            cm_back_drop = true;
7255
354k
        }
7256
4.94M
    }
7257
7258
    /* Always create the base color group information as it is only through
7259
       groups that we can have a color space change.  This will survive
7260
       the life of the context. */
7261
4.94M
    if (pdev->ctx->base_color == NULL) {
7262
1.13M
        pdev->ctx->base_color = pdf14_make_base_group_color(dev);
7263
1.13M
    }
7264
7265
    /* If this is not the page group and we don't yet have a group, we need
7266
       to create a buffer for the whole page so that we can handle stuff drawn
7267
       outside this current group (e.g. two non inclusive groups drawn independently) */
7268
4.94M
    if (pdev->ctx->stack == NULL && !ptgp->page_group) {
7269
86.0k
        code = pdf14_initialize_ctx(dev, NULL);
7270
86.0k
        if (code < 0)
7271
0
            return code;
7272
86.0k
        pdev->ctx->stack->isolated = true;
7273
86.0k
    }
7274
7275
4.94M
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptgp->icc_hashcode,
7276
4.94M
        group_profile, false);
7277
4.94M
    if (group_color_info == NULL)
7278
0
        return gs_error_VMerror;
7279
4.94M
    if_debug0m('v', dev->memory, "[v]Transparency group color space update\n");
7280
7281
4.94M
    code = pdf14_push_transparency_group(pdev->ctx, &rect, isolated, ptgp->Knockout,
7282
4.94M
                                        (uint16_t)floor (65535 * alpha + 0.5),
7283
4.94M
                                        (uint16_t)floor(65535 * ptgp->group_shape + 0.5),
7284
4.94M
                                        (uint16_t)floor(65535 * ptgp->group_opacity + 0.5),
7285
4.94M
                                        pgs->blend_mode, ptgp->idle,
7286
4.94M
                                         ptgp->mask_id, pdev->color_info.num_components - has_tags,
7287
4.94M
                                         cm_back_drop, ptgp->shade_group,
7288
4.94M
                                         group_profile, tos_profile, group_color_info, pgs, dev);
7289
4.94M
    if (new_icc)
7290
919k
        gsicc_adjust_profile_rc(group_profile, -1, "pdf14_begin_transparency_group");
7291
4.94M
    return code;
7292
4.94M
}
7293
7294
static void
7295
pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color)
7296
4.94M
{
7297
4.94M
    pdf14_device* pdev = (pdf14_device*)dev;
7298
7299
4.94M
    if (group_color != NULL &&
7300
4.94M
        !(group_color->group_color_mapping_procs == NULL &&
7301
4.94M
            group_color->group_color_comp_index == NULL)) {
7302
4.94M
        bool has_tags = device_encodes_tags(dev);
7303
4.94M
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7304
4.94M
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7305
4.94M
        pdev->color_info.polarity = group_color->polarity;
7306
4.94M
        if (pdev->num_planar_planes > 0)
7307
242k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7308
4.94M
        pdev->color_info.num_components = group_color->num_components + has_tags;
7309
4.94M
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7310
4.94M
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7311
4.94M
        pdev->blend_procs = group_color->blend_procs;
7312
4.94M
        pdev->ctx->additive = group_color->isadditive;
7313
4.94M
        pdev->pdf14_procs = group_color->unpack_procs;
7314
4.94M
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7315
4.94M
        pdev->color_info.depth = group_color->depth;
7316
4.94M
        pdev->color_info.max_color = group_color->max_color;
7317
4.94M
        pdev->color_info.max_gray = group_color->max_gray;
7318
4.94M
        memcpy(&(pdev->color_info.comp_bits), &(group_color->comp_bits),
7319
4.94M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7320
4.94M
        memcpy(&(pdev->color_info.comp_shift), &(group_color->comp_shift),
7321
4.94M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7322
4.94M
        if (group_color->icc_profile != NULL) {
7323
            /* make sure to decrement the device profile.  If it was allocated
7324
               with the push then it will be freed. */
7325
4.94M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7326
4.94M
                                    -1, "pdf14_pop_color_model");
7327
4.94M
            pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
7328
4.94M
                                    group_color->icc_profile;
7329
7330
4.94M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7331
4.94M
                                    1, "pdf14_pop_color_model");
7332
4.94M
        }
7333
4.94M
        pdev->num_std_colorants = group_color->num_std_colorants;
7334
4.94M
    }
7335
4.94M
}
7336
7337
static  int
7338
pdf14_end_transparency_group(gx_device* dev, gs_gstate* pgs)
7339
4.94M
{
7340
4.94M
    pdf14_device* pdev = (pdf14_device*)dev;
7341
4.94M
    int code;
7342
4.94M
    cmm_profile_t* group_profile;
7343
4.94M
    gsicc_rendering_param_t render_cond;
7344
4.94M
    cmm_dev_profile_t* dev_profile;
7345
4.94M
    int has_tags = device_encodes_tags(dev);
7346
7347
4.94M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7348
4.94M
    if (code < 0)
7349
0
        return code;
7350
7351
4.94M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
7352
4.94M
        &render_cond);
7353
4.94M
    if_debug0m('v', dev->memory, "[v]pdf14_end_transparency_group\n");
7354
7355
4.94M
    code = pdf14_pop_transparency_group(pgs, pdev->ctx, pdev->blend_procs,
7356
4.94M
        pdev->color_info.num_components - has_tags, group_profile, (gx_device*)pdev);
7357
4.94M
    if (code < 0)
7358
0
        return code;
7359
#ifdef DEBUG
7360
    pdf14_debug_mask_stack_state(pdev->ctx);
7361
#endif
7362
    /* If this group is the base group, then restore the color model
7363
       of the device at this time.  Note that during the actual device pop
7364
       we will need to use the profile of the buffer not the pdf14 device
7365
       as the source color space */
7366
4.94M
    if (pdev->ctx->stack->group_popped) {
7367
885k
        pdf14_pop_color_model(dev, pdev->ctx->base_color);
7368
4.05M
    } else {
7369
4.05M
        pdf14_pop_color_model(dev, pdev->ctx->stack->group_color_info);
7370
4.05M
    }
7371
7372
4.94M
    return code;
7373
4.94M
}
7374
7375
static pdf14_group_color_t*
7376
pdf14_push_color_model(gx_device *dev, gs_transparency_color_t group_color_type,
7377
                        int64_t icc_hashcode, cmm_profile_t *iccprofile,
7378
                        bool is_mask)
7379
5.95M
{
7380
5.95M
    pdf14_device *pdevproto = NULL;
7381
5.95M
    pdf14_device *pdev = (pdf14_device *)dev;
7382
5.95M
    const pdf14_procs_t *new_14procs = NULL;
7383
5.95M
    pdf14_group_color_t *group_color;
7384
5.95M
    gx_color_polarity_t new_polarity;
7385
5.95M
    uchar new_num_comps;
7386
5.95M
    bool new_additive;
7387
5.95M
    gx_device_clist_reader *pcrdev;
7388
5.95M
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7389
5.95M
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7390
5.95M
    int k;
7391
5.95M
    bool has_tags = device_encodes_tags(dev);
7392
5.95M
    bool deep = pdev->ctx->deep;
7393
7394
5.95M
    if_debug0m('v', dev->memory, "[v]pdf14_push_color_model\n");
7395
7396
5.95M
    assert(dev->color_info.num_components == dev->num_planar_planes || dev->num_planar_planes == 0);
7397
7398
5.95M
    group_color = gs_alloc_struct(dev->memory->stable_memory,
7399
5.95M
                               pdf14_group_color_t, &st_pdf14_clr,
7400
5.95M
                               "pdf14_push_color_model");
7401
5.95M
    if (group_color == NULL)
7402
0
        return NULL;
7403
7404
5.95M
    memset(group_color, 0, sizeof(pdf14_group_color_t));
7405
7406
5.95M
    switch (group_color_type) {
7407
0
        case GRAY_SCALE:
7408
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7409
0
            new_num_comps = 1;
7410
0
            pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7411
0
            new_additive = true;
7412
0
            new_14procs = &gray_pdf14_procs;
7413
0
            break;
7414
0
        case DEVICE_RGB:
7415
0
        case CIE_XYZ:
7416
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7417
0
            new_num_comps = 3;
7418
0
            pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7419
0
            new_additive = true;
7420
0
            new_14procs = &rgb_pdf14_procs;
7421
0
            break;
7422
0
        case DEVICE_CMYK:
7423
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7424
0
            new_num_comps = 4;
7425
0
            pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7426
0
            new_additive = false;
7427
            /* This is needed due to the mismatched compressed encode decode
7428
                between the device procs and the pdf14 procs */
7429
0
            if (dev->color_info.num_components > 4){
7430
0
                new_14procs = &cmykspot_pdf14_procs;
7431
0
            } else {
7432
0
                new_14procs = &cmyk_pdf14_procs;
7433
0
            }
7434
0
            break;
7435
5.95M
        case ICC:
7436
            /* If we are coming from the clist reader, then we need to get
7437
                the ICC data now  */
7438
5.95M
            if (iccprofile == NULL && pdev->pclist_device != NULL) {
7439
                /* Get the serialized data from the clist.  Not the whole
7440
                    profile. */
7441
996k
                pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
7442
996k
                iccprofile = gsicc_read_serial_icc((gx_device *) pcrdev,
7443
996k
                                                    icc_hashcode);
7444
996k
                if (iccprofile == NULL)
7445
0
                    return NULL;
7446
                /* Keep a pointer to the clist device */
7447
996k
                iccprofile->dev = (gx_device *) pcrdev;
7448
4.95M
            } else {
7449
                /* Go ahead and rc increment right now.  This way when
7450
                    we pop, we will make sure to decrement and avoid a
7451
                    leak for the above profile that we just created.  This
7452
                    goes with the assignment to the device's profile.
7453
                    Note that we still do the increment for the group_color
7454
                    assignment below. */
7455
4.95M
                if (iccprofile == NULL)
7456
0
                    return NULL;
7457
4.95M
                gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7458
4.95M
            }
7459
5.95M
            new_num_comps = iccprofile->num_comps;
7460
5.95M
            if (new_num_comps == 4) {
7461
1.39M
                new_additive = false;
7462
1.39M
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7463
4.55M
            } else {
7464
4.55M
                new_additive = true;
7465
4.55M
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7466
4.55M
            }
7467
5.95M
            switch (new_num_comps) {
7468
1.42M
                case 1:
7469
1.42M
                    if (pdev->sep_device && !is_mask) {
7470
30
                        pdevproto = (pdf14_device *)&gs_pdf14_Grayspot_device;
7471
30
                        new_14procs = &grayspot_pdf14_procs;
7472
1.42M
                    } else {
7473
1.42M
                        pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7474
1.42M
                        new_14procs = &gray_pdf14_procs;
7475
1.42M
                    }
7476
1.42M
                    break;
7477
3.12M
                case 3:
7478
3.12M
                    if (pdev->sep_device) {
7479
124k
                        pdevproto = (pdf14_device *)&gs_pdf14_RGBspot_device;
7480
124k
                        new_14procs = &rgbspot_pdf14_procs;
7481
124k
                    }
7482
3.00M
                    else {
7483
3.00M
                        pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7484
3.00M
                        new_14procs = &rgb_pdf14_procs;
7485
3.00M
                    }
7486
3.12M
                    break;
7487
1.39M
                case 4:
7488
1.39M
                    if (pdev->sep_device) {
7489
117k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYKspot_device;
7490
117k
                        new_14procs = &cmykspot_pdf14_procs;
7491
1.28M
                    } else {
7492
1.28M
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7493
1.28M
                        new_14procs = &cmyk_pdf14_procs;
7494
1.28M
                    }
7495
1.39M
                    break;
7496
0
                default:
7497
0
                    return NULL;
7498
0
                    break;
7499
5.95M
            }
7500
5.95M
            break;
7501
5.95M
        default:
7502
0
            return NULL;
7503
0
            break;
7504
5.95M
    }
7505
7506
    /* We might just have changed the colorspace of the device, which means
7507
     * the number of colorants have changed. */
7508
5.95M
    group_color->num_std_colorants = new_num_comps;
7509
5.95M
    pdev->num_std_colorants = new_num_comps;
7510
7511
5.95M
    if (has_tags)
7512
0
        new_num_comps++;
7513
7514
5.95M
    if (group_color_type == ICC && iccprofile != NULL) {
7515
5.95M
        group_color->icc_profile = iccprofile;
7516
5.95M
        gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7517
5.95M
    }
7518
7519
    /* If we are a sep device and this is not a softmask, ensure we maintain the
7520
       spot colorants and know how to index into them */
7521
5.95M
    if (pdev->sep_device && !is_mask) {
7522
242k
        int num_spots = dev->color_info.num_components - has_tags -
7523
242k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps;
7524
7525
242k
        if (num_spots > 0)
7526
7.08k
            new_num_comps += num_spots;
7527
242k
    }
7528
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7529
22.3M
    for (k = 0; k < new_num_comps; k++) {
7530
16.4M
        comp_bits[k] = 8<<deep;
7531
16.4M
        comp_shift[k] = (new_num_comps - k - 1) * (8<<deep);
7532
16.4M
    }
7533
7534
    /* Set device values now and store settings in group_color.  Then they
7535
       are available when we pop the previous group */
7536
5.95M
    if_debug2m('v', pdev->memory,
7537
5.95M
                "[v]pdf14_push_color_model, num_components_old = %d num_components_new = %d\n",
7538
5.95M
                pdev->color_info.num_components,new_num_comps);
7539
5.95M
    {
7540
5.95M
        gx_device local_device;
7541
7542
5.95M
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7543
5.95M
        local_device.initialize_device_procs((gx_device *)&local_device);
7544
5.95M
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7545
5.95M
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7546
5.95M
    }
7547
5.95M
    group_color->blend_procs = pdev->blend_procs = pdevproto->blend_procs;
7548
5.95M
    group_color->polarity = pdev->color_info.polarity = new_polarity;
7549
5.95M
    group_color->isadditive = pdev->ctx->additive = new_additive;
7550
5.95M
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7551
5.95M
    group_color->unpack_procs = pdev->pdf14_procs = new_14procs;
7552
5.95M
    if (pdev->num_planar_planes > 0)
7553
308k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7554
5.95M
    group_color->num_components = new_num_comps - has_tags;
7555
5.95M
    pdev->color_info.num_components = new_num_comps;
7556
5.95M
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7557
5.95M
    assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7558
5.95M
    pdev->color_info.depth = new_num_comps * (8<<deep);
7559
5.95M
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7560
5.95M
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7561
5.95M
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7562
5.95M
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7563
5.95M
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
7564
5.95M
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
7565
5.95M
    group_color->depth = pdev->color_info.depth;
7566
5.95M
    group_color->decode = dev_proc(pdev, decode_color);
7567
5.95M
    group_color->encode = dev_proc(pdev, encode_color);
7568
5.95M
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
7569
5.95M
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
7570
5.95M
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
7571
5.95M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7572
5.95M
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
7573
5.95M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7574
5.95M
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
7575
7576
    /* If the CS was ICC based, we need to update the device ICC profile
7577
        in the ICC manager, since that is the profile that is used for the
7578
        PDF14 device */
7579
5.95M
    if (group_color_type == ICC && iccprofile != NULL) {
7580
        /* iccprofile was incremented above if we had not just created it.
7581
           When we do the pop we will decrement and if we just created it, it
7582
           will be destroyed */
7583
5.95M
        gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_push_color_model");
7584
5.95M
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = iccprofile;
7585
5.95M
    }
7586
5.95M
    return group_color;
7587
5.95M
}
7588
7589
static int
7590
pdf14_clist_push_color_model(gx_device *dev, gx_device* cdev, gs_gstate *pgs,
7591
                             const gs_pdf14trans_t *pdf14pct, gs_memory_t* mem,
7592
                             bool is_mask)
7593
124k
{
7594
124k
    pdf14_device* pdev = (pdf14_device*)dev;
7595
124k
    pdf14_group_color_t* new_group_color;
7596
124k
    gsicc_rendering_param_t render_cond;
7597
124k
    cmm_dev_profile_t* dev_profile;
7598
124k
    pdf14_device* pdevproto;
7599
124k
    gx_device_clist_writer* cldev = (gx_device_clist_writer*)pdev->pclist_device;
7600
124k
    const pdf14_procs_t* new_14procs;
7601
124k
    bool update_color_info;
7602
124k
    gx_color_polarity_t new_polarity;
7603
124k
    int new_num_comps;
7604
124k
    bool new_additive = false;
7605
124k
    byte new_depth;
7606
124k
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7607
124k
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7608
124k
    int k;
7609
124k
    bool has_tags = device_encodes_tags(dev);
7610
124k
    bool deep = device_is_deep(dev);
7611
124k
    gs_transparency_color_t group_color_type = pdf14pct->params.group_color_type;
7612
124k
    cmm_profile_t *new_profile = pdf14pct->params.iccprofile;
7613
124k
    cmm_profile_t *old_profile = NULL;
7614
7615
124k
    assert(dev->num_planar_planes == 0 || dev->num_planar_planes == dev->color_info.num_components);
7616
7617
124k
    dev_proc(dev, get_profile)(dev, &dev_profile);
7618
124k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &old_profile,
7619
124k
        &render_cond);
7620
124k
    if_debug0m('v', dev->memory, "[v]pdf14_clist_push_color_model\n");
7621
7622
    /* Allocate a new one */
7623
124k
    new_group_color = gs_alloc_struct(dev->memory->stable_memory, pdf14_group_color_t,
7624
124k
        &st_pdf14_clr, "pdf14_clist_push_color_model");
7625
7626
124k
    if (new_group_color == NULL)
7627
0
        return_error(gs_error_VMerror);
7628
7629
    /* Link to old one */
7630
124k
    new_group_color->previous = pdev->color_model_stack;
7631
7632
    /* Reassign new one to dev */
7633
124k
    pdev->color_model_stack = new_group_color;
7634
7635
    /* Initialize with values */
7636
124k
    new_group_color->get_cmap_procs = pgs->get_cmap_procs;
7637
124k
    new_group_color->group_color_mapping_procs =
7638
124k
        dev_proc(pdev, get_color_mapping_procs);
7639
124k
    new_group_color->group_color_comp_index =
7640
124k
        dev_proc(pdev, get_color_comp_index);
7641
124k
    new_group_color->blend_procs = pdev->blend_procs;
7642
124k
    new_group_color->polarity = pdev->color_info.polarity;
7643
124k
    new_group_color->num_components = pdev->color_info.num_components - has_tags;
7644
124k
    new_group_color->unpack_procs = pdev->pdf14_procs;
7645
124k
    new_group_color->depth = pdev->color_info.depth;
7646
124k
    new_group_color->max_color = pdev->color_info.max_color;
7647
124k
    new_group_color->max_gray = pdev->color_info.max_gray;
7648
124k
    new_group_color->decode = dev_proc(pdev, decode_color);
7649
124k
    new_group_color->encode = dev_proc(pdev, encode_color);
7650
124k
    memcpy(&(new_group_color->comp_bits), &(pdev->color_info.comp_bits),
7651
124k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7652
124k
    memcpy(&(new_group_color->comp_shift), &(pdev->color_info.comp_shift),
7653
124k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7654
7655
124k
    if (new_profile == NULL)
7656
76.7k
        new_group_color->icc_profile = NULL;
7657
7658
    /* isadditive is only used in ctx */
7659
124k
    if (pdev->ctx) {
7660
0
        new_group_color->isadditive = pdev->ctx->additive;
7661
0
    }
7662
7663
124k
    memset(comp_bits, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7664
124k
    memset(comp_shift, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7665
7666
124k
    if (group_color_type == ICC && new_profile == NULL)
7667
0
        return gs_throw(gs_error_undefinedresult, "Missing ICC data");
7668
124k
    if_debug0m('v', cldev->memory, "[v]pdf14_clist_push_color_model\n");
7669
    /* Check if we need to alter the device procs at this stage.  Many of the procs
7670
       are based upon the color space of the device.  We want to remain in the
7671
       color space defined by the color space of the soft mask or transparency
7672
       group as opposed to the device color space. Later, when we pop the softmask
7673
       we will collapse it to a single band and then compose with it to the device
7674
       color space (or the parent layer space).  In the case where we pop an
7675
       isolated transparency group, we will do the blending in the proper color
7676
       space and then transform the data when we pop the group.  Remember that only
7677
       isolated groups can have color spaces that are different than their parent. */
7678
124k
    update_color_info = false;
7679
124k
    switch (group_color_type) {
7680
0
    case GRAY_SCALE:
7681
0
        if (pdev->color_info.num_components != 1) {
7682
0
            update_color_info = true;
7683
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7684
0
            new_num_comps = 1;
7685
0
            pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7686
0
            new_additive = true;
7687
0
            new_14procs = &gray_pdf14_procs;
7688
0
            new_depth = 8 << deep;
7689
0
        }
7690
0
        break;
7691
0
    case DEVICE_RGB:
7692
0
    case CIE_XYZ:
7693
0
        if (pdev->color_info.num_components != 3) {
7694
0
            update_color_info = true;
7695
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7696
0
            new_num_comps = 3;
7697
0
            pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7698
0
            new_additive = true;
7699
0
            new_14procs = &rgb_pdf14_procs;
7700
0
            new_depth = 24 << deep;
7701
0
        }
7702
0
        break;
7703
0
    case DEVICE_CMYK:
7704
0
        if (pdev->color_info.num_components != 4) {
7705
0
            update_color_info = true;
7706
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7707
0
            new_num_comps = 4;
7708
0
            pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7709
0
            new_additive = false;
7710
            /* This is needed due to the mismatched compressed encode decode
7711
               between the device procs and the pdf14 procs */
7712
0
            if (dev->color_info.num_components > 4) {
7713
0
                new_14procs = &cmykspot_pdf14_procs;
7714
0
            }
7715
0
            else {
7716
0
                new_14procs = &cmyk_pdf14_procs;
7717
0
            }
7718
0
            new_depth = 32 << deep;
7719
0
        }
7720
0
        break;
7721
47.4k
    case ICC:
7722
        /* Check if the profile is different. */
7723
47.4k
        if (!gsicc_profiles_equal(old_profile, new_profile)) {
7724
43.0k
            update_color_info = true;
7725
43.0k
            new_num_comps = new_profile->num_comps;
7726
43.0k
            new_depth = new_profile->num_comps * (8 << deep);
7727
43.0k
            switch (new_num_comps) {
7728
39.1k
            case 1:
7729
39.1k
                if (pdev->sep_device && !is_mask) {
7730
0
                    pdevproto = (pdf14_device*)&gs_pdf14_Grayspot_device;
7731
0
                    new_14procs = &grayspot_pdf14_procs;
7732
0
                }
7733
39.1k
                else {
7734
39.1k
                    pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7735
39.1k
                    new_14procs = &gray_pdf14_procs;
7736
39.1k
                }
7737
39.1k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7738
39.1k
                new_additive = true;
7739
39.1k
                break;
7740
2.77k
            case 3:
7741
2.77k
                if (pdev->sep_device) {
7742
894
                    pdevproto = (pdf14_device*)&gs_pdf14_RGBspot_device;
7743
894
                    new_14procs = &rgbspot_pdf14_procs;
7744
894
                }
7745
1.88k
                else {
7746
1.88k
                    pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7747
1.88k
                    new_14procs = &rgb_pdf14_procs;
7748
1.88k
                }
7749
2.77k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7750
2.77k
                new_additive = true;
7751
2.77k
                break;
7752
1.11k
            case 4:
7753
1.11k
                if (pdev->sep_device) {
7754
65
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYKspot_device;
7755
65
                    new_14procs = &cmykspot_pdf14_procs;
7756
65
                }
7757
1.05k
                else {
7758
1.05k
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7759
1.05k
                    new_14procs = &cmyk_pdf14_procs;
7760
1.05k
                }
7761
1.11k
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7762
1.11k
                new_additive = false;
7763
1.11k
                break;
7764
0
            default:
7765
0
                return gs_throw(gs_error_undefinedresult,
7766
43.0k
                    "ICC Number of colorants illegal");
7767
43.0k
            }
7768
43.0k
        }
7769
47.4k
        break;
7770
76.7k
    case UNKNOWN:
7771
76.7k
        return 0;
7772
0
        break;
7773
0
    default:
7774
0
        return_error(gs_error_rangecheck);
7775
0
        break;
7776
124k
    }
7777
7778
47.4k
    if (!update_color_info) {
7779
        /* Profile not updated */
7780
4.40k
        new_group_color->icc_profile = NULL;
7781
4.40k
        if_debug0m('v', pdev->memory, "[v]procs not updated\n");
7782
4.40k
        return 0;
7783
4.40k
    }
7784
7785
43.0k
    if (has_tags) {
7786
0
        new_num_comps++;
7787
        /* In planar mode, planes need to all be the same depth. Otherwise use 8 bits for tags. */
7788
0
        if (pdev->num_planar_planes > 0)
7789
0
            new_depth += deep ? 16 : 8;
7790
0
        else
7791
0
            new_depth += 8;
7792
0
    }
7793
43.0k
    if (pdev->sep_device && !is_mask) {
7794
959
        int num_spots;
7795
7796
959
        if (old_profile == NULL)
7797
0
            return_error(gs_error_undefined);
7798
7799
959
        num_spots = pdev->color_info.num_components - has_tags - old_profile->num_comps;
7800
7801
959
        if (num_spots > 0) {
7802
88
            new_num_comps += num_spots;
7803
88
            new_depth = (8 << deep) * new_num_comps;
7804
88
        }
7805
959
    }
7806
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7807
95.0k
    for (k = 0; k < new_num_comps; k++) {
7808
52.0k
        comp_bits[k] = 8 << deep;
7809
52.0k
        comp_shift[k] = (new_num_comps - 1 - k) * (8 << deep);
7810
52.0k
    }
7811
43.0k
    if_debug2m('v', pdev->memory,
7812
43.0k
        "[v]pdf14_clist_push_color_model, num_components_old = %d num_components_new = %d\n",
7813
43.0k
        pdev->color_info.num_components, new_num_comps);
7814
    /* Set new information in the device */
7815
43.0k
    {
7816
43.0k
        gx_device local_device;
7817
7818
43.0k
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7819
43.0k
        local_device.initialize_device_procs((gx_device *)&local_device);
7820
43.0k
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7821
43.0k
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7822
43.0k
    }
7823
43.0k
    pdev->blend_procs = pdevproto->blend_procs;
7824
43.0k
    pdev->color_info.polarity = new_polarity;
7825
43.0k
    pdev->color_info.max_color = deep ? 65535 : 255;
7826
43.0k
    pdev->color_info.max_gray = deep ? 65535 : 255;
7827
43.0k
    pdev->pdf14_procs = new_14procs;
7828
43.0k
    if (pdev->num_planar_planes > 0)
7829
7.06k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7830
43.0k
    pdev->color_info.num_components = new_num_comps;
7831
43.0k
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7832
43.0k
    pdev->color_info.depth = new_depth;
7833
43.0k
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7834
43.0k
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7835
43.0k
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7836
43.0k
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7837
43.0k
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7838
7839
    /* If we have a compressed color codec, and we are doing a soft mask
7840
       push operation then go ahead and update the color encode and
7841
       decode for the pdf14 device to not used compressed color
7842
       encoding while in the soft mask.  We will just check for gray
7843
       and compressed.  Note that we probably don't have_tags if we
7844
       are dealing with compressed color.  But is is possible so
7845
       we add it in to catch for future use. */
7846
43.0k
    cldev->clist_color_info.depth = pdev->color_info.depth;
7847
43.0k
    cldev->clist_color_info.polarity = pdev->color_info.polarity;
7848
43.0k
    cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7849
43.0k
    cldev->clist_color_info.num_components = pdev->color_info.num_components;
7850
43.0k
    cldev->clist_color_info.max_color = pdev->color_info.max_color;
7851
43.0k
    cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7852
    /* For the ICC profiles, we want to update the ICC profile for the
7853
       device.  We store the original in group_color.
7854
       That will be stored in the clist and restored during the reading phase. */
7855
43.0k
    if (group_color_type == ICC) {
7856
43.0k
        gsicc_adjust_profile_rc(new_profile, 1, "pdf14_clist_push_color_model");
7857
43.0k
        new_group_color->icc_profile =
7858
43.0k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
7859
43.0k
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = new_profile;
7860
43.0k
    }
7861
43.0k
    if (pdev->ctx) {
7862
0
        pdev->ctx->additive = new_additive;
7863
0
    }
7864
43.0k
    return 1;  /* Lets us detect that we did do an update */
7865
43.0k
}
7866
7867
static int
7868
pdf14_clist_pop_color_model(gx_device *dev, gs_gstate *pgs)
7869
124k
{
7870
7871
124k
    pdf14_device *pdev = (pdf14_device *)dev;
7872
124k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7873
124k
    gx_device_clist_writer * cldev = (gx_device_clist_writer *)pdev->pclist_device;
7874
7875
124k
    if (group_color == NULL)
7876
0
        return_error(gs_error_Fatal);  /* Unmatched group pop */
7877
7878
124k
    if_debug0m('v', pdev->memory, "[v]pdf14_clist_pop_color_model\n");
7879
    /* The color procs are always pushed.  Simply restore them. */
7880
124k
    if (group_color->group_color_mapping_procs == NULL &&
7881
0
        group_color->group_color_comp_index == NULL) {
7882
0
        if_debug0m('v', dev->memory, "[v]pdf14_clist_pop_color_model ERROR \n");
7883
124k
    } else {
7884
124k
        bool has_tags = device_encodes_tags(dev);
7885
124k
        if_debug2m('v', pdev->memory,
7886
124k
                   "[v]pdf14_clist_pop_color_model, num_components_old = %d num_components_new = %d\n",
7887
124k
                   pdev->color_info.num_components,group_color->num_components);
7888
124k
        pgs->get_cmap_procs = group_color->get_cmap_procs;
7889
124k
        gx_set_cmap_procs(pgs, dev);
7890
124k
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7891
124k
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7892
124k
        pdev->color_info.polarity = group_color->polarity;
7893
124k
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7894
124k
        pdev->color_info.depth = group_color->depth;
7895
124k
        if (pdev->num_planar_planes > 0)
7896
17.8k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7897
124k
        pdev->color_info.num_components = group_color->num_components + has_tags;
7898
124k
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7899
124k
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7900
124k
        pdev->blend_procs = group_color->blend_procs;
7901
124k
        pdev->pdf14_procs = group_color->unpack_procs;
7902
124k
        pdev->color_info.max_color = group_color->max_color;
7903
124k
        pdev->color_info.max_gray = group_color->max_gray;
7904
124k
        set_dev_proc(pdev, encode_color, group_color->encode);
7905
124k
        set_dev_proc(pdev, decode_color, group_color->decode);
7906
124k
        memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
7907
124k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7908
124k
        memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
7909
124k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7910
7911
        /* clist writer fill rect has no access to gs_gstate */
7912
        /* and it forwards the target device.  this information */
7913
        /* is passed along to use in this case */
7914
124k
        cldev->clist_color_info.depth = pdev->color_info.depth;
7915
124k
        cldev->clist_color_info.polarity = pdev->color_info.polarity;
7916
124k
        cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7917
124k
        cldev->clist_color_info.num_components = pdev->color_info.num_components;
7918
124k
        cldev->clist_color_info.max_color = pdev->color_info.max_color;
7919
124k
        cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7920
124k
        memcpy(&(cldev->clist_color_info.comp_bits),&(group_color->comp_bits),
7921
124k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7922
124k
        memcpy(&(cldev->clist_color_info.comp_shift),&(group_color->comp_shift),
7923
124k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7924
124k
        if (pdev->ctx){
7925
0
            pdev->ctx->additive = group_color->isadditive;
7926
0
        }
7927
       /* The device profile must be restored. */
7928
124k
        if (group_color->icc_profile != NULL) {
7929
43.0k
            gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7930
43.0k
                                    -1, "pdf14_clist_pop_color_model");
7931
43.0k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
7932
43.0k
        }
7933
124k
        if_debug0m('v', dev->memory, "[v]procs updated\n");
7934
124k
    }
7935
124k
   pdf14_pop_group_color(dev, pgs);
7936
124k
    return 0;
7937
124k
}
7938
7939
/* When a transparency group is popped, the parent colorprocs must be restored.
7940
   Since the color mapping procs are all based upon the device, we must have a
7941
   nested list based upon the transparency group color space.  This nesting
7942
   must be outside the nested ctx structures to allow the nesting for the
7943
   clist writer */
7944
static void
7945
pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs)
7946
124k
{
7947
124k
    pdf14_device *pdev = (pdf14_device *)dev;
7948
124k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7949
7950
124k
    if_debug0m('v', dev->memory, "[v]pdf14_pop_group_color\n");
7951
7952
    /* Update the link */
7953
124k
    pdev->color_model_stack = group_color->previous;
7954
7955
    /* Free the old one */
7956
124k
    gs_free_object(dev->memory->stable_memory, group_color, "pdf14_clr_free");
7957
124k
}
7958
7959
static  int
7960
pdf14_begin_transparency_mask(gx_device *dev,
7961
                              const gx_transparency_mask_params_t *ptmp,
7962
                              const gs_rect *pbbox,
7963
                              gs_gstate *pgs, gs_memory_t *mem)
7964
8.73M
{
7965
8.73M
    pdf14_device *pdev = (pdf14_device *)dev;
7966
8.73M
    uint16_t bg_alpha = 0;   /* By default the background alpha (area outside mask) is zero */
7967
8.73M
    byte *transfer_fn;
7968
8.73M
    gs_int_rect rect;
7969
8.73M
    int code;
7970
8.73M
    int group_color_numcomps;
7971
8.73M
    gs_transparency_color_t group_color_type;
7972
8.73M
    bool deep = device_is_deep(dev);
7973
8.73M
    pdf14_group_color_t* group_color_info;
7974
7975
8.73M
    code = pdf14_initialize_ctx(dev, pgs);
7976
8.73M
    if (code < 0)
7977
0
        return code;
7978
7979
8.73M
    if (ptmp->subtype == TRANSPARENCY_MASK_None) {
7980
7.72M
        pdf14_ctx *ctx = pdev->ctx;
7981
7982
        /* free up any maskbuf on the current tos */
7983
7.72M
        if (ctx->mask_stack) {
7984
1.33M
            if (ctx->mask_stack->rc_mask->mask_buf != NULL ) {
7985
659k
                pdf14_buf_free(ctx->mask_stack->rc_mask->mask_buf);
7986
659k
                ctx->mask_stack->rc_mask->mask_buf = NULL;
7987
659k
            }
7988
1.33M
        }
7989
7.72M
        return 0;
7990
7.72M
    }
7991
1.01M
    transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, (256+deep)<<deep,
7992
1.01M
                                         "pdf14_begin_transparency_mask");
7993
1.01M
    if (transfer_fn == NULL)
7994
0
        return_error(gs_error_VMerror);
7995
1.01M
    code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7996
1.01M
    if (code < 0)
7997
0
        return code;
7998
    /* If we have background components the background alpha may be nonzero */
7999
1.01M
    if (ptmp->Background_components)
8000
336k
        bg_alpha = (int)(65535 * ptmp->GrayBackground + 0.5);
8001
1.01M
    if_debug1m('v', dev->memory,
8002
1.01M
               "pdf14_begin_transparency_mask, bg_alpha = %d\n", bg_alpha);
8003
1.01M
    memcpy(transfer_fn, ptmp->transfer_fn, (256+deep)<<deep);
8004
   /* If the group color is unknown, then we must use the previous group color
8005
       space or the device process color space */
8006
1.01M
    if (ptmp->group_color_type == UNKNOWN){
8007
0
        if (pdev->ctx->stack){
8008
            /* Use previous group color space */
8009
0
            group_color_numcomps = pdev->ctx->stack->n_chan-1;  /* Remove alpha */
8010
0
        } else {
8011
            /* Use process color space */
8012
0
            group_color_numcomps = pdev->color_info.num_components;
8013
0
        }
8014
0
        switch (group_color_numcomps) {
8015
0
            case 1:
8016
0
                group_color_type = GRAY_SCALE;
8017
0
                break;
8018
0
            case 3:
8019
0
                group_color_type = DEVICE_RGB;
8020
0
                break;
8021
0
            case 4:
8022
0
                group_color_type = DEVICE_CMYK;
8023
0
            break;
8024
0
            default:
8025
                /* We can end up here if we are in a deviceN color space and
8026
                   we have a sep output device */
8027
0
                group_color_type = DEVICEN;
8028
0
            break;
8029
0
         }
8030
1.01M
    } else {
8031
1.01M
        group_color_type = ptmp->group_color_type;
8032
1.01M
        group_color_numcomps = ptmp->group_color_numcomps;
8033
1.01M
    }
8034
8035
1.01M
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptmp->icc_hashcode,
8036
1.01M
                                               ptmp->iccprofile, true);
8037
1.01M
    if (group_color_info == NULL)
8038
0
        return gs_error_VMerror;
8039
8040
    /* Note that the soft mask always follows the group color requirements even
8041
       when we have a separable device */
8042
1.01M
    code = pdf14_push_transparency_mask(pdev->ctx, &rect, bg_alpha,
8043
1.01M
                                        transfer_fn, ptmp->function_is_identity,
8044
1.01M
                                        ptmp->idle, ptmp->replacing,
8045
1.01M
                                        ptmp->mask_id, ptmp->subtype,
8046
1.01M
                                        group_color_numcomps,
8047
1.01M
                                        ptmp->Background_components,
8048
1.01M
                                        ptmp->Background,
8049
1.01M
                                        ptmp->Matte_components,
8050
1.01M
                                        ptmp->Matte,
8051
1.01M
                                        ptmp->GrayBackground,
8052
1.01M
                                        group_color_info);
8053
1.01M
    if (code < 0)
8054
0
        return code;
8055
8056
1.01M
    return 0;
8057
1.01M
}
8058
8059
static  int
8060
pdf14_end_transparency_mask(gx_device *dev, gs_gstate *pgs)
8061
1.01M
{
8062
1.01M
    pdf14_device *pdev = (pdf14_device *)dev;
8063
1.01M
    pdf14_group_color_t *group_color;
8064
1.01M
    int ok;
8065
1.01M
    bool has_tags = device_encodes_tags(dev);
8066
8067
1.01M
    if_debug0m('v', dev->memory, "pdf14_end_transparency_mask\n");
8068
1.01M
    ok = pdf14_pop_transparency_mask(pdev->ctx, pgs, dev);
8069
#ifdef DEBUG
8070
    pdf14_debug_mask_stack_state(pdev->ctx);
8071
#endif
8072
8073
    /* May need to reset some color stuff related
8074
     * to a mismatch between the Smask color space
8075
     * and the Smask blending space */
8076
1.01M
    if (pdev->ctx->stack != NULL ) {
8077
1.01M
        group_color = pdev->ctx->stack->group_color_info;
8078
1.01M
        if (!(group_color->group_color_mapping_procs == NULL &&
8079
1.01M
            group_color->group_color_comp_index == NULL)) {
8080
1.01M
            pgs->get_cmap_procs = group_color->get_cmap_procs;
8081
1.01M
            gx_set_cmap_procs(pgs, dev);
8082
1.01M
            set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
8083
1.01M
            set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
8084
1.01M
            pdev->color_info.polarity = group_color->polarity;
8085
1.01M
            pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
8086
1.01M
            if (pdev->num_planar_planes > 0)
8087
66.6k
                pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
8088
1.01M
            pdev->color_info.num_components = group_color->num_components + has_tags;
8089
1.01M
            assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
8090
1.01M
            assert(pdev->color_info.num_components - has_tags == group_color->num_components);
8091
1.01M
            pdev->num_std_colorants = group_color->num_std_colorants;
8092
1.01M
            pdev->color_info.depth = group_color->depth;
8093
1.01M
            pdev->blend_procs = group_color->blend_procs;
8094
1.01M
            pdev->ctx->additive = group_color->isadditive;
8095
1.01M
            pdev->pdf14_procs = group_color->unpack_procs;
8096
1.01M
            pdev->color_info.max_color = group_color->max_color;
8097
1.01M
            pdev->color_info.max_gray = group_color->max_gray;
8098
1.01M
            set_dev_proc(pdev, encode_color, group_color->encode);
8099
1.01M
            set_dev_proc(pdev, decode_color, group_color->decode);
8100
1.01M
            memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
8101
1.01M
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8102
1.01M
            memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
8103
1.01M
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8104
            /* Take care of the ICC profile */
8105
1.01M
            if (group_color->icc_profile != NULL) {
8106
1.01M
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8107
1.01M
                                        -1, "pdf14_end_transparency_mask");
8108
1.01M
                dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
8109
1.01M
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8110
1.01M
                                         1, "pdf14_end_transparency_mask");
8111
1.01M
            }
8112
1.01M
        }
8113
1.01M
    }
8114
1.01M
    return ok;
8115
1.01M
}
8116
8117
static  int
8118
do_mark_fill_rectangle_ko_simple(gx_device *dev, int x, int y, int w, int h,
8119
                                 gx_color_index color,
8120
                                 const gx_device_color *pdc, bool devn)
8121
5.65M
{
8122
5.65M
    pdf14_device *pdev = (pdf14_device *)dev;
8123
5.65M
    pdf14_buf *buf = pdev->ctx->stack;
8124
5.65M
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8125
5.65M
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8126
235k
        blend_mode == BLEND_MODE_Compatible ||
8127
235k
        blend_mode == BLEND_MODE_CompatibleOverprint;
8128
5.65M
    int i, j, k;
8129
5.65M
    byte *bline, *bg_ptr, *line, *dst_ptr;
8130
5.65M
    byte src[PDF14_MAX_PLANES];
8131
5.65M
    byte dst[PDF14_MAX_PLANES] = { 0 };
8132
5.65M
    byte dst2[PDF14_MAX_PLANES] = { 0 };
8133
5.65M
    intptr_t rowstride = buf->rowstride;
8134
5.65M
    intptr_t planestride = buf->planestride;
8135
5.65M
    int num_chan = buf->n_chan;
8136
5.65M
    int num_comp = num_chan - 1;
8137
5.65M
    intptr_t shape_off = num_chan * planestride;
8138
5.65M
    bool has_shape = buf->has_shape;
8139
5.65M
    bool has_alpha_g = buf->has_alpha_g;
8140
5.65M
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8141
5.65M
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8142
5.65M
                                   (has_shape ? planestride : 0);
8143
5.65M
    bool has_tags = buf->has_tags;
8144
5.65M
    bool additive = pdev->ctx->additive;
8145
5.65M
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8146
5.65M
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
8147
5.65M
    int shift = 8;
8148
5.65M
    byte shape = 0; /* Quiet compiler. */
8149
5.65M
    byte src_alpha;
8150
5.65M
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8151
5.65M
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
8152
5.14M
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8153
5.65M
    gx_color_index comps;
8154
5.65M
    bool has_backdrop = buf->backdrop != NULL;
8155
8156
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8157
       subtractive) and we are doing overprint with drawn_comps == 0
8158
       then this is a no-operation */
8159
5.65M
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8160
0
        return 0;
8161
8162
5.65M
    if (buf->data == NULL)
8163
2
        return 0;
8164
#if 0
8165
    if (sizeof(color) <= sizeof(ulong))
8166
        if_debug6m('v', dev->memory,
8167
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %lx, nc %d,\n",
8168
                   x, y, w, h, (ulong)color, num_chan);
8169
    else
8170
        if_debug7m('v', dev->memory,
8171
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8172
                   x, y, w, h,
8173
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8174
                   num_chan);
8175
#endif
8176
    /*
8177
     * Unpack the gx_color_index values.  Complement the components for subtractive
8178
     * color spaces.
8179
     */
8180
5.65M
    if (devn) {
8181
709k
        if (has_tags) {
8182
0
            curr_tag = pdc->tag;
8183
0
        }
8184
709k
        if (additive) {
8185
1.85M
            for (j = 0; j < num_comp; j++) {
8186
1.38M
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
8187
1.38M
            }
8188
463k
        } else {
8189
1.23M
            for (j = 0; j < num_comp; j++) {
8190
984k
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
8191
984k
            }
8192
246k
        }
8193
4.95M
    } else {
8194
4.95M
        if (has_tags) {
8195
0
            curr_tag = (color >> (num_comp * 8)) & 0xff;
8196
0
        }
8197
4.95M
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
8198
4.95M
    }
8199
8200
5.65M
    if (!has_tags)
8201
5.65M
        tag_off = 0;
8202
8203
5.65M
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
8204
5.65M
    if (has_shape) {
8205
6.61k
        shape = (byte)floor (255 * pdev->shape + 0.5);
8206
5.65M
    } else {
8207
5.65M
        shape_off = 0;
8208
5.65M
    }
8209
8210
5.65M
    if (!has_alpha_g)
8211
0
        alpha_g_off = 0;
8212
5.65M
    src_alpha = 255 - src_alpha;
8213
5.65M
    shape = 255 - shape;
8214
8215
    /* Fit the mark into the bounds of the buffer */
8216
5.65M
    if (x < buf->rect.p.x) {
8217
0
        w += x - buf->rect.p.x;
8218
0
        x = buf->rect.p.x;
8219
0
    }
8220
5.65M
    if (y < buf->rect.p.y) {
8221
9
      h += y - buf->rect.p.y;
8222
9
      y = buf->rect.p.y;
8223
9
    }
8224
5.65M
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8225
5.65M
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8226
    /* Update the dirty rectangle with the mark. */
8227
5.65M
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8228
5.65M
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8229
5.65M
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8230
5.65M
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8231
8232
    /* composite with backdrop only. */
8233
5.65M
    if (has_backdrop)
8234
5.65M
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8235
0
    else
8236
0
        bline = NULL;
8237
8238
5.65M
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8239
8240
11.8M
    for (j = 0; j < h; ++j) {
8241
6.16M
        bg_ptr = bline;
8242
6.16M
        dst_ptr = line;
8243
243M
        for (i = 0; i < w; ++i) {
8244
            /* Complement the components for subtractive color spaces */
8245
237M
            if (has_backdrop) {
8246
237M
                if (additive) {
8247
878M
                    for (k = 0; k < num_comp; ++k)
8248
648M
                        dst[k] = bg_ptr[k * planestride];
8249
229M
                } else {
8250
40.7M
                    for (k = 0; k < num_comp; ++k)
8251
32.5M
                        dst2[k] = dst[k] = 255 - bg_ptr[k * planestride];
8252
8.14M
                }
8253
237M
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8254
237M
            }
8255
237M
            if (buf->isolated || !has_backdrop) {
8256
0
                art_pdf_knockoutisolated_group_8(dst, src, num_comp);
8257
237M
            } else {
8258
237M
                art_pdf_composite_knockout_8(dst, src, num_comp,
8259
237M
                                            blend_mode, pdev->blend_procs, pdev);
8260
237M
            }
8261
            /* Complement the results for subtractive color spaces */
8262
237M
            if (additive) {
8263
229M
                if (!overprint) {
8264
1.10G
                    for (k = 0; k < num_chan; ++k)
8265
877M
                        dst_ptr[k * planestride] = dst[k];
8266
229M
                } else {
8267
                    /* Hybrid additive with subtractive spots */
8268
                    /* We may have to do the compatible overprint blending */
8269
73.4k
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8270
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8271
0
                            blend_mode, pdev->blend_procs, pdev);
8272
0
                    }
8273
293k
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8274
220k
                        if ((comps & 0x1) != 0) {
8275
220k
                            dst_ptr[k * planestride] = dst[k];
8276
220k
                        } else {
8277
                            /* Compatible overprint blend result. */
8278
0
                            dst_ptr[k * planestride] = dst2[k];
8279
0
                        }
8280
220k
                    }
8281
73.4k
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8282
73.4k
                }
8283
229M
            } else {
8284
8.14M
                if (overprint) {
8285
                    /* We may have to do the compatible overprint blending */
8286
0
                    if (!buf->isolated && drawn_comps != (( (size_t) 1 << (size_t) dev->color_info.num_components)-(size_t) 1)) {
8287
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8288
0
                            blend_mode, pdev->blend_procs, pdev);
8289
0
                    }
8290
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8291
0
                        if ((comps & 0x1) != 0) {
8292
0
                            dst_ptr[k * planestride] = 255 - dst[k];
8293
0
                        } else {
8294
                            /* Compatible overprint blend result. */
8295
0
                            dst_ptr[k * planestride] = 255 - dst2[k];
8296
0
                        }
8297
0
                    }
8298
8.14M
                } else {
8299
40.7M
                    for (k = 0; k < num_comp; ++k)
8300
32.5M
                        dst_ptr[k * planestride] = 255 - dst[k];
8301
8.14M
                }
8302
8.14M
                dst_ptr[num_comp * planestride] = dst[num_comp];
8303
8.14M
            }
8304
237M
            if (tag_off) {
8305
                /* If src alpha is 100% then set to curr_tag, else or */
8306
                /* other than Normal BM, we always OR */
8307
0
                if (src[num_comp] == 255 && tag_blend) {
8308
0
                    dst_ptr[tag_off] = curr_tag;
8309
0
                } else {
8310
0
                    dst_ptr[tag_off] |= curr_tag;
8311
0
                }
8312
0
            }
8313
            /* Knockout group alpha and shape too */
8314
237M
            if (alpha_g_off)
8315
237M
                dst_ptr[alpha_g_off] = 255 - src_alpha;
8316
237M
            if (shape_off)
8317
6.93k
                dst_ptr[shape_off] = 255 - shape;
8318
237M
            ++dst_ptr;
8319
237M
            if (has_backdrop)
8320
237M
                ++bg_ptr;
8321
237M
        }
8322
6.16M
        bline += rowstride;
8323
6.16M
        line += rowstride;
8324
6.16M
    }
8325
#if 0
8326
/* #if RAW_DUMP */
8327
    /* Dump the current buffer to see what we have. */
8328
    dump_raw_buffer(pdev->ctx->memory,
8329
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8330
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8331
                    pdev->ctx->stack->n_planes,
8332
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8333
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8334
                    pdev->ctx->stack->deep);
8335
    global_index++;
8336
#endif
8337
5.65M
    return 0;
8338
5.65M
}
8339
8340
static  int
8341
do_mark_fill_rectangle_ko_simple16(gx_device *dev, int x, int y, int w, int h,
8342
                                   gx_color_index color,
8343
                                   const gx_device_color *pdc, bool devn)
8344
0
{
8345
0
    pdf14_device *pdev = (pdf14_device *)dev;
8346
0
    pdf14_buf *buf = pdev->ctx->stack;
8347
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8348
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8349
0
        blend_mode == BLEND_MODE_Compatible ||
8350
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
8351
0
    int i, j, k;
8352
0
    uint16_t *bline, *bg_ptr, *line, *dst_ptr;
8353
0
    uint16_t src[PDF14_MAX_PLANES];
8354
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
8355
0
    uint16_t dst2[PDF14_MAX_PLANES] = { 0 };
8356
0
    intptr_t rowstride = buf->rowstride;
8357
0
    intptr_t planestride = buf->planestride;
8358
0
    int num_chan = buf->n_chan;
8359
0
    int num_comp = num_chan - 1;
8360
0
    intptr_t shape_off = num_chan * planestride;
8361
0
    bool has_shape = buf->has_shape;
8362
0
    bool has_alpha_g = buf->has_alpha_g;
8363
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8364
0
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8365
0
                                   (has_shape ? planestride : 0);
8366
0
    bool has_tags = buf->has_tags;
8367
0
    bool additive = pdev->ctx->additive;
8368
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8369
0
    uint16_t shape = 0; /* Quiet compiler. */
8370
0
    uint16_t src_alpha;
8371
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8372
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
8373
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8374
0
    gx_color_index comps;
8375
0
    bool has_backdrop = buf->backdrop != NULL;
8376
8377
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8378
       subtractive) and we are doing overprint with drawn_comps == 0
8379
       then this is a no-operation */
8380
0
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8381
0
        return 0;
8382
8383
0
    if (buf->data == NULL)
8384
0
        return 0;
8385
#if 0
8386
    if (sizeof(color) <= sizeof(ulong))
8387
        if_debug6m('v', dev->memory,
8388
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %lx, nc %d,\n",
8389
                   x, y, w, h, (ulong)color, num_chan);
8390
    else
8391
        if_debug7m('v', dev->memory,
8392
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8393
                   x, y, w, h,
8394
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8395
                   num_chan);
8396
#endif
8397
    /*
8398
     * Unpack the gx_color_index values.  Complement the components for subtractive
8399
     * color spaces.
8400
     */
8401
0
    if (devn) {
8402
0
        if (has_tags) {
8403
0
            curr_tag = pdc->tag;
8404
0
        }
8405
0
        if (additive) {
8406
0
            for (j = 0; j < num_comp; j++) {
8407
0
                src[j] = pdc->colors.devn.values[j];
8408
0
            }
8409
0
        } else {
8410
0
            for (j = 0; j < num_comp; j++) {
8411
0
                src[j] = 65535 - pdc->colors.devn.values[j];
8412
0
            }
8413
0
        }
8414
0
    } else {
8415
0
        if (has_tags) {
8416
0
            curr_tag = (color >> (num_comp * 16)) & 0xff;
8417
0
        }
8418
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
8419
0
    }
8420
8421
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
8422
0
    if (has_shape) {
8423
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
8424
0
    } else {
8425
0
        shape_off = 0;
8426
0
    }
8427
8428
0
    if (!has_tags) {
8429
0
        tag_off = 0;
8430
0
    }
8431
8432
0
    if (!has_alpha_g)
8433
0
        alpha_g_off = 0;
8434
0
    src_alpha = 65535 - src_alpha;
8435
0
    shape = 65535 - shape;
8436
8437
    /* Fit the mark into the bounds of the buffer */
8438
0
    if (x < buf->rect.p.x) {
8439
0
        w += x - buf->rect.p.x;
8440
0
        x = buf->rect.p.x;
8441
0
    }
8442
0
    if (y < buf->rect.p.y) {
8443
0
      h += y - buf->rect.p.y;
8444
0
      y = buf->rect.p.y;
8445
0
    }
8446
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8447
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8448
    /* Update the dirty rectangle with the mark. */
8449
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8450
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8451
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8452
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8453
8454
8455
    /* composite with backdrop only. */
8456
0
    if (has_backdrop)
8457
0
        bline = (uint16_t*)(void*)(buf->backdrop + (x - buf->rect.p.x) * 2 + (y - buf->rect.p.y) * rowstride);
8458
0
    else
8459
0
        bline = NULL;
8460
8461
0
    line = (uint16_t *)(void *)(buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride);
8462
0
    planestride >>= 1;
8463
0
    rowstride >>= 1;
8464
0
    alpha_g_off >>= 1;
8465
0
    shape_off >>= 1;
8466
0
    tag_off >>= 1;
8467
8468
0
    for (j = 0; j < h; ++j) {
8469
0
        bg_ptr = bline;
8470
0
        dst_ptr = line;
8471
0
        for (i = 0; i < w; ++i) {
8472
            /* Complement the components for subtractive color spaces */
8473
0
            if (has_backdrop) {
8474
0
                if (additive) {
8475
0
                    for (k = 0; k < num_comp; ++k)
8476
0
                        dst[k] = bg_ptr[k * planestride];
8477
0
                } else {
8478
0
                    for (k = 0; k < num_comp; ++k)
8479
0
                        dst2[k] = dst[k] = 65535 - bg_ptr[k * planestride];
8480
0
                }
8481
0
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8482
0
            }
8483
0
            if (buf->isolated || !has_backdrop) {
8484
0
                art_pdf_knockoutisolated_group_16(dst, src, num_comp);
8485
0
            } else {
8486
0
                art_pdf_composite_knockout_16(dst, src, num_comp,
8487
0
                                              blend_mode, pdev->blend_procs, pdev);
8488
0
            }
8489
            /* Complement the results for subtractive color spaces */
8490
0
            if (additive) {
8491
0
                if (!overprint) {
8492
0
                    for (k = 0; k < num_chan; ++k)
8493
0
                        dst_ptr[k * planestride] = dst[k];
8494
0
                } else {
8495
                    /* Hybrid additive with subtractive spots */
8496
                    /* We may have to do the compatible overprint blending */
8497
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8498
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8499
0
                            blend_mode, pdev->blend_procs, pdev);
8500
0
                    }
8501
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8502
0
                        if ((comps & 0x1) != 0) {
8503
0
                            dst_ptr[k * planestride] = dst[k];
8504
0
                        } else {
8505
                            /* Compatible overprint blend result. */
8506
0
                            dst_ptr[k * planestride] = dst2[k];
8507
0
                        }
8508
0
                    }
8509
0
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8510
0
                }
8511
0
            } else {
8512
0
                if (overprint) {
8513
                    /* We may have to do the compatible overprint blending */
8514
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8515
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8516
0
                            blend_mode, pdev->blend_procs, pdev);
8517
0
                    }
8518
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8519
0
                        if ((comps & 0x1) != 0) {
8520
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
8521
0
                        } else {
8522
                            /* Compatible overprint blend result. */
8523
0
                            dst_ptr[k * planestride] = 65535 - dst2[k];
8524
0
                        }
8525
0
                    }
8526
0
                } else {
8527
0
                    for (k = 0; k < num_comp; ++k)
8528
0
                        dst_ptr[k * planestride] = 65535 - dst[k];
8529
0
                }
8530
0
                dst_ptr[num_comp * planestride] = dst[num_comp];
8531
0
            }
8532
0
            if (tag_off) {
8533
                /* FIXME: As we are knocking out, possibly, we should be
8534
                 * always overwriting tag values here? */
8535
                /* If src alpha is 100% then set to curr_tag, else or */
8536
                /* other than Normal BM, we always OR */
8537
0
                if (src[num_comp] == 65535 && tag_blend) {
8538
0
                    dst_ptr[tag_off] = curr_tag;
8539
0
                } else {
8540
0
                    dst_ptr[tag_off] |= curr_tag;
8541
0
                }
8542
0
            }
8543
            /* Knockout group alpha and shape too */
8544
0
            if (alpha_g_off)
8545
0
                dst_ptr[alpha_g_off] = 65535 - src_alpha;
8546
0
            if (shape_off)
8547
0
                dst_ptr[shape_off] = 65535 - shape;
8548
0
            ++dst_ptr;
8549
0
            if (has_backdrop)
8550
0
                ++bg_ptr;
8551
0
        }
8552
0
        bline += rowstride;
8553
0
        line += rowstride;
8554
0
    }
8555
#if 0
8556
/* #if RAW_DUMP */
8557
    /* Dump the current buffer to see what we have. */
8558
    dump_raw_buffer(pdev->ctx->memory,
8559
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8560
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8561
                    pdev->ctx->stack->n_planes,
8562
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8563
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8564
                    pdev->ctx->stack->deep);
8565
    global_index++;
8566
#endif
8567
0
    return 0;
8568
0
}
8569
8570
static  int
8571
pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, int w, int h,
8572
                                    gx_color_index color,
8573
                                    const gx_device_color *pdc, bool devn)
8574
5.65M
{
8575
5.65M
    pdf14_device *pdev = (pdf14_device *)dev;
8576
5.65M
    pdf14_buf *buf = pdev->ctx->stack;
8577
8578
5.65M
    if (buf->deep)
8579
0
        return do_mark_fill_rectangle_ko_simple16(dev, x, y, w, h, color, pdc, devn);
8580
5.65M
    else
8581
5.65M
        return do_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, pdc, devn);
8582
5.65M
}
8583
8584
/**
8585
 * Here we have logic to override the cmap_procs with versions that
8586
 * do not apply the transfer function. These copies should track the
8587
 * versions in gxcmap.c.
8588
 **/
8589
static  cmap_proc_gray(pdf14_cmap_gray_direct);
8590
static  cmap_proc_rgb(pdf14_cmap_rgb_direct);
8591
static  cmap_proc_cmyk(pdf14_cmap_cmyk_direct);
8592
static  cmap_proc_separation(pdf14_cmap_separation_direct);
8593
static  cmap_proc_devicen(pdf14_cmap_devicen_direct);
8594
static  cmap_proc_is_halftoned(pdf14_cmap_is_halftoned);
8595
8596
static  const gx_color_map_procs pdf14_cmap_many = {
8597
     pdf14_cmap_gray_direct,
8598
     pdf14_cmap_rgb_direct,
8599
     pdf14_cmap_cmyk_direct,
8600
     pdf14_cmap_separation_direct,
8601
     pdf14_cmap_devicen_direct,
8602
     pdf14_cmap_is_halftoned
8603
    };
8604
8605
/**
8606
 * Note: copied from gxcmap.c because it's inlined.
8607
 **/
8608
static  inline void
8609
map_components_to_colorants(const frac * pcc,
8610
                            const gs_devicen_color_map * pcolor_component_map,
8611
                            frac * plist,
8612
                            int num_additives)
8613
4.81M
{
8614
4.81M
    int i = pcolor_component_map->num_colorants - 1;
8615
4.81M
    int pos;
8616
8617
    /* Clear all output colorants first */
8618
24.0M
    for (; i >= num_additives; i--) {
8619
19.2M
        plist[i] = frac_0;
8620
19.2M
    }
8621
4.82M
    for (; i >= 0; i--) {
8622
9.52k
        plist[i] = frac_1;
8623
9.52k
    }
8624
    /* Map color components into output list */
8625
10.2M
    for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
8626
5.39M
        pos = pcolor_component_map->color_map[i];
8627
5.39M
        if (pos >= 0) {
8628
5.39M
            if (pos < num_additives)
8629
0
                plist[pos] = frac_1 - pcc[i];
8630
5.39M
            else
8631
5.39M
                plist[pos] = pcc[i];
8632
5.39M
        }
8633
5.39M
    }
8634
4.81M
}
8635
8636
/* See Section 7.6.4 of PDF 1.7 spec */
8637
static inline bool
8638
pdf14_state_opaque(gx_device *pdev, const gs_gstate *pgs)
8639
490M
{
8640
490M
    if (pgs->fillconstantalpha != 1.0 ||
8641
489M
        pgs->strokeconstantalpha != 1.0 ||
8642
489M
        !(pgs->blend_mode == BLEND_MODE_Normal ||
8643
22.3M
          pgs->blend_mode == BLEND_MODE_CompatibleOverprint))
8644
23.5M
        return 0;
8645
8646
    /* We can only be opaque if we're not in an SMask. */
8647
466M
    return dev_proc(pdev, dev_spec_op)(pdev,
8648
466M
                                       gxdso_in_smask,
8649
466M
                                       NULL, 0) != 1;
8650
490M
}
8651
8652
static  void
8653
pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs,
8654
                       gx_device * dev, gs_color_select_t select)
8655
18.3M
{
8656
18.3M
    int i, nc, ncomps;
8657
18.3M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8658
18.3M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8659
18.3M
    gx_color_index color;
8660
18.3M
    gx_device *trans_device;
8661
18.3M
    const gx_device *map_dev;
8662
18.3M
    const gx_cm_color_map_procs *procs;
8663
8664
    /* If trans device is set, we need to use its procs. */
8665
18.3M
    if (pgs->trans_device != NULL) {
8666
4.35M
        trans_device = pgs->trans_device;
8667
13.9M
    } else {
8668
13.9M
        trans_device = dev;
8669
13.9M
    }
8670
18.3M
    ncomps = trans_device->color_info.num_components;
8671
8672
    /* map to the color model */
8673
18.3M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8674
18.3M
    procs->map_gray(map_dev, gray, cm_comps);
8675
8676
18.3M
    nc = ncomps;
8677
18.3M
    if (device_encodes_tags(trans_device))
8678
0
        nc--;
8679
18.3M
    if (pdf14_state_opaque(trans_device, pgs)) {
8680
9.68M
        for (i = 0; i < nc; i++)
8681
4.84M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8682
13.4M
    } else {
8683
26.9M
        for (i = 0; i < nc; i++)
8684
13.4M
            cv[i] = frac2cv(cm_comps[i]);
8685
13.4M
    }
8686
    /* Copy tags untransformed. */
8687
18.3M
    if (nc < ncomps)
8688
0
        cv[nc] = dev->graphics_type_tag;
8689
8690
    /* If output device supports devn, we need to make sure we send it the
8691
       proper color type.  We now support Gray + spots as devn colors */
8692
18.3M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8693
1.75M
        for (i = 0; i < ncomps; i++)
8694
875k
            pdc->colors.devn.values[i] = cv[i];
8695
56.0M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8696
55.1M
            pdc->colors.devn.values[i] = 0;
8697
875k
        pdc->type = gx_dc_type_devn;
8698
17.4M
    } else {
8699
        /* encode as a color index */
8700
17.4M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8701
        /* check if the encoding was successful; we presume failure is rare */
8702
17.4M
        if (color != gx_no_color_index)
8703
17.4M
            color_set_pure(pdc, color);
8704
17.4M
    }
8705
18.3M
}
8706
8707
static  void
8708
pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
8709
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
8710
439M
{
8711
439M
    int i, nc, ncomps;
8712
439M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8713
439M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8714
439M
    gx_color_index color;
8715
439M
    gx_device *trans_device;
8716
439M
    const gx_device *map_dev;
8717
439M
    const gx_cm_color_map_procs *procs;
8718
8719
    /* If trans device is set, we need to use its procs. */
8720
439M
    if (pgs->trans_device != NULL){
8721
1.87M
        trans_device = pgs->trans_device;
8722
437M
    } else {
8723
437M
        trans_device = dev;
8724
437M
    }
8725
439M
    ncomps = trans_device->color_info.num_components;
8726
    /* map to the color model */
8727
439M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8728
439M
    procs->map_rgb(map_dev, pgs, r, g, b, cm_comps);
8729
8730
439M
    nc = ncomps;
8731
439M
    if (device_encodes_tags(trans_device))
8732
0
        nc--;
8733
439M
    if (pdf14_state_opaque(trans_device, pgs)) {
8734
928M
        for (i = 0; i < nc; i++)
8735
696M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8736
232M
    } else {
8737
830M
        for (i = 0; i < nc; i++)
8738
622M
            cv[i] = frac2cv(cm_comps[i]);
8739
207M
    }
8740
    /* Copy tags untransformed. */
8741
439M
    if (nc < ncomps)
8742
0
        cv[nc] = dev->graphics_type_tag;
8743
8744
    /* If output device supports devn, we need to make sure we send it the
8745
       proper color type.  We now support RGB + spots as devn colors */
8746
439M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8747
71.2M
        for (i = 0; i < ncomps; i++)
8748
53.4M
            pdc->colors.devn.values[i] = cv[i];
8749
1.10G
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8750
1.08G
            pdc->colors.devn.values[i] = 0;
8751
17.8M
        pdc->type = gx_dc_type_devn;
8752
421M
    } else {
8753
        /* encode as a color index */
8754
421M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8755
        /* check if the encoding was successful; we presume failure is rare */
8756
421M
        if (color != gx_no_color_index)
8757
421M
            color_set_pure(pdc, color);
8758
421M
    }
8759
439M
}
8760
8761
static  void
8762
pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc,
8763
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select,
8764
     const gs_color_space *pcs)
8765
32.4M
{
8766
32.4M
    int i, nc, ncomps;
8767
32.4M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8768
32.4M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8769
32.4M
    gx_color_index color;
8770
32.4M
    gx_device *trans_device;
8771
32.4M
    const gx_device *map_dev;
8772
32.4M
    const gx_cm_color_map_procs *procs;
8773
8774
8775
    /* If trans device is set, we need to use its procs. */
8776
32.4M
    if (pgs->trans_device != NULL){
8777
26.7M
        trans_device = pgs->trans_device;
8778
26.7M
    } else {
8779
5.70M
        trans_device = dev;
8780
5.70M
    }
8781
32.4M
    ncomps = trans_device->color_info.num_components;
8782
8783
    /* Map to the color model. Transfer function is only used
8784
       if we are drawing with an opaque color. */
8785
32.4M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8786
32.4M
    procs->map_cmyk(map_dev, c, m, y, k, cm_comps);
8787
8788
32.4M
    nc = ncomps;
8789
32.4M
    if (device_encodes_tags(trans_device))
8790
0
        nc--;
8791
32.4M
    if (pdf14_state_opaque(trans_device, pgs)) {
8792
145M
        for (i = 0; i < nc; i++)
8793
116M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8794
29.1M
    } else {
8795
16.5M
        for (i = 0; i < nc; i++)
8796
13.2M
            cv[i] = frac2cv(cm_comps[i]);
8797
3.30M
    }
8798
    /* Copy tags untransformed. */
8799
32.4M
    if (nc < ncomps)
8800
0
        cv[nc] = dev->graphics_type_tag;
8801
8802
    /* if output device supports devn, we need to make sure we send it the
8803
       proper color type */
8804
32.4M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8805
47.4M
        for (i = 0; i < ncomps; i++)
8806
37.9M
            pdc->colors.devn.values[i] = cv[i];
8807
578M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8808
569M
            pdc->colors.devn.values[i] = 0;
8809
9.49M
        pdc->type = gx_dc_type_devn;
8810
22.9M
    } else {
8811
        /* encode as a color index */
8812
22.9M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8813
        /* check if the encoding was successful; we presume failure is rare */
8814
22.9M
        if (color != gx_no_color_index)
8815
22.9M
            color_set_pure(pdc, color);
8816
22.9M
    }
8817
32.4M
}
8818
8819
static int
8820
pdf14_get_num_spots(gx_device * dev)
8821
4.81M
{
8822
4.81M
    cmm_dev_profile_t *dev_profile;
8823
4.81M
    cmm_profile_t *icc_profile;
8824
4.81M
    gsicc_rendering_param_t render_cond;
8825
8826
4.81M
    dev_proc(dev, get_profile)(dev, &dev_profile);
8827
4.81M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
8828
4.81M
        &render_cond);
8829
4.81M
    return dev->color_info.num_components - icc_profile->num_comps - device_encodes_tags(dev);
8830
4.81M
}
8831
8832
static  void
8833
pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs,
8834
                 gx_device * dev, gs_color_select_t select, const gs_color_space *pcs)
8835
72.1k
{
8836
72.1k
    int i, nc, ncomps = dev->color_info.num_components;
8837
72.1k
    int num_spots = pdf14_get_num_spots(dev);
8838
72.1k
    bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
8839
72.1k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8840
72.1k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8841
72.1k
    gx_color_index color;
8842
72.1k
    int n = 0;
8843
8844
72.1k
    nc = ncomps;
8845
72.1k
    if (device_encodes_tags(dev))
8846
0
        nc--;
8847
8848
72.1k
    n = additive ? nc - num_spots : 0;
8849
72.1k
    if (pgs->color_component_map.sep_type == SEP_ALL) {
8850
0
        frac comp_value = all;
8851
8852
0
        for (i = pgs->color_component_map.num_colorants - 1; i >= nc - num_spots; i--)
8853
0
            cm_comps[i] = comp_value;
8854
        /*
8855
         * Invert the photometric interpretation for additive
8856
         * color spaces because separations are always subtractive.
8857
         */
8858
0
        if (additive)
8859
0
            comp_value = frac_1 - comp_value;
8860
        /* Use the "all" value for all components */
8861
0
        for (; i >= 0; i--)
8862
0
            cm_comps[i] = comp_value;
8863
72.1k
    } else {
8864
72.1k
        frac comp_value[GX_DEVICE_COLOR_MAX_COMPONENTS];
8865
8866
72.1k
        if (pgs->color_component_map.sep_type == SEP_NONE) {
8867
0
            color_set_null(pdc);
8868
0
            return;
8869
0
        }
8870
8871
        /* map to the color model */
8872
144k
        for (i = pgs->color_component_map.num_components - 1; i >= 0; i--)
8873
72.1k
            comp_value[i] = all;
8874
72.1k
        map_components_to_colorants(comp_value, &(pgs->color_component_map), cm_comps, n);
8875
72.1k
    }
8876
8877
    /* apply the transfer function(s); convert to color values */
8878
81.6k
    for (i = 0; i < n; i++)
8879
72.1k
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8880
351k
    for (; i < nc; i++)
8881
279k
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8882
8883
    /* Copy tags untransformed. */
8884
72.1k
    if (nc < ncomps)
8885
0
        cv[nc] = dev->graphics_type_tag;
8886
8887
    /* if output device supports devn, we need to make sure we send it the
8888
       proper color type */
8889
72.1k
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)) {
8890
360k
        for (i = 0; i < ncomps; i++)
8891
288k
            pdc->colors.devn.values[i] = cv[i];
8892
4.40M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8893
4.32M
            pdc->colors.devn.values[i] = 0;
8894
72.1k
        pdc->type = gx_dc_type_devn;
8895
72.1k
    } else {
8896
        /* encode as a color index */
8897
0
        color = dev_proc(dev, encode_color)(dev, cv);
8898
        /* check if the encoding was successful; we presume failure is rare */
8899
0
        if (color != gx_no_color_index)
8900
0
            color_set_pure(pdc, color);
8901
0
    }
8902
72.1k
}
8903
8904
static  void
8905
pdf14_cmap_devicen_direct(const frac * pcc,
8906
    gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
8907
    gs_color_select_t select, const gs_color_space *pcs)
8908
4.74M
{
8909
4.74M
    int i, nc, ncomps = dev->color_info.num_components;
8910
4.74M
    int num_spots = pdf14_get_num_spots(dev);
8911
4.74M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8912
4.74M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8913
4.74M
    gx_color_index color;
8914
4.74M
    gx_device *trans_device;
8915
4.74M
    int num_add_colorants = 0;
8916
8917
     /*  We may be coming from the clist writer which often forwards us the
8918
         target device. If this occurs we actually need to get to the color
8919
         space defined by the transparency group and we use the operators
8920
         defined by the transparency device to do the job.
8921
       */
8922
4.74M
    if (pgs->trans_device != NULL){
8923
4.74M
        trans_device = pgs->trans_device;
8924
4.74M
    } else {
8925
0
        trans_device = dev;
8926
0
    }
8927
4.74M
    ncomps = trans_device->color_info.num_components;
8928
4.74M
    nc = ncomps;
8929
4.74M
    if (device_encodes_tags(trans_device))
8930
0
        nc--;
8931
8932
4.74M
    if (trans_device->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
8933
0
        num_add_colorants = nc - num_spots;
8934
8935
    /* map to the color model */
8936
4.74M
    map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps, num_add_colorants);
8937
8938
    /* apply the transfer function(s); convert to color values */
8939
    /* The additive ones (if there are any) need to be inverted. */
8940
4.74M
    for (i = 0; i < num_add_colorants; i++)
8941
4.74M
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8942
23.7M
    for (; i < nc; i++)
8943
18.9M
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8944
    /* Copy tags untransformed. */
8945
4.74M
    if (nc < ncomps)
8946
0
        cv[nc] = dev->graphics_type_tag;
8947
8948
    /* if output device supports devn, we need to make sure we send it the
8949
       proper color type */
8950
4.74M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8951
5.16M
        for (i = 0; i < ncomps; i++)
8952
4.13M
            pdc->colors.devn.values[i] = cv[i];
8953
63.0M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8954
62.0M
            pdc->colors.devn.values[i] = 0;
8955
1.03M
        pdc->type = gx_dc_type_devn;
8956
3.71M
    } else {
8957
    /* encode as a color index */
8958
3.71M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8959
        /* check if the encoding was successful; we presume failure is rare */
8960
3.71M
        if (color != gx_no_color_index)
8961
3.71M
            color_set_pure(pdc, color);
8962
3.71M
    }
8963
4.74M
}
8964
8965
static  bool
8966
pdf14_cmap_is_halftoned(const gs_gstate * pgs, gx_device * dev)
8967
467k
{
8968
467k
    return false;
8969
467k
}
8970
8971
static  const gx_color_map_procs *
8972
pdf14_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev)
8973
3.69M
{
8974
    /* The pdf14 marking device itself is always continuous tone. */
8975
3.69M
    return &pdf14_cmap_many;
8976
3.69M
}
8977
8978
static int
8979
pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op,
8980
                  void *data, int size)
8981
1.11G
{
8982
1.11G
    pdf14_device * p14dev = (pdf14_device *)pdev;
8983
8984
1.11G
    if (dev_spec_op == gxdso_supports_pattern_transparency)
8985
2.52M
        return 1;
8986
1.11G
    if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path)
8987
76.3k
        return 1;
8988
1.11G
    if (dev_spec_op == gxdso_is_pdf14_device) {
8989
1.90k
        if (data != NULL && size == sizeof(gx_device *))
8990
798
            *(gx_device **)data = pdev;
8991
1.90k
        return 1;
8992
1.90k
    }
8993
1.11G
    if (dev_spec_op == gxdso_device_child) {
8994
4.90k
        pdf14_device *dev = (pdf14_device *)pdev;
8995
4.90k
        gxdso_device_child_request *d = (gxdso_device_child_request *)data;
8996
4.90k
        if (d->target == pdev) {
8997
4.90k
            d->target = dev->target;
8998
4.90k
            return 1;
8999
4.90k
        }
9000
4.90k
    }
9001
1.11G
    if (dev_spec_op == gxdso_supports_devn
9002
589M
     || dev_spec_op == gxdso_skip_icc_component_validation) {
9003
589M
        cmm_dev_profile_t *dev_profile;
9004
589M
        int code;
9005
589M
        code = dev_proc(pdev, get_profile)((gx_device*) pdev, &dev_profile);
9006
589M
        if (code == 0) {
9007
589M
            return dev_profile->supports_devn;
9008
589M
        } else {
9009
0
            return 0;
9010
0
        }
9011
589M
    }
9012
524M
    if (dev_spec_op == gxdso_pdf14_sep_device) {
9013
739k
        pdf14_device* dev = (pdf14_device*)pdev;
9014
9015
739k
        if (strcmp(dev->dname, "pdf14cmykspot") == 0 ||
9016
739k
            strcmp(dev->dname, "pdf14clistcmykspot") == 0)
9017
292k
            return 1;
9018
447k
        return 0;
9019
739k
    }
9020
523M
    if (dev_spec_op == gxdso_is_encoding_direct)
9021
861k
        return 1;
9022
9023
    /* We don't want to pass on these spec_ops either, because the child might respond
9024
     * with an inappropriate response when the PDF14 device is active. For example; the
9025
     * JPEG passthrough will give utterly wrong results if we pass that to a device which
9026
     * supports JPEG passthrough, because the pdf14 device needs to render the image.
9027
     */
9028
522M
    if (dev_spec_op == gxdso_in_pattern_accumulator)
9029
844k
        return 0;
9030
522M
    if (dev_spec_op == gxdso_copy_color_is_fast)
9031
446k
        return 0;
9032
521M
    if(dev_spec_op == gxdso_pattern_handles_clip_path)
9033
75.6k
        return 0;
9034
521M
    if(dev_spec_op == gxdso_supports_hlcolor)
9035
2.08k
        return 0;
9036
521M
    if(dev_spec_op == gxdso_pattern_can_accum)
9037
181k
        return 0;
9038
521M
    if(dev_spec_op == gxdso_JPEG_passthrough_query)
9039
3.95k
        return 0;
9040
521M
    if (dev_spec_op == gxdso_overprint_active) {
9041
8.83M
        if (p14dev->pclist_device != NULL) {
9042
8.79M
            return dev_proc(p14dev->pclist_device, dev_spec_op)(p14dev->pclist_device, dev_spec_op, data, size);
9043
8.79M
        } else {
9044
37.4k
            return p14dev->overprint || p14dev->stroke_overprint;
9045
37.4k
        }
9046
8.83M
    }
9047
9048
    /* These should be coming only from the abuf device
9049
       during fill-stroke operation. Any other use will
9050
       result in bad things. */
9051
512M
    if (dev_spec_op == gxdso_abuf_optrans)
9052
0
    {
9053
0
        int ret = p14dev->op_state;
9054
0
        overprint_abuf_state_t *state_data = (overprint_abuf_state_t *)data;
9055
0
        pdf14_abuf_state_t *pdf14_abuf = (pdf14_abuf_state_t *)&state_data->storage[0];
9056
0
        const gs_gstate* cpgs = state_data->pgs;
9057
0
        union {
9058
0
            const gs_gstate* cpgs;
9059
0
            gs_gstate* pgs;
9060
0
        } const_breaker;
9061
0
        gs_gstate* pgs;
9062
0
        int code = 0;
9063
0
        int code1 = 0;
9064
9065
        /* A compile time assert to check our storage types are appropriately sized. */
9066
0
        typedef char compile_time_assert[sizeof(pdf14_abuf_state_t) <= sizeof(state_data->storage) ? 1 : -1];
9067
9068
        /* I don't really like this, but there is no easy way around it. The device
9069
           in the pgs needs to be the pdf14 device to ensure that the compositor
9070
           actions occur with the gs_transparency calls. We have to call at that
9071
           level (as opposed to the gx_ or pdf14_ level) to ensure that the clist
9072
           operations are invoked. We could change the gs_trans calls to take a
9073
           device to avoid this dance but that changes the device procs. */
9074
0
        gx_device *curr_dev;
9075
9076
0
        const_breaker.cpgs = cpgs;
9077
0
        pgs = const_breaker.pgs;
9078
0
        curr_dev = pgs->device;
9079
0
        pgs->device = pdev;
9080
9081
0
        switch (state_data->op_trans) {
9082
9083
0
            case OP_FS_TRANS_PREFILL:
9084
0
                pdf14_abuf->orig_state = p14dev->op_state;
9085
0
                pdf14_abuf->blend_mode = cpgs->blend_mode;
9086
0
                pdf14_abuf->fill_alpha = cpgs->fillconstantalpha;
9087
0
                pdf14_abuf->stroke_alpha = cpgs->strokeconstantalpha;
9088
0
                pdf14_abuf->pgs = pgs; /* ref count? only used for this back and forth so ok */
9089
0
                if (pdf14_abuf->fill_alpha == 1.0 && pdf14_abuf->stroke_alpha == 1.0 &&
9090
0
                    pdf14_abuf->blend_mode == BLEND_MODE_Normal)
9091
0
                    pdf14_abuf->group_needed = false;
9092
0
                else
9093
0
                    pdf14_abuf->group_needed = true;
9094
9095
0
                if (pdf14_abuf->group_needed) {
9096
0
                    code = pdf14_fill_stroke_prefill(pdev, pgs, state_data->ppath,
9097
0
                        state_data->pcpath, pdf14_abuf->fill_alpha,
9098
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode,
9099
0
                        &(pdf14_abuf->op_ca_eq_CA), &(pdf14_abuf->path_empty),
9100
0
                        state_data->alpha_buf_path_scale);
9101
0
                    if (code < 0)
9102
0
                        goto cleanup;
9103
0
                }
9104
0
                code = gs_update_trans_marking_params(pgs);
9105
0
                break;
9106
9107
0
            case OP_FS_TRANS_PRESTROKE:
9108
0
                if (pdf14_abuf->group_needed) {
9109
0
                    pdf14_fill_stroke_prestroke(pdev, pdf14_abuf->pgs, pdf14_abuf->stroke_alpha,
9110
0
                                                pdf14_abuf->blend_mode, pdf14_abuf->op_ca_eq_CA);
9111
0
                }
9112
0
                code = gs_update_trans_marking_params(pgs);
9113
0
                break;
9114
9115
0
            case OP_FS_TRANS_POSTSTROKE:
9116
0
                if (pdf14_abuf->group_needed) {
9117
0
                    code = pdf14_fill_stroke_poststroke(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9118
0
                                                        pdf14_abuf->op_ca_eq_CA);
9119
0
                }
9120
0
                if (code >= 0)
9121
0
                    code = gs_update_trans_marking_params(pgs);
9122
9123
                /* fallthrough */
9124
9125
0
            case OP_FS_TRANS_CLEANUP:
9126
0
cleanup:
9127
0
                if (pdf14_abuf->group_needed) {
9128
0
                    code1 = pdf14_fill_stroke_cleanup(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9129
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode, (PDF14_OP_FS_STATE)pdf14_abuf->orig_state);
9130
0
                    if (code1 < 0)
9131
0
                        code = gs_note_error(gs_error_Fatal);
9132
0
                }
9133
0
                break;
9134
0
        }
9135
0
        pgs->device = curr_dev;
9136
9137
0
        return (code < 0) ? code : ret;
9138
0
    }
9139
9140
512M
    if (dev_spec_op == gxdso_in_smask_construction)
9141
9.10M
        return p14dev->in_smask_construction > 0;
9142
503M
    if (dev_spec_op == gxdso_in_smask)
9143
467M
        return p14dev->in_smask_construction > 0 || p14dev->depth_within_smask;
9144
35.5M
    if (dev_spec_op == gxdso_replacecolor) {
9145
34.6M
        gx_device *tdev = p14dev->target;
9146
34.6M
        cmm_dev_profile_t *tdev_profile;
9147
34.6M
        int code;
9148
9149
         /* If in a softmask or softmask construction do not allow
9150
           replacement. */
9151
34.6M
        if (p14dev->in_smask_construction > 0 || p14dev->depth_within_smask)
9152
808k
            return 0;
9153
9154
        /* If the target CS is different than the pdf14 profile add this information
9155
           for the target device that will be handling the replacement. While not
9156
           perfect this at least lets you do the replacehment and have some information
9157
           about what the situation is. */
9158
33.8M
        code = dev_proc(tdev, get_profile)((gx_device*) tdev, &tdev_profile);
9159
33.8M
        if (code != 0)
9160
0
            return 0;
9161
9162
33.8M
        if (tdev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode !=
9163
33.8M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode) {
9164
23.1M
            color_replace_t* replace_data = (color_replace_t*)data;
9165
            /* Not ref counted as data is on the stack (from gx_remap_ICC) and we should be fine during this
9166
               color remap operation. */
9167
23.1M
            replace_data->pdf14_iccprofile = p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
9168
23.1M
        }
9169
9170
        /* Pass on to target device */
9171
33.8M
        return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9172
33.8M
    }
9173
931k
    if (dev_spec_op == gxdso_device_insert_child) {
9174
434
        gx_device *tdev = p14dev->target;
9175
434
        p14dev->target = (gx_device *)data;
9176
434
        rc_increment(p14dev->target);
9177
434
        rc_decrement_only(tdev, "pdf14_dev_spec_op");
9178
434
        return 0;
9179
434
    }
9180
930k
    if (dev_spec_op == gxdso_interpolate_threshold)
9181
19.6k
        return p14dev->interpolate_threshold;
9182
9183
911k
    if (dev_spec_op == gxdso_overprintsim_state) {
9184
19.6k
        unsigned char *data_uchar = (unsigned char *) data;
9185
19.6k
        data_uchar[0] = (unsigned char) p14dev->overprint_sim;
9186
19.6k
        if (p14dev->ctx != NULL)
9187
18
            data_uchar[1] = (unsigned char)p14dev->ctx->num_spots; /* pdf14 page device */
9188
19.5k
        else
9189
19.5k
            data_uchar[1] = (unsigned char)p14dev->devn_params.page_spot_colors;  /* pdf14 clist device */
9190
19.6k
        return 1;
9191
19.6k
    }
9192
9193
891k
    return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9194
911k
}
9195
9196
/* Needed to set color monitoring in the target device's profile */
9197
int
9198
gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring)
9199
0
{
9200
0
    pdf14_device * p14dev = (pdf14_device *)pdev;
9201
0
    gx_device *targ = p14dev->target;
9202
0
    cmm_dev_profile_t *dev_profile;
9203
0
    int code = dev_proc(targ, get_profile)((gx_device*) targ, &dev_profile);
9204
9205
0
    if (code == 0)
9206
0
        dev_profile->pageneutralcolor = monitoring;
9207
0
    return code;
9208
0
}
9209
9210
static int
9211
gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
9212
        gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct)
9213
1.96M
{
9214
1.96M
    pdf14_device dev_proto;
9215
1.96M
    pdf14_device * p14dev;
9216
1.96M
    int code;
9217
1.96M
    bool has_tags;
9218
1.96M
    cmm_profile_t *icc_profile;
9219
1.96M
    gsicc_rendering_param_t render_cond;
9220
1.96M
    cmm_dev_profile_t *dev_profile;
9221
1.96M
    uchar k;
9222
1.96M
    int max_bitmap;
9223
1.96M
    bool use_pdf14_accum = false;
9224
1.96M
    bool deep;
9225
9226
    /* Guard against later seg faults, this should not be possible */
9227
1.96M
    if (target == NULL)
9228
0
        return gs_throw_code(gs_error_Fatal);
9229
9230
1.96M
    has_tags = device_encodes_tags(target);
9231
1.96M
    deep = device_is_deep(target);
9232
1.96M
    max_bitmap = target->space_params.MaxBitmap == 0 ? MAX_BITMAP :
9233
1.96M
                                 target->space_params.MaxBitmap;
9234
    /* If the device is not a printer class device, it won't support saved-pages */
9235
    /* and so we may need to make a clist device in order to prevent very large  */
9236
    /* or high resolution pages from having allocation problems.                 */
9237
    /* We use MaxBitmap to decide when a clist is needed.*/
9238
1.96M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_saved_pages, NULL, 0) <= 0 &&
9239
10.2k
        gx_device_is_pattern_clist(target) == 0 &&
9240
10.2k
        gx_device_is_pattern_accum(target) == 0 &&
9241
7.25k
        gs_device_is_memory(target) == 0) {
9242
9243
7.25k
        uint32_t pdf14_trans_buffer_size =
9244
7.25k
              (ESTIMATED_PDF14_ROW_SPACE(max(1, target->width),
9245
7.25k
                                         target->color_info.num_components,
9246
7.25k
                                         deep ? 16 : 8) >> 3);
9247
9248
7.25k
        if (target->height < max_ulong / pdf14_trans_buffer_size)
9249
7.25k
                pdf14_trans_buffer_size *= target->height;
9250
0
        else
9251
0
                max_bitmap = 0;     /* Force decision to clist */
9252
7.25k
        if (pdf14_trans_buffer_size > max_bitmap)
9253
6.74k
            use_pdf14_accum = true;
9254
7.25k
    }
9255
1.96M
    code = dev_proc(target, get_profile)(target,  &dev_profile);
9256
1.96M
    if (code < 0)
9257
0
        return code;
9258
1.96M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9259
1.96M
                          &render_cond);
9260
1.96M
    if_debug0m('v', mem, "[v]gs_pdf14_device_push\n");
9261
9262
    /* Get the proto from which to copy the device. This will always
9263
     * ignore tags! */
9264
1.96M
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
9265
1.96M
                                  pdf14pct, use_pdf14_accum);
9266
1.96M
    if (code < 0)
9267
0
        return code;
9268
1.96M
    code = gs_copydevice((gx_device **) &p14dev,
9269
1.96M
                         (const gx_device *) &dev_proto, mem);
9270
1.96M
    if (code < 0)
9271
0
        return code;
9272
9273
1.96M
    p14dev->graphics_type_tag = target->graphics_type_tag;
9274
9275
    /* Copying the params across will add tags to the colorinfo as required. */
9276
1.96M
    code = gs_pdf14_device_copy_params((gx_device *)p14dev, target);
9277
1.96M
    if (code < 0)
9278
0
        return code;
9279
9280
1.96M
    gx_device_set_target((gx_device_forward *)p14dev, target);
9281
1.96M
    p14dev->pad = target->pad;
9282
1.96M
    p14dev->log2_align_mod = target->log2_align_mod;
9283
1.96M
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0) {
9284
0
        p14dev->num_planar_planes = p14dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
9285
0
        p14dev->color_info.num_components = p14dev->num_planar_planes;
9286
0
    }
9287
1.96M
    else if (pdf14pct->params.overprint_sim_push && target->num_planar_planes != 0) {
9288
0
        p14dev->num_planar_planes = p14dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
9289
0
        p14dev->color_info.num_components = p14dev->num_planar_planes;
9290
0
    }
9291
1.96M
    else
9292
1.96M
        p14dev->num_planar_planes = target->num_planar_planes;
9293
1.96M
    p14dev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
9294
9295
1.96M
    p14dev->alpha = 1.0;
9296
1.96M
    p14dev->shape = 1.0;
9297
1.96M
    p14dev->opacity = 1.0;
9298
1.96M
    p14dev->fillconstantalpha = 1.0;
9299
1.96M
    p14dev->strokeconstantalpha = 1.0;
9300
9301
    /* Simulated overprint case.  We have to use CMYK-based profile.  Also if the target
9302
       profile is NCLR, we are going to use a pdf14 device that is CMYK based and
9303
       do the mapping to the NCLR profile when the put_image occurs */
9304
1.96M
    if ((p14dev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
9305
1.96M
        icc_profile->data_cs == gsNCHANNEL) {
9306
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "gs_pdf14_device_push");
9307
0
        gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9308
0
            -1, "gs_pdf14_device_push");
9309
0
        p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
9310
1.96M
    } else {
9311
        /* If the target profile was CIELAB (and we are not using a blend CS),
9312
           then overide with default RGB for proper blending.  During put_image
9313
           we will convert from RGB to CIELAB.  Need to check that we have a
9314
           default profile, which will not be the case if we are coming from the clist reader */
9315
1.96M
        if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab)
9316
0
            && pgs->icc_manager->default_rgb != NULL &&
9317
0
            p14dev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
9318
0
            p14dev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
9319
0
            gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "gs_pdf14_device_push");
9320
0
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9321
0
                -1, "gs_pdf14_device_push");
9322
0
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_rgb;
9323
0
        }
9324
1.96M
    }
9325
9326
1.96M
    if (pdf14pct->params.overprint_sim_push &&
9327
0
        pdf14pct->params.num_spot_colors_int > 0) {
9328
0
        p14dev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
9329
0
        p14dev->procs.ret_devn_params = pdf14_ret_devn_params;
9330
0
        p14dev->op_pequiv_cmyk_colors.all_color_info_valid = false;
9331
0
        p14dev->target_support_devn = p14dev->icc_struct->supports_devn;
9332
0
        p14dev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
9333
0
    }
9334
9335
    /* The number of color planes should not exceed that of the target.
9336
       Unless we are using a blend CS */
9337
1.96M
    if (!(p14dev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || p14dev->overprint_sim)) {
9338
1.96M
        if (p14dev->color_info.num_components > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev))
9339
0
            p14dev->color_info.num_components = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev);
9340
1.96M
        if (p14dev->color_info.max_components > target->color_info.max_components)
9341
158k
            p14dev->color_info.max_components = target->color_info.max_components;
9342
1.96M
    }
9343
1.96M
    p14dev->color_info.depth = p14dev->color_info.num_components * (8<<deep);
9344
    /* If we have a tag device then go ahead and do a special encoder
9345
       decoder for the pdf14 device to make sure we maintain this
9346
       information in the encoded color information.  We could use
9347
       the target device's methods but the PDF14 device has to maintain
9348
       8 bit color always and we could run into other issues if the number
9349
       of colorants became large.  If we need to do compressed color with
9350
       tags that will be a special project at that time */
9351
1.96M
    if (deep) {
9352
0
        set_dev_proc(p14dev, encode_color, pdf14_encode_color16);
9353
0
        set_dev_proc(p14dev, decode_color, pdf14_decode_color16);
9354
0
    }
9355
1.96M
    if (has_tags) {
9356
0
        set_dev_proc(p14dev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
9357
0
    }
9358
    /* if the device has separations already defined (by SeparationOrderNames) */
9359
    /* we need to copy them (allocating new names) so the colorants are in the */
9360
    /* same order as the target device.                                        */
9361
1.96M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0)) {
9362
158k
        code = devn_copy_params(target, (gx_device *)p14dev);
9363
158k
        if (code < 0) {
9364
60
            *pdev = NULL;
9365
60
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9366
60
            rc_decrement(p14dev, "gs_pdf14_device_push");
9367
60
            return code;
9368
60
        }
9369
158k
    }
9370
    /* by definition pdf14_encode _is_ standard */
9371
1.96M
    p14dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
9372
1.96M
    gx_device_fill_in_procs((gx_device *)p14dev);
9373
1.96M
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
9374
1.96M
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
9375
1.96M
    gx_set_cmap_procs(pgs, (gx_device *)p14dev);
9376
9377
    /* Components shift, etc have to be based upon 8 (or 16) bit */
9378
6.85M
    for (k = 0; k < p14dev->color_info.num_components; k++) {
9379
4.89M
        p14dev->color_info.comp_bits[k] = 8<<deep;
9380
4.89M
        p14dev->color_info.comp_shift[k] =
9381
4.89M
                            (p14dev->color_info.num_components - 1 - k) * (8<<deep);
9382
4.89M
    }
9383
1.96M
    if (use_pdf14_accum) {
9384
        /* we will disable this device later, but we don't want to allocate large buffers */
9385
6.74k
        p14dev->width = 1;
9386
6.74k
        p14dev->height = 1;
9387
6.74k
    }
9388
9389
1.96M
    p14dev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
9390
1.96M
    code = dev_proc((gx_device *) p14dev, open_device) ((gx_device *) p14dev);
9391
1.96M
    *pdev = (gx_device *) p14dev;
9392
1.96M
    pdf14_set_marking_params((gx_device *)p14dev, pgs);
9393
1.96M
    p14dev->color_model_stack = NULL;
9394
9395
    /* In case we have alphabits set */
9396
1.96M
    p14dev->color_info.anti_alias = target->color_info.anti_alias;
9397
9398
1.96M
    if (pdf14pct->params.is_pattern) {
9399
22.0k
        code = pdf14_initialize_ctx((gx_device*)p14dev, pgs);
9400
22.0k
        if (code < 0) {
9401
0
            *pdev = NULL;
9402
0
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9403
0
            rc_decrement(p14dev, "gs_pdf14_device_push");
9404
0
            return code;
9405
0
        }
9406
22.0k
    }
9407
9408
    /* We should never go into this when using a blend color space */
9409
1.96M
    if (use_pdf14_accum) {
9410
6.74k
        const gx_device_pdf14_accum *accum_proto = NULL;
9411
6.74k
        gx_device *new_target = NULL;
9412
6.74k
        gx_device_color pdcolor;
9413
6.74k
        frac pconc_white = frac_1;
9414
6.74k
        bool UsePlanarBuffer = false;
9415
9416
6.74k
        if_debug0m('v', mem, "[v]gs_pdf14_device_push: Inserting clist device.\n");
9417
9418
        /* get the prototype for the accumulator device based on colorspace */
9419
6.74k
        switch (target->color_info.max_components) { /* use max_components in case is devn device */
9420
1.35k
            case 1:
9421
1.35k
                accum_proto = &pdf14_accum_Gray;
9422
1.35k
                break;
9423
5.39k
            case 3:
9424
5.39k
                accum_proto = &pdf14_accum_RGB;
9425
5.39k
                break;
9426
0
            case 4:
9427
0
                accum_proto = &pdf14_accum_CMYK;
9428
0
                break;
9429
0
            default:
9430
0
                accum_proto = &pdf14_accum_CMYKspot;
9431
0
                UsePlanarBuffer = true;
9432
6.74k
        }
9433
6.74k
        if (accum_proto == NULL ||
9434
6.74k
            (code = gs_copydevice(&new_target, (gx_device *)accum_proto, mem->stable_memory)) < 0)
9435
0
            goto no_clist_accum;
9436
9437
6.74k
        ((gx_device_pdf14_accum *)new_target)->save_p14dev = (gx_device *)p14dev;  /* non-clist p14dev */
9438
        /* Fill in values from the target device before opening */
9439
6.74k
        new_target->color_info = p14dev->color_info;
9440
6.74k
        ((gx_device_pdf14_accum *)new_target)->devn_params = p14dev->devn_params;
9441
6.74k
        new_target->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
9442
6.74k
        set_linear_color_bits_mask_shift(new_target);
9443
6.74k
        gs_pdf14_device_copy_params(new_target, target);
9444
6.74k
        ((gx_device_pdf14_accum *)new_target)->page_uses_transparency = true;
9445
6.74k
        gx_device_fill_in_procs(new_target);
9446
9447
6.74k
        memcpy(&(new_target->space_params), &(target->space_params), sizeof(gdev_space_params));
9448
6.74k
        max_bitmap = max(target->space_params.MaxBitmap, target->space_params.BufferSpace);
9449
6.74k
        ((gx_device_pdf14_accum *)new_target)->space_params.BufferSpace = max_bitmap;
9450
9451
        /* This is used to mark the various internal subclass devices as having already
9452
         * been pushed, so that opening the device won't result in us trying to push
9453
         * them again, which leads to trouble.
9454
         */
9455
6.74k
        code = mark_internal_subclass_devices(new_target);
9456
6.74k
        if (code < 0)
9457
0
            return code;
9458
9459
        /* if the device has separations already defined (by SeparationOrderNames) */
9460
        /* we need to copy them (allocating new names) so the colorants are in the */
9461
        /* same order as the target device.                                        */
9462
6.74k
        if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0)) {
9463
0
            code = devn_copy_params(target, (gx_device *)*pdev);
9464
0
            if (code < 0)
9465
0
                return code;
9466
0
        }
9467
        /* UsePlanarBuffer is true in case this is CMYKspot */
9468
6.74k
        if ((code = gdev_prn_open_planar(new_target, UsePlanarBuffer ? new_target->color_info.num_components : 0)) < 0 ||
9469
6.74k
             !PRINTER_IS_CLIST((gx_device_printer *)new_target)) {
9470
0
            gs_free_object(mem->stable_memory, new_target, "pdf14-accum");
9471
0
            goto no_clist_accum;
9472
0
        }
9473
        /* Do the initial fillpage into the pdf14-accum device we just created */
9474
6.74k
        dev_proc(new_target, set_graphics_type_tag)((gx_device *)new_target, GS_UNTOUCHED_TAG);
9475
6.74k
        if ((code = gx_remap_concrete_DGray(gs_currentcolorspace_inline((gs_gstate *)pgs),
9476
6.74k
                                            &pconc_white,
9477
6.74k
                                            &pdcolor, pgs, new_target, gs_color_select_all,
9478
6.74k
                                            dev_profile)) < 0)
9479
0
            goto no_clist_accum;
9480
9481
6.74k
        (*dev_proc(new_target, fillpage))(new_target, pgs, &pdcolor);
9482
6.74k
        code = clist_composite(new_target, pdev, (gs_composite_t *)pdf14pct, pgs, mem, NULL);
9483
6.74k
        if (code < 0)
9484
0
            goto no_clist_accum;
9485
9486
6.74k
        pdf14_disable_device((gx_device *)p14dev);           /* make the non-clist device forward */
9487
6.74k
        pdf14_close((gx_device *)p14dev);                    /* and free up the little memory it had */
9488
6.74k
    }
9489
1.96M
    return code;
9490
9491
0
no_clist_accum:
9492
        /* FIXME: We allocated a really small p14dev, but that won't work */
9493
0
    return gs_throw_code(gs_error_Fatal); /* punt for now */
9494
1.96M
}
9495
9496
/*
9497
 * In a modest violation of good coding practice, the gs_composite_common
9498
 * fields are "known" to be simple (contain no pointers to garbage
9499
 * collected memory), and we also know the gs_pdf14trans_params_t structure
9500
 * to be simple, so we just create a trivial structure descriptor for the
9501
 * entire gs_pdf14trans_s structure.
9502
 */
9503
#define private_st_gs_pdf14trans_t()\
9504
  gs_private_st_ptrs2(st_pdf14trans, gs_pdf14trans_t, "gs_pdf14trans_t",\
9505
      st_pdf14trans_enum_ptrs, st_pdf14trans_reloc_ptrs, params.transfer_function, params.iccprofile)
9506
9507
/* GC descriptor for gs_pdf14trans_t */
9508
private_st_gs_pdf14trans_t();
9509
9510
/*
9511
 * Check for equality of two PDF 1.4 transparency compositor objects.
9512
 *
9513
 * We are currently always indicating that PDF 1.4 transparency compositors are
9514
 * equal.  Two transparency compositors may have teh same data but still
9515
 * represent separate actions.  (E.g. two PDF14_BEGIN_TRANS_GROUP compositor
9516
 * operations in a row mean that we are creating a group inside of a group.
9517
 */
9518
static  bool
9519
c_pdf14trans_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
9520
0
{
9521
0
    return false;
9522
0
}
9523
9524
#ifdef DEBUG
9525
static const char * pdf14_opcode_names[] = PDF14_OPCODE_NAMES;
9526
#endif
9527
9528
#define put_value(dp, value)\
9529
13.6M
    BEGIN\
9530
13.6M
        memcpy(dp, &value, sizeof(value));\
9531
13.6M
        dp += sizeof(value);\
9532
13.6M
    END
9533
9534
static inline int
9535
c_pdf14trans_write_ctm(byte **ppbuf, const gs_pdf14trans_params_t *pparams)
9536
1.59M
{
9537
    /* Note: We can't skip writing CTM if it is equal to pgs->ctm,
9538
       because clist writer may skip this command for some bands.
9539
       For a better result we need individual CTM for each band.
9540
     */
9541
1.59M
    byte *pbuf = *ppbuf;
9542
1.59M
    int len, code;
9543
9544
1.59M
    len = cmd_write_ctm_return_length_nodevice(&pparams->ctm);
9545
1.59M
    pbuf--; /* For cmd_write_ctm. */
9546
1.59M
    code = cmd_write_ctm(&pparams->ctm, pbuf, len);
9547
1.59M
    if (code < 0)
9548
0
        return code;
9549
1.59M
    pbuf += len + 1;
9550
1.59M
    *ppbuf = pbuf;
9551
1.59M
    return 0;
9552
1.59M
}
9553
9554
/*
9555
 * Convert a PDF 1.4 transparency compositor to string form for use by the command
9556
 * list device. This is also where we update the pdf14_needed. When set the clist
9557
 * painting procs will update the trans_bbox state for bands that are affected.
9558
*/
9559
static  int
9560
c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
9561
                   gx_device_clist_writer *cdev)
9562
3.87M
{
9563
3.87M
    const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
9564
3.87M
    int need, avail = *psize;
9565
3.87M
    byte buf[MAX_CLIST_TRANSPARENCY_BUFFER_SIZE]; /* Must be large enough
9566
        to fit the data written below. We don't implement a dynamic check for
9567
        the buffer owerflow, assuming that the consistency is verified in the
9568
        coding phase. See the definition of MAX_CLIST_TRANSPARENCY_BUFFER_SIZE. */
9569
3.87M
    byte * pbuf = buf;
9570
3.87M
    int opcode = pparams->pdf14_op;
9571
3.87M
    int mask_size = 0;
9572
3.87M
    uint mask_id = 0;
9573
3.87M
    int code;
9574
3.87M
    bool found_icc;
9575
3.87M
    int64_t hashcode = 0;
9576
3.87M
    cmm_profile_t *icc_profile;
9577
3.87M
    gsicc_rendering_param_t render_cond;
9578
3.87M
    cmm_dev_profile_t *dev_profile;
9579
    /* We maintain and update working copies until we actually write the clist */
9580
3.87M
    int pdf14_needed = cdev->pdf14_needed;
9581
3.87M
    int trans_group_level = cdev->pdf14_trans_group_level;
9582
3.87M
    int smask_level = cdev->pdf14_smask_level;
9583
3.87M
    bool deep = device_is_deep((gx_device *)cdev);
9584
9585
3.87M
    code = dev_proc((gx_device *) cdev, get_profile)((gx_device *) cdev,
9586
3.87M
                                                     &dev_profile);
9587
3.87M
    if (code < 0)
9588
0
        return code;
9589
3.87M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9590
3.87M
                          &render_cond);
9591
3.87M
    *pbuf++ = opcode;     /* 1 byte */
9592
3.87M
    if (trans_group_level < 0 && opcode != PDF14_PUSH_DEVICE)
9593
5
        return_error(gs_error_unregistered); /* prevent spurious transparency ops (Bug 702327) */
9594
9595
3.87M
    switch (opcode) {
9596
0
        default:      /* Should not occur. */
9597
0
            break;
9598
34.4k
        case PDF14_PUSH_DEVICE:
9599
34.4k
            trans_group_level = 0;
9600
34.4k
            cdev->pdf14_smask_level = 0;
9601
34.4k
            cdev->page_pdf14_needed = false;
9602
34.4k
            put_value(pbuf, pparams->num_spot_colors);
9603
34.4k
            put_value(pbuf, pparams->num_spot_colors_int);
9604
34.4k
            put_value(pbuf, pparams->overprint_sim_push);
9605
34.4k
            put_value(pbuf, pparams->is_pattern);
9606
9607
            /* If we happen to be going to a color space like CIELAB then
9608
               we are going to do our blending in default RGB and convert
9609
               to CIELAB at the end.  To do this, we need to store the
9610
               default RGB profile in the clist so that we can grab it
9611
               later on during the clist read back and put image command */
9612
34.4k
            if (icc_profile->data_cs == gsCIELAB || icc_profile->islab) {
9613
                /* Get the default RGB profile.  Set the device hash code
9614
                   so that we can extract it during the put_image operation. */
9615
0
                cdev->trans_dev_icc_hash = gsicc_get_hash(pparams->iccprofile);
9616
0
                found_icc =
9617
0
                    clist_icc_searchtable(cdev, gsicc_get_hash(pparams->iccprofile));
9618
0
                if (!found_icc) {
9619
                    /* Add it to the table */
9620
0
                    clist_icc_addentry(cdev, gsicc_get_hash(pparams->iccprofile),
9621
0
                                       pparams->iccprofile);
9622
0
                }
9623
0
            }
9624
34.4k
            break;
9625
32.8k
        case PDF14_POP_DEVICE:
9626
32.8k
            pdf14_needed = false;   /* reset pdf14_needed */
9627
32.8k
            trans_group_level = -1;   /* reset so we need to PUSH_DEVICE next */
9628
32.8k
            smask_level = 0;
9629
32.8k
            put_value(pbuf, pparams->is_pattern);
9630
32.8k
            break;
9631
858k
        case PDF14_END_TRANS_GROUP:
9632
867k
        case PDF14_END_TRANS_TEXT_GROUP:
9633
867k
            trans_group_level--;  /* if now at page level, pdf14_needed will be updated */
9634
867k
            if (smask_level == 0 && trans_group_level == 0)
9635
49.0k
                pdf14_needed = cdev->page_pdf14_needed;
9636
867k
            break;      /* No data */
9637
13.6k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9638
867k
        case PDF14_BEGIN_TRANS_GROUP:
9639
867k
            pdf14_needed = true;   /* the compositor will be needed while reading */
9640
867k
            trans_group_level++;
9641
867k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9642
867k
            if (code < 0)
9643
0
                return code;
9644
867k
            *pbuf++ = (pparams->Isolated & 1) + ((pparams->Knockout & 1) << 1);
9645
867k
            *pbuf++ = pparams->blend_mode;
9646
867k
            *pbuf++ = pparams->group_color_type;
9647
867k
            *pbuf++ = pparams->page_group;
9648
867k
            put_value(pbuf, pparams->group_color_numcomps);
9649
867k
            put_value(pbuf, pparams->opacity);
9650
867k
            put_value(pbuf, pparams->shape);
9651
867k
            put_value(pbuf, pparams->bbox);
9652
867k
            put_value(pbuf, pparams->shade_group);
9653
867k
            put_value(pbuf, pparams->text_group);
9654
867k
            mask_id = pparams->mask_id;
9655
867k
            put_value(pbuf, mask_id);
9656
            /* Color space information maybe ICC based
9657
               in this case we need to store the ICC
9658
               profile or the ID if it is cached already */
9659
867k
            if (pparams->group_color_type == ICC) {
9660
                /* Check if it is already in the ICC clist table */
9661
25.3k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9662
25.3k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9663
25.3k
                if (!found_icc) {
9664
                    /* Add it to the table */
9665
7.34k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9666
7.34k
                    put_value(pbuf, hashcode);
9667
18.0k
                } else {
9668
                    /* It will be in the clist. Just write out the hashcode */
9669
18.0k
                    put_value(pbuf, hashcode);
9670
18.0k
                }
9671
842k
            } else {
9672
842k
                put_value(pbuf, hashcode);
9673
842k
            }
9674
867k
            break;
9675
725k
        case PDF14_BEGIN_TRANS_MASK:
9676
725k
            if (pparams->subtype != TRANSPARENCY_MASK_None) {
9677
618k
                pdf14_needed = true;   /* the compositor will be needed while reading */
9678
618k
                smask_level++;
9679
618k
            }
9680
725k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9681
725k
            if (code < 0)
9682
0
                return code;
9683
725k
            put_value(pbuf, pparams->subtype);
9684
725k
            *pbuf++ = pparams->group_color_type;
9685
725k
            put_value(pbuf, pparams->group_color_numcomps);
9686
725k
            *pbuf++ = pparams->replacing;
9687
725k
            *pbuf++ = (pparams->function_is_identity) | (deep<<1);
9688
725k
            *pbuf++ = pparams->Background_components;
9689
725k
            *pbuf++ = pparams->Matte_components;
9690
725k
            put_value(pbuf, pparams->bbox);
9691
725k
            mask_id = pparams->mask_id;
9692
725k
            put_value(pbuf, mask_id);
9693
725k
            if (pparams->Background_components) {
9694
5.87k
                const int l = sizeof(pparams->Background[0]) * pparams->Background_components;
9695
9696
5.87k
                memcpy(pbuf, pparams->Background, l);
9697
5.87k
                pbuf += l;
9698
5.87k
                memcpy(pbuf, &pparams->GrayBackground, sizeof(pparams->GrayBackground));
9699
5.87k
                pbuf += sizeof(pparams->GrayBackground);
9700
5.87k
            }
9701
725k
            if (pparams->Matte_components) {
9702
316
                const int m = sizeof(pparams->Matte[0]) * pparams->Matte_components;
9703
9704
316
                memcpy(pbuf, pparams->Matte, m);
9705
316
                pbuf += m;
9706
316
            }
9707
725k
            if (!pparams->function_is_identity)
9708
1.55k
                mask_size = (256+deep)<<deep;
9709
            /* Color space information may be ICC based
9710
               in this case we need to store the ICC
9711
               profile or the ID if it is cached already */
9712
725k
            if (pparams->group_color_type == ICC) {
9713
                /* Check if it is already in the ICC clist table */
9714
618k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9715
618k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9716
618k
                if (!found_icc) {
9717
                    /* Add it to the table */
9718
5.24k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9719
5.24k
                    put_value(pbuf, hashcode);
9720
613k
                } else {
9721
                    /* It will be in the clist. Just write out the hashcode */
9722
613k
                    put_value(pbuf, hashcode);
9723
613k
                }
9724
618k
            } else {
9725
106k
                put_value(pbuf, hashcode);
9726
106k
            }
9727
725k
            break;
9728
618k
        case PDF14_END_TRANS_MASK:
9729
618k
            smask_level--;
9730
618k
            if (smask_level == 0 && trans_group_level == 0)
9731
18.0k
                pdf14_needed = cdev->page_pdf14_needed;
9732
618k
            break;
9733
641k
        case PDF14_SET_BLEND_PARAMS:
9734
641k
            if (pparams->blend_mode != BLEND_MODE_Normal || pparams->opacity != 1.0 ||
9735
0
                pparams->shape != 1.0)
9736
641k
                pdf14_needed = true;    /* the compositor will be needed while reading */
9737
0
            else if (smask_level == 0 && trans_group_level == 0)
9738
0
                pdf14_needed = false;   /* At page level, set back to false */
9739
641k
            if (smask_level == 0 && trans_group_level == 0)
9740
218k
                cdev->page_pdf14_needed = pdf14_needed;         /* save for after popping to page level */
9741
            /* Changed is now two bytes due to overprint stroke fill. Write as int */
9742
641k
            put_value(pbuf, pparams->changed);
9743
641k
            if (pparams->changed & PDF14_SET_BLEND_MODE)
9744
61.5k
                *pbuf++ = pparams->blend_mode;
9745
641k
            if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
9746
31.8k
                *pbuf++ = pparams->text_knockout;
9747
641k
            if (pparams->changed & PDF14_SET_AIS)
9748
641k
                put_value(pbuf, pparams->ais);
9749
641k
            if (pparams->changed & PDF14_SET_OVERPRINT)
9750
641k
                put_value(pbuf, pparams->overprint);
9751
641k
            if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
9752
641k
                put_value(pbuf, pparams->stroke_overprint);
9753
641k
            if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
9754
641k
                put_value(pbuf, pparams->fillconstantalpha);
9755
641k
            if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
9756
641k
                put_value(pbuf, pparams->strokeconstantalpha);
9757
641k
            if (pparams->changed & PDF14_SET_FILLSTROKE_STATE)
9758
641k
                put_value(pbuf, pparams->op_fs_state);
9759
641k
            break;
9760
0
        case PDF14_PUSH_TRANS_STATE:
9761
0
            break;
9762
90.5k
        case PDF14_POP_TRANS_STATE:
9763
90.5k
            break;
9764
0
        case PDF14_PUSH_SMASK_COLOR:
9765
0
            return 0;   /* We really should never be here */
9766
0
            break;
9767
0
        case PDF14_POP_SMASK_COLOR:
9768
0
            return 0;   /* We really should never be here */
9769
0
            break;
9770
3.87M
    }
9771
9772
    /* check for fit */
9773
3.87M
    need = (pbuf - buf) + mask_size;
9774
3.87M
    *psize = need;
9775
3.87M
    if (need > avail) {
9776
688k
        if (avail)
9777
0
            return_error(gs_error_rangecheck);
9778
688k
        else
9779
688k
            return gs_error_rangecheck;
9780
688k
    }
9781
9782
    /* If we are writing more than the maximum ever expected,
9783
     * return a rangecheck error. Second check is for Coverity
9784
     */
9785
3.19M
    if ((need + 3 > MAX_CLIST_COMPOSITOR_SIZE) ||
9786
3.19M
        (need + 3 - mask_size > MAX_CLIST_TRANSPARENCY_BUFFER_SIZE) )
9787
0
        return_error(gs_error_rangecheck);
9788
9789
    /* Copy our serialized data into the output buffer */
9790
3.19M
    memcpy(data, buf, need - mask_size);
9791
3.19M
    if (mask_size)  /* Include the transfer mask data if present */
9792
1.18k
        memcpy(data + need - mask_size, pparams->transfer_fn, mask_size);
9793
3.19M
    if_debug3m('v', cdev->memory,
9794
3.19M
               "[v] c_pdf14trans_write: opcode = %s mask_id=%d need = %d\n",
9795
3.19M
               pdf14_opcode_names[opcode], mask_id, need);
9796
3.19M
    cdev->pdf14_needed = pdf14_needed;          /* all OK to update */
9797
3.19M
    cdev->pdf14_trans_group_level = trans_group_level;
9798
3.19M
    cdev->pdf14_smask_level = smask_level;
9799
3.19M
    return 0;
9800
3.19M
}
9801
9802
#undef put_value
9803
9804
/* Function prototypes */
9805
static int gs_create_pdf14trans( gs_composite_t ** ppct,
9806
                const gs_pdf14trans_params_t * pparams,
9807
                gs_memory_t * mem );
9808
9809
#define read_value(dp, value)\
9810
323M
    BEGIN\
9811
323M
        memcpy(&value, dp, sizeof(value));\
9812
323M
        dp += sizeof(value);\
9813
323M
    END
9814
9815
/*
9816
 * Convert the string representation of the PDF 1.4 transparency parameter
9817
 * into the full compositor.
9818
 */
9819
static  int
9820
c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
9821
                                uint size, gs_memory_t * mem )
9822
95.3M
{
9823
95.3M
    gs_pdf14trans_params_t params = {0};
9824
95.3M
    const byte * start = data;
9825
95.3M
    int used, code = 0;
9826
95.3M
    bool deep;
9827
9828
95.3M
    if (size < 1)
9829
0
        return_error(gs_error_rangecheck);
9830
9831
    /* Read PDF 1.4 compositor data from the clist */
9832
95.3M
    params.pdf14_op = *data++;
9833
95.3M
    if_debug2m('v', mem, "[v] c_pdf14trans_read: opcode = %s  avail = %d",
9834
95.3M
               pdf14_opcode_names[params.pdf14_op], size);
9835
95.3M
    memset(&params.ctm, 0, sizeof(params.ctm));
9836
95.3M
    switch (params.pdf14_op) {
9837
0
        default:      /* Should not occur. */
9838
0
            break;
9839
2.79M
        case PDF14_PUSH_DEVICE:
9840
2.79M
            read_value(data, params.num_spot_colors);
9841
2.79M
            read_value(data, params.num_spot_colors_int);
9842
2.79M
            read_value(data, params.overprint_sim_push);
9843
2.79M
            read_value(data, params.is_pattern);
9844
2.79M
            break;
9845
0
        case PDF14_ABORT_DEVICE:
9846
0
            break;
9847
2.79M
        case PDF14_POP_DEVICE:
9848
2.79M
            read_value(data, params.is_pattern);
9849
2.79M
            break;
9850
5.07M
        case PDF14_END_TRANS_GROUP:
9851
5.86M
        case PDF14_END_TRANS_TEXT_GROUP:
9852
#ifdef DEBUG
9853
            code += 0; /* A good place for a breakpoint. */
9854
#endif
9855
5.86M
            break;      /* No data */
9856
0
        case PDF14_PUSH_TRANS_STATE:
9857
0
            break;
9858
6.73M
        case PDF14_POP_TRANS_STATE:
9859
6.73M
            break;
9860
1.25M
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9861
5.86M
        case PDF14_BEGIN_TRANS_GROUP:
9862
            /*
9863
             * We are currently not using the bbox or the colorspace so they were
9864
             * not placed in the clist
9865
             */
9866
5.86M
            data = cmd_read_matrix(&params.ctm, data);
9867
5.86M
            params.Isolated = (*data) & 1;
9868
5.86M
            params.Knockout = (*data++ >> 1) & 1;
9869
5.86M
            params.blend_mode = *data++;
9870
5.86M
            params.group_color_type = *data++;  /* Trans group color */
9871
5.86M
            params.page_group = *data++;
9872
5.86M
            read_value(data,params.group_color_numcomps);  /* color group size */
9873
5.86M
            read_value(data, params.opacity);
9874
5.86M
            read_value(data, params.shape);
9875
5.86M
            read_value(data, params.bbox);
9876
5.86M
            read_value(data, params.shade_group);
9877
5.86M
            read_value(data, params.text_group);
9878
5.86M
            read_value(data, params.mask_id);
9879
5.86M
            read_value(data, params.icc_hash);
9880
5.86M
            break;
9881
10.3M
        case PDF14_BEGIN_TRANS_MASK:
9882
                /* This is the largest transparency parameter at this time (potentially
9883
                 * 1531 bytes in size if Background_components =
9884
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and Matte_components =
9885
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and we have a transfer function as well).
9886
                 *
9887
                 * NOTE:
9888
                 * The clist reader must be able to handle this sized device.
9889
                 * If any changes are made here the #define MAX_CLIST_COMPOSITOR_SIZE
9890
                 * may also need to be changed correspondingly (defined in gstparam.h)
9891
                 * Also... if another compositor param should exceed this size, this
9892
                 * same condition applies.
9893
                 */
9894
10.3M
            data = cmd_read_matrix(&params.ctm, data);
9895
10.3M
            read_value(data, params.subtype);
9896
10.3M
            params.group_color_type = *data++;
9897
10.3M
            read_value(data, params.group_color_numcomps);
9898
10.3M
            params.replacing = *data++;
9899
10.3M
            params.function_is_identity = *data & 1;
9900
10.3M
            deep = (*data++)>>1;
9901
10.3M
            params.Background_components = *data++;
9902
10.3M
            params.Matte_components = *data++;
9903
10.3M
            read_value(data, params.bbox);
9904
10.3M
            read_value(data, params.mask_id);
9905
10.3M
            if (params.Background_components) {
9906
408k
                const int l = sizeof(params.Background[0]) * params.Background_components;
9907
9908
408k
                memcpy(params.Background, data, l);
9909
408k
                data += l;
9910
408k
                memcpy(&params.GrayBackground, data, sizeof(params.GrayBackground));
9911
408k
                data += sizeof(params.GrayBackground);
9912
408k
            }
9913
10.3M
            if (params.Matte_components) {
9914
9.54k
                const int m = sizeof(params.Matte[0]) * params.Matte_components;
9915
9916
9.54k
                memcpy(params.Matte, data, m);
9917
9.54k
                data += m;
9918
9.54k
            }
9919
10.3M
            read_value(data, params.icc_hash);
9920
10.3M
            if (params.function_is_identity) {
9921
10.3M
                int i;
9922
9923
10.3M
                if (deep) {
9924
0
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++)
9925
0
                        ((uint16_t *)params.transfer_fn)[i] = i*0x10000/MASK_TRANSFER_FUNCTION_SIZE;
9926
0
                    ((uint16_t *)params.transfer_fn)[i] = 0xffff;
9927
10.3M
                } else {
9928
2.65G
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
9929
2.64G
                        params.transfer_fn[i] = (byte)floor(i *
9930
2.64G
                            (255.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)) + 0.5);
9931
2.64G
                    }
9932
10.3M
                }
9933
10.3M
            } else {
9934
40.3k
                memcpy(params.transfer_fn, data, (256+deep)<<deep);
9935
40.3k
                data += (256+deep)<<deep;
9936
40.3k
            }
9937
10.3M
            break;
9938
1.12M
        case PDF14_END_TRANS_MASK:
9939
1.12M
            break;
9940
0
        case PDF14_PUSH_SMASK_COLOR:
9941
0
            return 0;
9942
0
            break;
9943
0
        case PDF14_POP_SMASK_COLOR:
9944
0
            return 0;
9945
0
            break;
9946
59.7M
        case PDF14_SET_BLEND_PARAMS:
9947
59.7M
            read_value(data, params.changed);
9948
59.7M
            if (params.changed & PDF14_SET_BLEND_MODE)
9949
5.94M
                params.blend_mode = *data++;
9950
59.7M
            if (params.changed & PDF14_SET_TEXT_KNOCKOUT)
9951
2.72M
                params.text_knockout = *data++;
9952
59.7M
            if (params.changed & PDF14_SET_AIS)
9953
59.7M
                read_value(data, params.ais);
9954
59.7M
            if (params.changed & PDF14_SET_OVERPRINT)
9955
59.7M
                read_value(data, params.overprint);
9956
59.7M
            if (params.changed & PDF14_SET_STROKEOVERPRINT)
9957
59.7M
                read_value(data, params.stroke_overprint);
9958
59.7M
            if (params.changed & PDF14_SET_FILLCONSTANTALPHA)
9959
59.7M
                read_value(data, params.fillconstantalpha);
9960
59.7M
            if (params.changed & PDF14_SET_STROKECONSTANTALPHA)
9961
59.7M
                read_value(data, params.strokeconstantalpha);
9962
59.7M
            if (params.changed & PDF14_SET_FILLSTROKE_STATE)
9963
59.7M
                read_value(data, params.op_fs_state);
9964
59.7M
            break;
9965
95.3M
    }
9966
95.3M
    code = gs_create_pdf14trans(ppct, &params, mem);
9967
95.3M
    if (code < 0)
9968
0
        return code;
9969
95.3M
    used = data - start;
9970
95.3M
    if_debug2m('v', mem, " mask_id=%d used = %d\n", params.mask_id, used);
9971
9972
    /* If we read more than the maximum expected, return a rangecheck error */
9973
95.3M
    if ( used + 3 > MAX_CLIST_COMPOSITOR_SIZE )
9974
0
        return_error(gs_error_rangecheck);
9975
95.3M
    else
9976
95.3M
        return used;
9977
95.3M
}
9978
9979
/*
9980
 * Adjust the compositor's CTM.
9981
 */
9982
static int
9983
c_pdf14trans_adjust_ctm(gs_composite_t * pct0, int x0, int y0, gs_gstate *pgs)
9984
50.7M
{
9985
50.7M
    gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pct0;
9986
50.7M
    gs_matrix mat = pct->params.ctm;
9987
9988
50.7M
    if_debug6m('L', pgs->memory, " [%g %g %g %g %g %g]\n",
9989
50.7M
               mat.xx, mat.xy, mat.yx, mat.yy,
9990
50.7M
               mat.tx, mat.ty);
9991
50.7M
    mat.tx -= x0;
9992
50.7M
    mat.ty -= y0;
9993
50.7M
    gs_gstate_setmatrix(pgs, &mat);
9994
50.7M
    return 0;
9995
50.7M
}
9996
9997
/*
9998
 * Create a PDF 1.4 transparency compositor.
9999
 *
10000
 * Note that this routine will be called only if the device is not already
10001
 * a PDF 1.4 transparency compositor.
10002
 * Return an error if it is not a PDF14_PUSH_DEVICE operation.
10003
 */
10004
static  int
10005
c_pdf14trans_create_default_compositor(const gs_composite_t * pct,
10006
    gx_device ** pp14dev, gx_device * tdev, gs_gstate * pgs,
10007
    gs_memory_t * mem)
10008
1.99M
{
10009
1.99M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
10010
1.99M
    int code = 0;
10011
10012
    /*
10013
     * We only handle the push operation.  All other operations are ignored.
10014
     * The other operations will be handled by the composite routine
10015
     * for the PDF 1.4 compositing device.
10016
     */
10017
1.99M
    switch (pdf14pct->params.pdf14_op) {
10018
1.96M
        case PDF14_PUSH_DEVICE:
10019
1.96M
            code = gs_pdf14_device_push(mem, pgs, pp14dev, tdev, pdf14pct);
10020
            /* Change (non-error) code to 1 to indicate that we created
10021
             * a device. */
10022
1.96M
            if (code >= 0)
10023
1.96M
                code = 1;
10024
1.96M
            break;
10025
31.3k
        default:
10026
            /* No other compositor actions are allowed if this isn't a pdf14 compositor */
10027
31.3k
            *pp14dev = NULL;
10028
31.3k
            return_error(gs_error_unregistered);
10029
1.99M
    }
10030
1.96M
    return code;
10031
1.99M
}
10032
10033
/*
10034
 * Find an opening compositor op.
10035
 */
10036
static gs_compositor_closing_state
10037
find_opening_op(int opening_op, gs_composite_t **ppcte,
10038
                gs_compositor_closing_state return_code)
10039
5.32M
{
10040
    /* Assuming a right *BEGIN* - *END* operation balance. */
10041
5.32M
    gs_composite_t *pcte = *ppcte;
10042
10043
13.1M
    for (;;) {
10044
13.1M
        if (pcte->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
10045
12.3M
            gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pcte;
10046
12.3M
            int op = pct->params.pdf14_op;
10047
10048
12.3M
            *ppcte = pcte;
10049
12.3M
            if (op == opening_op)
10050
3.52M
                return return_code;
10051
8.85M
            if (op != PDF14_SET_BLEND_PARAMS) {
10052
5.51M
                if (opening_op == PDF14_BEGIN_TRANS_MASK)
10053
1.78k
                    return COMP_ENQUEUE;
10054
5.50M
                if (opening_op == PDF14_BEGIN_TRANS_GROUP || opening_op == PDF14_BEGIN_TRANS_PAGE_GROUP) {
10055
490k
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK)
10056
433k
                        return COMP_ENQUEUE;
10057
490k
                }
10058
5.07M
                if (opening_op == PDF14_PUSH_DEVICE) {
10059
5.01M
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK &&
10060
4.94M
                        op != PDF14_BEGIN_TRANS_GROUP && op != PDF14_BEGIN_TRANS_PAGE_GROUP && op != PDF14_END_TRANS_GROUP &&
10061
487k
                        op != PDF14_END_TRANS_TEXT_GROUP)
10062
288k
                        return COMP_ENQUEUE;
10063
5.01M
                }
10064
5.07M
            }
10065
8.85M
        } else
10066
776k
            return COMP_ENQUEUE;
10067
8.13M
        pcte = pcte->prev;
10068
8.13M
        if (pcte == NULL)
10069
302k
            return COMP_EXEC_QUEUE; /* Not in queue. */
10070
8.13M
    }
10071
5.32M
}
10072
10073
/*
10074
 * Find an opening compositor op.
10075
 */
10076
static gs_compositor_closing_state
10077
find_same_op(const gs_composite_t *composite_action, int my_op, gs_composite_t **ppcte)
10078
49.8M
{
10079
49.8M
    const gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10080
49.8M
    gs_composite_t *pct = *ppcte;
10081
10082
49.8M
    for (;;) {
10083
49.8M
        if (pct->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
10084
43.0M
            gs_pdf14trans_t *pct_pdf14 = (gs_pdf14trans_t *)pct;
10085
10086
43.0M
            *ppcte = pct;
10087
43.0M
            if (pct_pdf14->params.pdf14_op != my_op)
10088
8.43M
                return COMP_ENQUEUE;
10089
34.5M
            if (pct_pdf14->params.csel == pct0->params.csel) {
10090
                /* If the new parameters completely replace the old ones
10091
                   then remove the old one from the queu */
10092
34.5M
                if ((pct_pdf14->params.changed & pct0->params.changed) ==
10093
34.5M
                    pct_pdf14->params.changed) {
10094
32.2M
                    return COMP_REPLACE_CURR;
10095
32.2M
                } else {
10096
2.35M
                    return COMP_ENQUEUE;
10097
2.35M
                }
10098
34.5M
            }
10099
34.5M
        } else
10100
6.77M
            return COMP_ENQUEUE;
10101
0
        pct = pct->prev;
10102
0
        if (pct == NULL)
10103
0
            return COMP_ENQUEUE; /* Not in queue. */
10104
0
    }
10105
49.8M
}
10106
10107
/*
10108
 * Check for closing compositor.
10109
 */
10110
static gs_compositor_closing_state
10111
c_pdf14trans_is_closing(const gs_composite_t * composite_action, gs_composite_t ** ppcte,
10112
                        gx_device *dev)
10113
83.0M
{
10114
83.0M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10115
83.0M
    int op0 = pct0->params.pdf14_op;
10116
10117
83.0M
    switch (op0) {
10118
0
        default: return_error(gs_error_unregistered); /* Must not happen. */
10119
2.09M
        case PDF14_PUSH_DEVICE:
10120
2.09M
            return COMP_ENQUEUE;
10121
0
        case PDF14_ABORT_DEVICE:
10122
0
            return COMP_ENQUEUE;
10123
2.09M
        case PDF14_POP_DEVICE:
10124
2.09M
            if (*ppcte == NULL)
10125
1.36M
                return COMP_ENQUEUE;
10126
720k
            else {
10127
720k
                gs_compositor_closing_state state = find_opening_op(PDF14_PUSH_DEVICE, ppcte, COMP_EXEC_IDLE);
10128
10129
720k
                if (state == COMP_EXEC_IDLE)
10130
135k
                    return COMP_DROP_QUEUE;
10131
585k
                return state;
10132
720k
            }
10133
974k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
10134
5.04M
        case PDF14_BEGIN_TRANS_GROUP:
10135
5.04M
            return COMP_ENQUEUE;
10136
4.30M
        case PDF14_END_TRANS_GROUP:
10137
5.04M
        case PDF14_END_TRANS_TEXT_GROUP:
10138
5.04M
            if (*ppcte == NULL)
10139
841k
                return COMP_EXEC_QUEUE;
10140
4.20M
            return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, COMP_MARK_IDLE);
10141
8.70M
        case PDF14_BEGIN_TRANS_MASK:
10142
8.70M
            return COMP_ENQUEUE;
10143
0
        case PDF14_PUSH_TRANS_STATE:
10144
0
            return COMP_ENQUEUE;
10145
5.65M
        case PDF14_POP_TRANS_STATE:
10146
5.65M
            return COMP_ENQUEUE;
10147
0
        case PDF14_PUSH_SMASK_COLOR:
10148
0
            return COMP_ENQUEUE;
10149
0
            break;
10150
0
        case PDF14_POP_SMASK_COLOR:
10151
0
            return COMP_ENQUEUE;
10152
0
            break;
10153
996k
        case PDF14_END_TRANS_MASK:
10154
996k
            if (*ppcte == NULL)
10155
594k
                return COMP_EXEC_QUEUE;
10156
401k
            return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte, COMP_MARK_IDLE);
10157
53.4M
        case PDF14_SET_BLEND_PARAMS:
10158
53.4M
            if (*ppcte == NULL)
10159
3.60M
                return COMP_ENQUEUE;
10160
            /* hack : ignore csel - here it is always zero : */
10161
49.8M
            return find_same_op(composite_action, PDF14_SET_BLEND_PARAMS, ppcte);
10162
83.0M
    }
10163
83.0M
}
10164
10165
/*
10166
 * Check whether a next operation is friendly to the compositor.
10167
 */
10168
static bool
10169
c_pdf14trans_is_friendly(const gs_composite_t * composite_action, byte cmd0, byte cmd1)
10170
8.29M
{
10171
8.29M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10172
8.29M
    int op0 = pct0->params.pdf14_op;
10173
10174
8.29M
    if (op0 == PDF14_PUSH_DEVICE || op0 == PDF14_END_TRANS_GROUP ||
10175
6.23M
        op0 == PDF14_END_TRANS_TEXT_GROUP) {
10176
        /* Halftone commands are always passed to the target printer device,
10177
           because transparency buffers are always contone.
10178
           So we're safe to execute them before queued transparency compositors. */
10179
2.09M
        if (cmd0 == cmd_opv_extend && (cmd1 == cmd_opv_ext_put_halftone ||
10180
551k
                                       cmd1 == cmd_opv_ext_put_ht_seg))
10181
888k
            return true;
10182
1.20M
        if (cmd0 == cmd_opv_set_misc && (cmd1 >> 6) == (cmd_set_misc_map >> 6))
10183
1.18M
            return true;
10184
1.20M
    }
10185
6.22M
    return false;
10186
8.29M
}
10187
10188
static composite_create_default_compositor_proc(c_pdf14trans_create_default_compositor);
10189
static composite_equal_proc(c_pdf14trans_equal);
10190
static composite_write_proc(c_pdf14trans_write);
10191
static composite_read_proc(c_pdf14trans_read);
10192
static composite_adjust_ctm_proc(c_pdf14trans_adjust_ctm);
10193
static composite_is_closing_proc(c_pdf14trans_is_closing);
10194
static composite_is_friendly_proc(c_pdf14trans_is_friendly);
10195
static composite_clist_write_update(c_pdf14trans_clist_write_update);
10196
static composite_clist_read_update(c_pdf14trans_clist_read_update);
10197
static composite_get_cropping_proc(c_pdf14trans_get_cropping);
10198
10199
/*
10200
 * Methods for the PDF 1.4 transparency compositor
10201
 *
10202
 * Note:  We have two set of methods.  They are the same except for the
10203
 * composite_clist_write_update method.  Once the clist write device is created,
10204
 * we use the second set of procedures.  This prevents the creation of multiple
10205
 * PDF 1.4 clist write compositor devices being chained together.
10206
 */
10207
const gs_composite_type_t   gs_composite_pdf14trans_type = {
10208
    GX_COMPOSITOR_PDF14_TRANS,
10209
    {
10210
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10211
        c_pdf14trans_equal,                      /* procs.equal */
10212
        c_pdf14trans_write,                      /* procs.write */
10213
        c_pdf14trans_read,                       /* procs.read */
10214
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10215
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10216
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10217
                /* Create a PDF 1.4 clist write device */
10218
        c_pdf14trans_clist_write_update,   /* procs.composite_clist_write_update */
10219
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10220
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10221
    }                                            /* procs */
10222
};
10223
10224
const gs_composite_type_t   gs_composite_pdf14trans_no_clist_writer_type = {
10225
    GX_COMPOSITOR_PDF14_TRANS,
10226
    {
10227
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10228
        c_pdf14trans_equal,                      /* procs.equal */
10229
        c_pdf14trans_write,                      /* procs.write */
10230
        c_pdf14trans_read,                       /* procs.read */
10231
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10232
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10233
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10234
                /* The PDF 1.4 clist writer already exists, Do not create it. */
10235
        gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */
10236
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10237
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10238
    }                                            /* procs */
10239
};
10240
10241
/*
10242
 * Verify that a compositor data structure is for the PDF 1.4 compositor.
10243
 */
10244
int
10245
gs_is_pdf14trans_compositor(const gs_composite_t * pct)
10246
698M
{
10247
698M
    return (pct->type == &gs_composite_pdf14trans_type
10248
552M
                || pct->type == &gs_composite_pdf14trans_no_clist_writer_type);
10249
698M
}
10250
10251
/*
10252
 * Create a PDF 1.4 transparency compositor data structure.
10253
 */
10254
static int
10255
gs_create_pdf14trans(
10256
    gs_composite_t **               ppct,
10257
    const gs_pdf14trans_params_t *  pparams,
10258
    gs_memory_t *                   mem )
10259
98.6M
{
10260
98.6M
    gs_pdf14trans_t *                pct;
10261
10262
98.6M
    pct = gs_alloc_struct(mem, gs_pdf14trans_t, &st_pdf14trans,
10263
98.6M
                             "gs_create_pdf14trans");
10264
98.6M
    if (pct == NULL)
10265
0
        return_error(gs_error_VMerror);
10266
98.6M
    pct->type = &gs_composite_pdf14trans_type;
10267
98.6M
    pct->id = gs_next_ids(mem, 1);
10268
98.6M
    pct->params = *pparams;
10269
98.6M
    pct->idle = false;
10270
98.6M
    *ppct = (gs_composite_t *)pct;
10271
98.6M
    return 0;
10272
98.6M
}
10273
10274
/*
10275
 * Send a PDF 1.4 transparency compositor action to the specified device.
10276
 */
10277
int
10278
send_pdf14trans(gs_gstate * pgs, gx_device * dev,
10279
    gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem)
10280
3.02M
{
10281
3.02M
    gs_composite_t * pct = NULL;
10282
3.02M
    int code;
10283
10284
3.02M
    pparams->ctm = ctm_only(pgs);
10285
3.02M
    code = gs_create_pdf14trans(&pct, pparams, mem);
10286
3.02M
    if (code < 0)
10287
0
        return code;
10288
3.02M
    code = dev_proc(dev, composite) (dev, pcdev, pct, pgs, mem, NULL);
10289
3.02M
    if (code == gs_error_handled)
10290
0
        code = 0;
10291
10292
3.02M
    gs_free_object(pgs->memory, pct, "send_pdf14trans");
10293
10294
3.02M
    return code;
10295
3.02M
}
10296
10297
/* ------------- PDF 1.4 transparency device for clist writing ------------- */
10298
10299
/*
10300
 * The PDF 1.4 transparency compositor device may have a different process
10301
 * color model than the output device.  If we are banding then we need to
10302
 * create two compositor devices.  The output side (clist reader) needs a
10303
 * compositor to actually composite the output.  We also need a compositor
10304
 * device before the clist writer.  This is needed to provide a process color
10305
 * model which matches the PDF 1.4 blending space.
10306
 *
10307
 * This section provides support for this device.
10308
 */
10309
10310
/*
10311
 * Define the default pre-clist (clist writer) PDF 1.4 compositing device.
10312
 * We actually use the same structure for both the clist writer and reader
10313
 * devices.  However we use separate names to identify the routines for each
10314
 * device.
10315
 */
10316
10317
static  dev_proc_composite(pdf14_clist_composite);
10318
static  dev_proc_composite(pdf14_clist_forward_composite);
10319
static  dev_proc_fill_path(pdf14_clist_fill_path);
10320
static  dev_proc_stroke_path(pdf14_clist_stroke_path);
10321
static  dev_proc_fill_stroke_path(pdf14_clist_fill_stroke_path);
10322
static  dev_proc_text_begin(pdf14_clist_text_begin);
10323
static  dev_proc_begin_typed_image(pdf14_clist_begin_typed_image);
10324
static  dev_proc_copy_planes(pdf14_clist_copy_planes);
10325
10326
static void
10327
pdf14_clist_init_procs(gx_device *dev,
10328
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
10329
                       dev_proc_get_color_comp_index(get_color_comp_index))
10330
17.2k
{
10331
17.2k
    set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
10332
17.2k
    set_dev_proc(dev, sync_output, gx_forward_sync_output);
10333
17.2k
    set_dev_proc(dev, output_page, gx_forward_output_page);
10334
17.2k
    set_dev_proc(dev, close_device, gx_forward_close_device);
10335
17.2k
    set_dev_proc(dev, map_rgb_color, pdf14_encode_color);
10336
17.2k
    set_dev_proc(dev, map_color_rgb, pdf14_decode_color);
10337
17.2k
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
10338
17.2k
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
10339
17.2k
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
10340
17.2k
    set_dev_proc(dev, get_params, gx_forward_get_params);
10341
17.2k
    set_dev_proc(dev, put_params, pdf14_put_params);
10342
17.2k
    set_dev_proc(dev, map_cmyk_color, pdf14_encode_color);
10343
17.2k
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
10344
17.2k
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
10345
17.2k
    set_dev_proc(dev, fill_path, pdf14_clist_fill_path);
10346
17.2k
    set_dev_proc(dev, stroke_path, pdf14_clist_stroke_path);
10347
17.2k
    set_dev_proc(dev, fill_mask, gx_forward_fill_mask);
10348
17.2k
    set_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid);
10349
17.2k
    set_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram);
10350
17.2k
    set_dev_proc(dev, fill_triangle, gx_forward_fill_triangle);
10351
17.2k
    set_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line);
10352
17.2k
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
10353
17.2k
    set_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2);
10354
17.2k
    set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box);
10355
17.2k
    set_dev_proc(dev, begin_typed_image, pdf14_clist_begin_typed_image);
10356
17.2k
    set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle);
10357
17.2k
    set_dev_proc(dev, composite, pdf14_clist_composite);
10358
17.2k
    set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params);
10359
17.2k
    set_dev_proc(dev, text_begin, pdf14_clist_text_begin);
10360
17.2k
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
10361
17.2k
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
10362
17.2k
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
10363
17.2k
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
10364
17.2k
    set_dev_proc(dev, discard_transparency_layer, gx_default_discard_transparency_layer);
10365
17.2k
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
10366
17.2k
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
10367
17.2k
    set_dev_proc(dev, encode_color, pdf14_encode_color);
10368
17.2k
    set_dev_proc(dev, decode_color, pdf14_decode_color);
10369
17.2k
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
10370
17.2k
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
10371
17.2k
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
10372
17.2k
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
10373
17.2k
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
10374
17.2k
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
10375
17.2k
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
10376
17.2k
    set_dev_proc(dev, copy_planes, pdf14_clist_copy_planes);
10377
17.2k
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
10378
17.2k
    set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color);
10379
17.2k
    set_dev_proc(dev, fill_stroke_path, pdf14_clist_fill_stroke_path);
10380
17.2k
}
10381
10382
static void
10383
pdf14_clist_Gray_initialize_device_procs(gx_device *dev)
10384
4.44k
{
10385
4.44k
    pdf14_clist_init_procs(dev,
10386
4.44k
                           gx_default_DevGray_get_color_mapping_procs,
10387
4.44k
                           gx_default_DevGray_get_color_comp_index);
10388
4.44k
}
10389
10390
static void
10391
pdf14_clist_RGB_initialize_device_procs(gx_device *dev)
10392
10.3k
{
10393
10.3k
    pdf14_clist_init_procs(dev,
10394
10.3k
                           gx_default_DevRGB_get_color_mapping_procs,
10395
10.3k
                           gx_default_DevRGB_get_color_comp_index);
10396
10.3k
}
10397
10398
static void
10399
pdf14_clist_CMYK_initialize_device_procs(gx_device *dev)
10400
22
{
10401
22
    pdf14_clist_init_procs(dev,
10402
22
                           gx_default_DevCMYK_get_color_mapping_procs,
10403
22
                           gx_default_DevCMYK_get_color_comp_index);
10404
22
}
10405
10406
static void
10407
pdf14_clist_CMYKspot_initialize_device_procs(gx_device *dev)
10408
2.41k
{
10409
2.41k
    pdf14_clist_init_procs(dev,
10410
2.41k
                           pdf14_cmykspot_get_color_mapping_procs,
10411
2.41k
                           pdf14_cmykspot_get_color_comp_index);
10412
2.41k
}
10413
10414
static void
10415
pdf14_clist_RGBspot_initialize_device_procs(gx_device *dev)
10416
0
{
10417
0
    pdf14_clist_init_procs(dev,
10418
0
                           pdf14_rgbspot_get_color_mapping_procs,
10419
0
                           pdf14_rgbspot_get_color_comp_index);
10420
0
}
10421
10422
#if 0 /* NOT USED */
10423
static int
10424
pdf14_clist_Grayspot_initialize_device_procs(gx_device *dev)
10425
{
10426
    pdf14_clist_init_procs(dev,
10427
                           pdf14_grayspot_get_color_mapping_procs,
10428
                           pdf14_grayspot_get_color_comp_index);
10429
}
10430
#endif  /* NOT USED */
10431
10432
const pdf14_clist_device pdf14_clist_Gray_device = {
10433
    std_device_color_stype_body(pdf14_clist_device,
10434
                                pdf14_clist_Gray_initialize_device_procs,
10435
                                "pdf14clistgray",
10436
                                &st_pdf14_device,
10437
                                XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256),
10438
    { 0 },      /* Procs */
10439
    NULL,     /* target */
10440
    { 0 },      /* devn_params - not used */
10441
    &gray_pdf14_procs,
10442
    &gray_blending_procs
10443
};
10444
10445
const pdf14_clist_device pdf14_clist_RGB_device = {
10446
    std_device_color_stype_body(pdf14_clist_device,
10447
                                pdf14_clist_RGB_initialize_device_procs,
10448
                                "pdf14clistRGB",
10449
                                &st_pdf14_device,
10450
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
10451
    { 0 },      /* Procs */
10452
    NULL,     /* target */
10453
    { 0 },      /* devn_params - not used */
10454
    &rgb_pdf14_procs,
10455
    &rgb_blending_procs
10456
};
10457
10458
const pdf14_clist_device pdf14_clist_RGBspot_device = {
10459
    std_device_part1_(pdf14_device,
10460
                      pdf14_clist_RGBspot_initialize_device_procs,
10461
                      "pdf14clistrgbspot",
10462
                      &st_pdf14_device,
10463
                      open_init_closed),
10464
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10465
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10466
    offset_margin_values(0, 0, 0, 0, 0, 0),
10467
    std_device_part3_(),
10468
    { 0 },      /* Procs */
10469
    NULL,     /* target */
10470
    /* DeviceN parameters */
10471
    { 8,      /* Not used - Bits per color */
10472
      DeviceRGBComponents,  /* Names of color model colorants */
10473
      3,      /* Number colorants for CMYK */
10474
      0,      /* MaxSeparations has not been specified */
10475
      -1,     /* PageSpotColors has not been specified */
10476
      {0},      /* SeparationNames */
10477
      0,      /* SeparationOrder names */
10478
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10479
    },
10480
    &rgbspot_pdf14_procs,
10481
    &rgb_blending_procs
10482
};
10483
10484
const pdf14_clist_device pdf14_clist_CMYK_device = {
10485
    std_device_std_color_full_body_type(pdf14_clist_device,
10486
                                        pdf14_clist_CMYK_initialize_device_procs,
10487
                                        "pdf14clistcmyk",
10488
                                        &st_pdf14_device,
10489
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
10490
                                        0, 0, 0, 0, 0, 0),
10491
    { 0 },      /* Procs */
10492
    NULL,     /* target */
10493
    { 0 },      /* devn_params - not used */
10494
    &cmyk_pdf14_procs,
10495
    &cmyk_blending_procs
10496
};
10497
10498
const pdf14_clist_device pdf14_clist_CMYKspot_device = {
10499
    std_device_part1_(pdf14_device,
10500
                      pdf14_clist_CMYKspot_initialize_device_procs,
10501
                      "pdf14clistcmykspot",
10502
                      &st_pdf14_device,
10503
                      open_init_closed),
10504
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10505
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10506
    offset_margin_values(0, 0, 0, 0, 0, 0),
10507
    std_device_part3_(),
10508
    { 0 },      /* Procs */
10509
    NULL,     /* target */
10510
    /* DeviceN parameters */
10511
    { 8,      /* Not used - Bits per color */
10512
      DeviceCMYKComponents, /* Names of color model colorants */
10513
      4,      /* Number colorants for CMYK */
10514
      0,      /* MaxSeparations has not been specified */
10515
      -1,     /* PageSpotColors has not been specified */
10516
      {0},      /* SeparationNames */
10517
      0,      /* SeparationOrder names */
10518
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10519
    },
10520
    &cmykspot_pdf14_procs,
10521
    &cmyk_blending_procs
10522
};
10523
10524
const pdf14_clist_device pdf14_clist_custom_device = {
10525
    std_device_part1_(pdf14_device,
10526
                      pdf14_clist_CMYKspot_initialize_device_procs,
10527
                      "pdf14clistcustom",
10528
                      &st_pdf14_device,
10529
                      open_init_closed),
10530
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10531
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10532
    offset_margin_values(0, 0, 0, 0, 0, 0),
10533
    std_device_part3_(),
10534
    { 0 },      /* Procs */
10535
    NULL,     /* target */
10536
    /* DeviceN parameters */
10537
    { 8,      /* Not used - Bits per color */
10538
      DeviceCMYKComponents, /* Names of color model colorants */
10539
      4,      /* Number colorants for CMYK */
10540
      0,      /* MaxSeparations has not been specified */
10541
      -1,     /* PageSpotColors has not been specified */
10542
      {0},      /* SeparationNames */
10543
      0,      /* SeparationOrder names */
10544
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10545
    },
10546
    &custom_pdf14_procs,
10547
    &custom_blending_procs
10548
};
10549
10550
/*
10551
 * the PDF 1.4 transparency spec says that color space for blending
10552
 * operations can be based upon either a color space specified in the
10553
 * group or a default value based upon the output device.  We are
10554
 * currently only using a color space based upon the device.
10555
 */
10556
static  int
10557
get_pdf14_clist_device_proto(gx_device          *dev,
10558
                             pdf14_clist_device *pdevproto,
10559
                             gs_gstate          *pgs,
10560
                       const gs_pdf14trans_t    *pdf14pct,
10561
                             bool                use_pdf14_accum)
10562
17.2k
{
10563
17.2k
    pdf14_blend_cs_t blend_cs_state;
10564
17.2k
    pdf14_default_colorspace_t dev_cs =
10565
17.2k
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
10566
17.2k
                                                 &blend_cs_state);
10567
17.2k
    bool deep = device_is_deep(dev);
10568
17.2k
    int num_spots = pdf14pct->params.num_spot_colors;
10569
10570
    /* overprint overide */
10571
17.2k
    if (pdf14pct->params.overprint_sim_push &&
10572
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10573
10574
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
10575
0
            dev_cs = PDF14_DeviceCMYKspot;
10576
0
            num_spots = pdf14pct->params.num_spot_colors_int;
10577
0
        } else
10578
0
            dev_cs = PDF14_DeviceCMYK;
10579
0
    }
10580
10581
17.2k
    switch (dev_cs) {
10582
4.44k
        case PDF14_DeviceGray:
10583
           /* We want gray to be single channel.  Low level
10584
               initialization of gray device prototype is
10585
               peculiar in that in dci_std_color_num_components
10586
               the comment is
10587
              "A device is monochrome only if it is bi-level"
10588
              Here we want monochrome anytime we have a gray device.
10589
              To avoid breaking things elsewhere, we will overide
10590
              the prototype intialization here */
10591
4.44k
            *pdevproto = pdf14_clist_Gray_device;
10592
4.44k
            pdevproto->color_info.max_components = 1;
10593
4.44k
            pdevproto->color_info.num_components =
10594
4.44k
                                    pdevproto->color_info.max_components;
10595
4.44k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10596
4.44k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
10597
4.44k
            pdevproto->color_info.dither_grays = pdevproto->color_info.max_gray+1;
10598
4.44k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10599
4.44k
            pdevproto->color_info.depth = deep ? 16 : 8;
10600
4.44k
            pdevproto->sep_device = false;
10601
4.44k
            break;
10602
10.3k
        case PDF14_DeviceRGB:
10603
10.3k
            *pdevproto = pdf14_clist_RGB_device;
10604
10.3k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10605
10.3k
            pdevproto->sep_device = false;
10606
10.3k
            if (deep) {
10607
0
                pdevproto->color_info.depth = 3*16;
10608
0
                pdevproto->color_info.max_color = 65535;
10609
0
                pdevproto->color_info.max_gray = 65535;
10610
0
                pdevproto->color_info.dither_colors = 65536;
10611
0
                pdevproto->color_info.dither_grays = 65536;
10612
0
            }
10613
10.3k
            break;
10614
22
        case PDF14_DeviceCMYK:
10615
22
            *pdevproto = pdf14_clist_CMYK_device;
10616
22
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10617
22
            pdevproto->sep_device = false;
10618
22
            if (deep) {
10619
0
                pdevproto->color_info.depth = 4*16;
10620
0
                pdevproto->color_info.max_color = 65535;
10621
0
                pdevproto->color_info.max_gray = 65535;
10622
0
                pdevproto->color_info.dither_colors = 65536;
10623
0
                pdevproto->color_info.dither_grays = 65536;
10624
0
            }
10625
22
            break;
10626
2.41k
        case PDF14_DeviceCMYKspot:
10627
2.41k
            *pdevproto = pdf14_clist_CMYKspot_device;
10628
            /*
10629
             * The number of components for the PDF14 device is the sum
10630
             * of the process components and the number of spot colors
10631
             * for the page. If we are using an NCLR ICC profile at
10632
             * the output device, those spot colors are skipped. They
10633
             * do not appear in the transparency buffer, but appear
10634
             * during put image transform of the page group to the target
10635
             * color space.
10636
             */
10637
2.41k
            if (num_spots >= 0) {
10638
2.41k
                pdevproto->devn_params.page_spot_colors = num_spots;
10639
2.41k
                pdevproto->color_info.num_components =
10640
2.41k
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10641
2.41k
                if (pdevproto->color_info.num_components >
10642
2.41k
                              pdevproto->color_info.max_components)
10643
0
                    pdevproto->color_info.num_components =
10644
0
                              pdevproto->color_info.max_components;
10645
2.41k
                pdevproto->color_info.depth =
10646
2.41k
                              pdevproto->color_info.num_components * (8<<deep);
10647
2.41k
            }
10648
2.41k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10649
2.41k
            pdevproto->sep_device = true;
10650
2.41k
            break;
10651
0
        case PDF14_DeviceRGBspot:
10652
0
            *pdevproto = pdf14_clist_RGBspot_device;
10653
            /*
10654
             * The number of components for the PDF14 device is the sum
10655
             * of the process components and the number of spot colors
10656
             * for the page. If we are using an NCLR ICC profile at
10657
             * the output device, those spot colors are skipped. They
10658
             * do not appear in the transparency buffer, but appear
10659
             * during put image transform of the page group to the target
10660
             * color space.
10661
             */
10662
0
            if (num_spots >= 0) {
10663
0
                pdevproto->devn_params.page_spot_colors = num_spots;
10664
0
                pdevproto->color_info.num_components =
10665
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10666
0
                if (pdevproto->color_info.num_components >
10667
0
                    pdevproto->color_info.max_components)
10668
0
                    pdevproto->color_info.num_components =
10669
0
                        pdevproto->color_info.max_components;
10670
0
                pdevproto->color_info.depth =
10671
0
                    pdevproto->color_info.num_components * (8 << deep);
10672
0
            }
10673
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10674
0
            pdevproto->sep_device = true;
10675
0
            break;
10676
0
        case PDF14_DeviceCustom:
10677
            /*
10678
             * We are using the output device's process color model.  The
10679
             * color_info for the PDF 1.4 compositing device needs to match
10680
             * the output device.
10681
             */
10682
0
            *pdevproto = pdf14_clist_custom_device;
10683
0
            pdevproto->color_info = dev->color_info;
10684
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
10685
0
            pdevproto->color_info.depth =
10686
0
                pdevproto->color_info.num_components * (8<<deep);
10687
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10688
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
10689
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
10690
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
10691
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10692
0
            break;
10693
0
        default:      /* Should not occur */
10694
0
            return_error(gs_error_rangecheck);
10695
17.2k
    }
10696
17.2k
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
10697
17.2k
    pdevproto->blend_cs_state = blend_cs_state;
10698
17.2k
    return 0;
10699
17.2k
}
10700
10701
static  int
10702
pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10703
                                gx_device ** ppdev, gx_device * target,
10704
                                const gs_pdf14trans_t * pdf14pct)
10705
17.2k
{
10706
17.2k
    pdf14_clist_device dev_proto;
10707
17.2k
    pdf14_clist_device * pdev;
10708
17.2k
    int code;
10709
17.2k
    bool has_tags = device_encodes_tags(target);
10710
17.2k
    cmm_profile_t *target_profile;
10711
17.2k
    gsicc_rendering_param_t render_cond;
10712
17.2k
    cmm_dev_profile_t *dev_profile;
10713
17.2k
    uchar k;
10714
17.2k
    bool deep = device_is_deep(target);
10715
17.2k
    cmm_profile_t *icc_profile;
10716
17.2k
    int nc;
10717
10718
17.2k
    code = dev_proc(target, get_profile)(target,  &dev_profile);
10719
17.2k
    if (code < 0)
10720
0
        return code;
10721
17.2k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &target_profile,
10722
17.2k
                          &render_cond);
10723
17.2k
    if_debug0m('v', pgs->memory, "[v]pdf14_create_clist_device\n");
10724
    /* Prototypes never include tags. We add those in later. */
10725
17.2k
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10726
17.2k
                                        pgs, pdf14pct, false);
10727
17.2k
    if (code < 0)
10728
0
        return code;
10729
17.2k
    code = gs_copydevice((gx_device **) &pdev,
10730
17.2k
                         (const gx_device *) &dev_proto, mem);
10731
17.2k
    if (code < 0)
10732
0
        return code;
10733
10734
17.2k
    nc = pdev->color_info.num_components;
10735
    /* If we are not using a blending color space, the number of color planes
10736
       should not exceed that of the target */
10737
17.2k
    if (!(pdev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || pdev->overprint_sim)) {
10738
17.2k
        if (nc > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev))
10739
0
            nc = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev);
10740
17.2k
        if (pdev->color_info.max_components > target->color_info.max_components)
10741
2.48k
            pdev->color_info.max_components = target->color_info.max_components;
10742
17.2k
    }
10743
17.2k
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10744
0
        nc = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10745
10746
17.2k
    pdev->color_info.num_components = nc;
10747
17.2k
    pdev->color_info.depth = pdev->color_info.num_components * (8<<deep);
10748
17.2k
    pdev->pad = target->pad;
10749
17.2k
    pdev->log2_align_mod = target->log2_align_mod;
10750
10751
17.2k
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10752
10753
17.2k
    pdev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
10754
10755
17.2k
    if (deep) {
10756
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
10757
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
10758
0
    }
10759
    /* If we have a tag device then go ahead and do a special encoder decoder
10760
       for the pdf14 device to make sure we maintain this information in the
10761
       encoded color information.  We could use the target device's methods but
10762
       the PDF14 device has to maintain 8 bit color always and we could run
10763
       into other issues if the number of colorants became large.  If we need to
10764
       do compressed color with tags that will be a special project at that time */
10765
17.2k
    if (has_tags) {
10766
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag: pdf14_encode_color_tag);
10767
0
    }
10768
17.2k
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;  /* this is the standard */
10769
17.2k
    gx_device_fill_in_procs((gx_device *)pdev);
10770
    /* Copying the params adds the tags to the color_info if required. */
10771
17.2k
    gs_pdf14_device_copy_params((gx_device *)pdev, target);
10772
17.2k
    if (target->num_planar_planes > 0)
10773
2.59k
        pdev->num_planar_planes = pdev->color_info.num_components;
10774
17.2k
    gx_device_set_target((gx_device_forward *)pdev, target);
10775
10776
    /* Components shift, etc have to be based upon 8 bit */
10777
62.4k
    for (k = 0; k < pdev->color_info.num_components; k++) {
10778
45.2k
        pdev->color_info.comp_bits[k] = 8<<deep;
10779
45.2k
        pdev->color_info.comp_shift[k] = (pdev->color_info.num_components - 1 - k) * (8<<deep);
10780
45.2k
    }
10781
17.2k
    code = dev_proc((gx_device *) pdev, open_device) ((gx_device *) pdev);
10782
17.2k
    if (code < 0)
10783
0
        return code;
10784
17.2k
    pdev->pclist_device = target;
10785
10786
17.2k
    code = dev_proc(target, get_profile)(target, &dev_profile);
10787
17.2k
    if (code < 0)
10788
0
        return code;
10789
17.2k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
10790
17.2k
        &render_cond);
10791
17.2k
    if_debug0m('v', mem, "[v]pdf14_create_clist_device\n");
10792
10793
    /* Simulated overprint case.  We have to use CMYK-based profile
10794
       Also if the target profile is NCLR, we are going to use a pdf14
10795
       device that is CMYK based and do the mapping to the NCLR profile
10796
       when the put_image occurs */
10797
17.2k
    if ((pdev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
10798
17.2k
         icc_profile->data_cs == gsNCHANNEL) {
10799
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_create_clist_device");
10800
0
        gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10801
0
            -1, "pdf14_create_clist_device");
10802
0
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
10803
17.2k
    } else {
10804
        /* If the target profile was CIELAB, then overide with default RGB for
10805
           proper blending.  During put_image we will convert from RGB to
10806
           CIELAB */
10807
17.2k
        if ((target_profile->data_cs == gsCIELAB || target_profile->islab) &&
10808
0
            pdev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10809
0
            pdev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
10810
0
            rc_assign(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10811
0
                pgs->icc_manager->default_rgb, "pdf14_create_clist_device");
10812
0
        }
10813
17.2k
    }
10814
10815
17.2k
    if (pdf14pct->params.overprint_sim_push &&
10816
0
        pdf14pct->params.num_spot_colors_int > 0) {
10817
0
        pdev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
10818
0
        pdev->procs.ret_devn_params = pdf14_ret_devn_params;
10819
0
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
10820
0
        pdev->target_support_devn = pdev->icc_struct->supports_devn;
10821
0
        pdev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
10822
0
    }
10823
    /* if the device has separations already defined (by SeparationOrderNames) */
10824
    /* we need to copy them (allocating new names) so the colorants are in the */
10825
    /* same order as the target device.                                        */
10826
17.2k
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0)) {
10827
2.59k
        code = devn_copy_params(target, (gx_device *)pdev);
10828
2.59k
        if (code < 0)
10829
0
            return code;
10830
2.59k
    }
10831
17.2k
    pdev->my_encode_color = dev_proc(pdev, encode_color);
10832
17.2k
    pdev->my_decode_color = dev_proc(pdev, decode_color);
10833
17.2k
    pdev->my_get_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
10834
17.2k
    pdev->my_get_color_comp_index = dev_proc(pdev, get_color_comp_index);
10835
17.2k
    pdev->color_info.separable_and_linear =
10836
17.2k
        target->color_info.separable_and_linear;
10837
17.2k
    *ppdev = (gx_device *) pdev;
10838
17.2k
    return code;
10839
17.2k
}
10840
10841
/*
10842
 * Disable the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10843
 * compositor device is never removed.  (We do not have a remove compositor
10844
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10845
 * routine implements that action.
10846
 */
10847
static  int
10848
pdf14_disable_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10849
                                gx_device * dev)
10850
16.4k
{
10851
16.4k
    gx_device_forward * pdev = (gx_device_forward *)dev;
10852
16.4k
    gx_device * target = pdev->target;
10853
10854
16.4k
    if_debug0m('v', pgs->memory, "[v]pdf14_disable_clist_device\n");
10855
10856
    /*
10857
     * To disable the action of this device, we forward all device
10858
     * procedures to the target except the composite and copy
10859
     * the target's color_info.
10860
     */
10861
16.4k
    dev->color_info = target->color_info;
10862
16.4k
    pdf14_forward_device_procs(dev);
10863
16.4k
    set_dev_proc(dev, composite, pdf14_clist_forward_composite);
10864
16.4k
    return 0;
10865
16.4k
}
10866
10867
/*
10868
 * Recreate the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10869
 * compositor device is never removed.  (We do not have a remove compositor
10870
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10871
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
10872
 * again.
10873
 */
10874
static  int
10875
pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10876
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
10877
0
{
10878
0
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
10879
0
    gx_device * target = pdev->target;
10880
0
    pdf14_clist_device dev_proto;
10881
0
    int code;
10882
10883
0
    if_debug0m('v', pgs->memory, "[v]pdf14_recreate_clist_device\n");
10884
    /*
10885
     * We will not use the entire prototype device but we will set the
10886
     * color related info to match the prototype.
10887
     */
10888
0
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10889
0
                                        pgs, pdf14pct, false);
10890
0
    if (code < 0)
10891
0
        return code;
10892
0
    pdev->color_info = dev_proto.color_info;
10893
10894
0
    if (dev_proto.initialize_device_procs != NULL)
10895
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
10896
10897
0
    pdev->procs = dev_proto.procs;
10898
0
    pdev->pad = target->pad;
10899
0
    pdev->log2_align_mod = target->log2_align_mod;
10900
10901
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10902
0
        pdev->num_planar_planes = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10903
0
    else
10904
0
        pdev->num_planar_planes = target->num_planar_planes;
10905
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10906
10907
0
    copy_tag_setup(dev, target);
10908
10909
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
10910
0
    gx_device_fill_in_procs((gx_device *)pdev);
10911
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
10912
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
10913
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
10914
0
    check_device_separable((gx_device *)pdev);
10915
0
    return code;
10916
0
}
10917
10918
/*
10919
 * devicen params
10920
 */
10921
gs_devn_params *
10922
pdf14_ret_devn_params(gx_device *pdev)
10923
4.06M
{
10924
4.06M
    pdf14_device *p14dev = (pdf14_device *)pdev;
10925
10926
4.06M
    return &(p14dev->devn_params);
10927
4.06M
}
10928
10929
/*
10930
 * devicen params
10931
 */
10932
gs_devn_params *
10933
pdf14_accum_ret_devn_params(gx_device *pdev)
10934
0
{
10935
0
    gx_device_pdf14_accum *p14dev = (gx_device_pdf14_accum *)pdev;
10936
10937
0
    return &(p14dev->devn_params);
10938
0
}
10939
10940
static int
10941
pdf14_accum_get_color_comp_index(gx_device * dev,
10942
    const char * pname, int name_size, int component_type)
10943
0
{
10944
0
    pdf14_device *p14dev = (pdf14_device *)(((gx_device_pdf14_accum *)dev)->save_p14dev);
10945
0
    gx_device *target = p14dev->target;
10946
0
    int colorant_number = devn_get_color_comp_index(dev,
10947
0
                &(((gx_device_pdf14_accum *)dev)->devn_params),
10948
0
                &(((gx_device_pdf14_accum *)dev)->equiv_cmyk_colors),
10949
0
                pname, name_size, component_type, ENABLE_AUTO_SPOT_COLORS);
10950
10951
0
    if (target != NULL)
10952
        /* colorant_number returned here _should_ be the same as from above */
10953
0
        colorant_number = (*dev_proc(target, get_color_comp_index))
10954
0
                              (target, (const char *)pname, name_size, component_type);
10955
0
    return colorant_number;
10956
0
}
10957
10958
/*
10959
 * The following procedures are used to map the standard color spaces into
10960
 * the separation color components for the pdf14_accum device.
10961
 */
10962
static void
10963
pdf14_accum_gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[])
10964
0
{
10965
0
    int * map =
10966
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10967
10968
0
    gray_cs_to_devn_cm(dev, map, gray, out);
10969
0
}
10970
10971
static void
10972
pdf14_accum_rgb_cs_to_cmyk_cm(const gx_device * dev,
10973
    const gs_gstate *pgs, frac r, frac g, frac b, frac out[])
10974
0
{
10975
0
    int * map =
10976
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10977
10978
0
    rgb_cs_to_devn_cm(dev, map, pgs, r, g, b, out);
10979
0
}
10980
10981
static void
10982
pdf14_accum_cmyk_cs_to_cmyk_cm(const gx_device * dev,
10983
    frac c, frac m, frac y, frac k, frac out[])
10984
0
{
10985
0
    const int * map =
10986
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10987
10988
0
    cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out);
10989
0
}
10990
10991
static const gx_cm_color_map_procs pdf14_accum_cm_procs = {
10992
    pdf14_accum_gray_cs_to_cmyk_cm,
10993
    pdf14_accum_rgb_cs_to_cmyk_cm,
10994
    pdf14_accum_cmyk_cs_to_cmyk_cm
10995
};
10996
10997
static const gx_cm_color_map_procs *
10998
pdf14_accum_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev)
10999
0
{
11000
0
    *map_dev = dev;
11001
0
    return &pdf14_accum_cm_procs;
11002
0
}
11003
11004
/*
11005
 *  Device proc for updating the equivalent CMYK color for spot colors.
11006
 */
11007
static int
11008
pdf14_accum_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs, const gs_color_space *pcs)
11009
0
{
11010
0
    gx_device_pdf14_accum *pdev = (gx_device_pdf14_accum *)dev;
11011
0
    gx_device *tdev = ((pdf14_device *)(pdev->save_p14dev))->target;
11012
0
    int code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
11013
0
                                              &pdev->equiv_cmyk_colors);
11014
11015
0
    if (code >= 0 && tdev != NULL)
11016
0
        code = dev_proc(tdev, update_spot_equivalent_colors)(tdev, pgs, pcs);
11017
0
    return code;
11018
0
}
11019
11020
/* Used when doing overprint simulation and have spot colors */
11021
static int
11022
pdf14_update_spot_equivalent_colors(gx_device *dev, const gs_gstate *pgs, const gs_color_space *pcs)
11023
0
{
11024
0
    pdf14_device *pdev = (pdf14_device *)dev;
11025
0
    int code;
11026
11027
    /* Make sure we are not All or None */
11028
0
    if (pcs != NULL && pcs->type->index == gs_color_space_index_Separation &&
11029
0
        pcs->params.separation.sep_type != SEP_OTHER)
11030
0
            return 0;
11031
11032
0
    code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
11033
0
        &pdev->op_pequiv_cmyk_colors);
11034
0
    return code;
11035
0
}
11036
11037
/*
11038
 * Retrieve a list of spot color names for the PDF14 device.
11039
 */
11040
int
11041
put_param_pdf14_spot_names(gx_device * pdev,
11042
                gs_separations * pseparations, gs_param_list * plist)
11043
146k
{
11044
146k
    int code, num_spot_colors, i;
11045
146k
    gs_param_string str;
11046
11047
    /* Check if the given keyname is present. */
11048
146k
    code = param_read_int(plist, PDF14NumSpotColorsParamName,
11049
146k
                                                &num_spot_colors);
11050
146k
    switch (code) {
11051
0
        default:
11052
0
            param_signal_error(plist, PDF14NumSpotColorsParamName, code);
11053
0
            break;
11054
146k
        case 1:
11055
146k
            return 0;
11056
0
        case 0:
11057
0
            if (num_spot_colors < 1 ||
11058
0
                num_spot_colors > GX_DEVICE_COLOR_MAX_COMPONENTS)
11059
0
                return_error(gs_error_rangecheck);
11060
0
            for (i = 0; i < num_spot_colors; i++) {
11061
0
                char buff[20];
11062
0
                byte * sep_name;
11063
11064
0
                gs_snprintf(buff, sizeof(buff), "PDF14SpotName_%d", i);
11065
0
                code = param_read_string(plist, buff, &str);
11066
0
                switch (code) {
11067
0
                    default:
11068
0
                        param_signal_error(plist, buff, code);
11069
0
                        break;
11070
0
                    case 0:
11071
0
                        sep_name = gs_alloc_bytes(pdev->memory,
11072
0
                                str.size, "put_param_pdf14_spot_names");
11073
0
                        if (sep_name == NULL)
11074
0
                            return_error(gs_error_VMerror);
11075
11076
0
                        memcpy(sep_name, str.data, str.size);
11077
0
                        pseparations->names[i].size = str.size;
11078
0
                        pseparations->names[i].data = sep_name;
11079
0
                }
11080
0
            }
11081
0
            pseparations->num_separations = num_spot_colors;
11082
0
            break;
11083
146k
    }
11084
0
    return 0;;
11085
0
}
11086
11087
/*
11088
 * This procedure will have information from the PDF 1.4 clist writing
11089
 * clist compositior device.  This is information output the compressed
11090
 * color list info which is needed for the support of spot colors in
11091
 * PDF 1.4 compositing.  This info needs to be passed to the PDF 1.4
11092
 * clist reading compositor.  However this device is not created until
11093
 * the clist is read.  To get this info to that device, we have to
11094
 * temporarily store that info in the output device.  This routine saves
11095
 * that info in the output device.
11096
 */
11097
int
11098
pdf14_put_devn_params(gx_device * pdev, gs_devn_params * pdevn_params,
11099
                                        gs_param_list * plist)
11100
146k
{
11101
146k
    int code;
11102
146k
    code = put_param_pdf14_spot_names(pdev,
11103
146k
                       &pdevn_params->pdf14_separations, plist);
11104
146k
    return code;
11105
146k
}
11106
11107
/*
11108
 * When we are banding, we have two PDF 1.4 compositor devices.  One for
11109
 * when we are creating the clist.  The second is for imaging the data from
11110
 * the clist.  This routine is part of the clist writing PDF 1.4 device.
11111
 * This routine is only called once the PDF 1.4 clist write compositor already
11112
 * exists.
11113
 */
11114
static  int
11115
pdf14_clist_composite(gx_device * dev, gx_device ** pcdev,
11116
    const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem,
11117
    gx_device *cdev)
11118
4.02M
{
11119
4.02M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11120
4.02M
    int code, is_pdf14_compositor;
11121
4.02M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11122
4.02M
    bool deep = device_is_deep(dev);
11123
11124
    /* We only handle a few PDF 1.4 transparency operations */
11125
4.02M
    if ((is_pdf14_compositor = gs_is_pdf14trans_compositor(pct)) != 0) {
11126
2.54M
        switch (pdf14pct->params.pdf14_op) {
11127
0
            case PDF14_PUSH_DEVICE:
11128
                /* Re-activate the PDF 1.4 compositor */
11129
/*
11130
                We previously did:
11131
11132
                pdev->saved_target_color_info = pdev->target->color_info;
11133
11134
                Here, but since we already saved and modified the the color_info
11135
                of the target clist device in gs_pdf14_clist_device_push() this is
11136
                overwriting saved_target_color_info that we already saved with the
11137
                group color_info, meaning when we set it back again, it's incorrect.
11138
*/
11139
0
                pdev->target->color_info = pdev->color_info;
11140
0
                pdev->saved_target_encode_color = dev_proc(pdev->target, encode_color);
11141
0
                pdev->saved_target_decode_color = dev_proc(pdev->target, decode_color);
11142
0
                set_dev_proc(pdev->target, encode_color, pdev->my_encode_color);
11143
0
                set_dev_proc(pdev, encode_color, pdev->my_encode_color);
11144
0
                set_dev_proc(pdev->target, decode_color, pdev->my_decode_color);
11145
0
                set_dev_proc(pdev, decode_color, pdev->my_decode_color);
11146
0
                pdev->saved_target_get_color_mapping_procs =
11147
0
                                        dev_proc(pdev->target, get_color_mapping_procs);
11148
0
                pdev->saved_target_get_color_comp_index =
11149
0
                                        dev_proc(pdev->target, get_color_comp_index);
11150
0
                set_dev_proc(pdev->target, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11151
0
                set_dev_proc(pdev, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11152
0
                set_dev_proc(pdev->target, get_color_comp_index, pdev->my_get_color_comp_index);
11153
0
                set_dev_proc(pdev, get_color_comp_index, pdev->my_get_color_comp_index);
11154
0
                pdev->save_get_cmap_procs = pgs->get_cmap_procs;
11155
0
                pgs->get_cmap_procs = pdf14_get_cmap_procs;
11156
0
                gx_set_cmap_procs(pgs, dev);
11157
0
                code = pdf14_recreate_clist_device(mem, pgs, dev, pdf14pct);
11158
0
                pdev->blend_mode = pdev->text_knockout = 0;
11159
0
                pdev->opacity = pdev->shape = 0.0;
11160
0
                if (code < 0)
11161
0
                    return code;
11162
                /*
11163
                 * This routine is part of the PDF 1.4 clist write device.
11164
                 * Change the compositor procs to not create another since we
11165
                 * do not need to create a chain of identical devices.
11166
                 */
11167
0
                {
11168
0
                    gs_pdf14trans_t pctemp = *pdf14pct;
11169
11170
0
                    pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type;
11171
0
                    code = dev_proc(pdev->target, composite)
11172
0
                                (pdev->target, pcdev, (gs_composite_t *)&pctemp, pgs, mem, cdev);
11173
                    /* We should never have created a new device here. */
11174
0
                    assert(code != 1);
11175
0
                    return code;
11176
0
                }
11177
16.4k
            case PDF14_POP_DEVICE:
11178
16.4k
            {
11179
16.4k
                gx_device *clistdev = pdev->target;
11180
11181
                /* Find the clist device */
11182
16.4k
                while (1) {
11183
16.4k
                    gxdso_device_child_request req;
11184
                    /* Ignore any errors here, that's expected as non-clist
11185
                     * devices don't implement it. */
11186
16.4k
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_is_clist_device, NULL, 0);
11187
16.4k
                    if (code == 1)
11188
16.4k
                        break;
11189
0
                    req.n = 0;
11190
0
                    req.target = clistdev;
11191
0
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_device_child, &req, sizeof(req));
11192
0
                    if (code < 0)
11193
0
                        return code;
11194
0
                    clistdev = req.target;
11195
0
                }
11196
11197
                /* If we have overprint simulation spot color information, store
11198
                   it in a pseudo-band of the clist */
11199
16.4k
                if (pdev->overprint_sim &&
11200
0
                    pdev->devn_params.page_spot_colors > 0) {
11201
0
                    code = clist_write_op_equiv_cmyk_colors((gx_device_clist_writer *)clistdev,
11202
0
                        &pdev->op_pequiv_cmyk_colors);
11203
0
                    if (code < 0)
11204
0
                        return code;
11205
0
                }
11206
11207
                /* If we hit an error during an SMask, we need to undo the color
11208
                 * swapping before continuing. pdf14_decrement_smask_color() checks
11209
                 * for itself if it needs to take action.
11210
                 */
11211
16.4k
                pdf14_decrement_smask_color(pgs, dev);
11212
                /* Restore the color_info for the clist device */
11213
16.4k
                clistdev->color_info = pdev->saved_target_color_info;
11214
16.4k
                ((gx_device_clist_writer*)clistdev)->clist_color_info = clistdev->color_info; /* also reset for writer */
11215
16.4k
                set_dev_proc(clistdev, encode_color, pdev->saved_target_encode_color);
11216
16.4k
                set_dev_proc(clistdev, decode_color, pdev->saved_target_decode_color);
11217
16.4k
                set_dev_proc(clistdev, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs);
11218
16.4k
                set_dev_proc(clistdev, get_color_comp_index, pdev->saved_target_get_color_comp_index);
11219
16.4k
                pgs->get_cmap_procs = pdev->save_get_cmap_procs;
11220
16.4k
                gx_set_cmap_procs(pgs, clistdev);
11221
16.4k
                gx_device_decache_colors(clistdev);
11222
                /* Disable the PDF 1.4 compositor */
11223
16.4k
                pdf14_disable_clist_device(mem, pgs, dev);
11224
                /*
11225
                 * Make sure that the transfer funtions, etc. are current.
11226
                 */
11227
16.4k
                code = cmd_put_color_mapping((gx_device_clist_writer *)clistdev, pgs);
11228
16.4k
                if (code < 0)
11229
0
                    return code;
11230
16.4k
                break;
11231
16.4k
            }
11232
16.4k
            case PDF14_BEGIN_TRANS_PAGE_GROUP:
11233
84.9k
            case PDF14_BEGIN_TRANS_GROUP:
11234
84.9k
                if (pdev->smask_constructed || pdev->depth_within_smask)
11235
38.9k
                    pdev->depth_within_smask++;
11236
84.9k
                pdev->smask_constructed = 0;
11237
                /*
11238
                 * Keep track of any changes made in the blending parameters.
11239
                   These need to be written out in the same bands as the group
11240
                   information is written.  Hence the passing of the dimensions
11241
                   for the group. */
11242
84.9k
                code = pdf14_clist_update_params(pdev, pgs, true,
11243
84.9k
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11244
84.9k
                if (code < 0)
11245
0
                    return code;
11246
84.9k
                if (pdf14pct->params.Background_components != 0 &&
11247
0
                    pdf14pct->params.Background_components !=
11248
0
                    pdev->color_info.num_components)
11249
0
                    return_error(gs_error_rangecheck);
11250
11251
                /* We need to update the clist writer device procs based upon the
11252
                   the group color space. This ensures the proper color data is
11253
                   written out to the device. For simplicity, the list item is
11254
                   created even if the color space did not change */
11255
84.9k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, false);
11256
84.9k
                if (code < 0)
11257
0
                    return code;
11258
11259
84.9k
                break;
11260
86.6k
            case PDF14_BEGIN_TRANS_MASK:
11261
                /* We need to update the clist writer device procs based upon the
11262
                   the group color space.  For simplicity, the list item is created
11263
                   even if the color space did not change */
11264
                /* First store the current ones */
11265
86.6k
                if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
11266
47.4k
                    break;
11267
11268
                /* Update the color settings of the clist writer.  Store information in stack */
11269
39.2k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, true);
11270
39.2k
                if (code < 0)
11271
0
                    return code;
11272
11273
                /* Also, if the BC is a value that may end up as something other
11274
                  than transparent. We must use the parent colors bounding box in
11275
                  determining the range of bands in which this mask can affect.
11276
                  So, if needed change the masks bounding box at this time */
11277
39.2k
                pdev->in_smask_construction++;
11278
39.2k
                break;
11279
1.04M
            case PDF14_BEGIN_TRANS_TEXT_GROUP:
11280
1.04M
                if (pdev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
11281
0
                    emprintf(pdev->memory, "Warning: Text group pushed but no ET found\n");
11282
0
                    pdev->text_group = PDF14_TEXTGROUP_MISSING_ET;
11283
0
                } else
11284
1.04M
                    pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
11285
1.04M
                *pcdev = dev;
11286
1.04M
                return 0; /* Never put into clist. Only used during writing */
11287
1.08M
            case PDF14_END_TRANS_TEXT_GROUP:
11288
1.08M
                if (pdev->text_group != PDF14_TEXTGROUP_BT_PUSHED) {
11289
1.07M
                    *pcdev = dev;
11290
1.07M
                    return 0; /* Avoids spurious ET calls in interpreter */
11291
1.07M
                }
11292
4.10k
                pdev->text_group = PDF14_TEXTGROUP_NO_BT; /* These can't be nested */
11293
4.10k
                code = pdf14_clist_pop_color_model(dev, pgs);
11294
4.10k
                if (code < 0)
11295
0
                    return code;
11296
4.10k
                break;
11297
39.2k
            case PDF14_END_TRANS_MASK:
11298
39.2k
                pdev->in_smask_construction--;
11299
39.2k
                if (pdev->in_smask_construction < 0)
11300
0
                    pdev->in_smask_construction = 0;
11301
39.2k
                if (pdev->in_smask_construction == 0)
11302
39.0k
                    pdev->smask_constructed = 1;
11303
                /* fallthrough */
11304
120k
            case PDF14_END_TRANS_GROUP:
11305
                /* We need to update the clist writer device procs based upon the
11306
                   the group color space. */
11307
120k
                code = pdf14_clist_pop_color_model(dev, pgs);
11308
120k
                if (pdev->depth_within_smask)
11309
38.9k
                    pdev->depth_within_smask--;
11310
120k
                if (code < 0)
11311
0
                    return code;
11312
120k
                break;
11313
120k
            case PDF14_PUSH_TRANS_STATE:
11314
0
                break;
11315
37.9k
            case PDF14_POP_TRANS_STATE:
11316
37.9k
                break;
11317
39.2k
            case PDF14_PUSH_SMASK_COLOR:
11318
39.2k
                code = pdf14_increment_smask_color(pgs,dev);
11319
39.2k
                *pcdev = dev;
11320
39.2k
                return code;  /* Note, this are NOT put in the clist */
11321
0
                break;
11322
39.2k
            case PDF14_POP_SMASK_COLOR:
11323
39.2k
                code = pdf14_decrement_smask_color(pgs,dev);
11324
39.2k
                *pcdev = dev;
11325
39.2k
                return code;  /* Note, this are NOT put in the clist */
11326
0
                break;
11327
0
            case PDF14_SET_BLEND_PARAMS:
11328
                /* If there is a change we go ahead and apply it to the target */
11329
0
                code = pdf14_clist_update_params(pdev, pgs, false,
11330
0
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11331
0
                *pcdev = dev;
11332
0
                return code;
11333
0
                break;
11334
0
            case PDF14_ABORT_DEVICE:
11335
0
                code = gx_abort_trans_device(pgs, dev);
11336
0
                if (pdev->free_devicen) {
11337
0
                    devn_free_params(dev);
11338
0
                }
11339
0
                pdf14_disable_device(dev);
11340
0
                pdf14_close(dev);
11341
0
                *pcdev = dev;
11342
0
                return code;
11343
0
                break;
11344
0
            default:
11345
0
                break;   /* Pass remaining ops to target */
11346
2.54M
        }
11347
2.54M
    }
11348
1.82M
    code = dev_proc(pdev->target, composite)
11349
1.82M
                        (pdev->target, pcdev, pct, pgs, mem, cdev);
11350
    /* If we were accumulating into a pdf14-clist-accum device, */
11351
    /* we now have to render the page into it's target device */
11352
1.82M
    if (is_pdf14_compositor && pdf14pct->params.pdf14_op == PDF14_POP_DEVICE &&
11353
16.4k
        pdev->target->stype == &st_gx_devn_accum_device) {
11354
11355
6.74k
        int i, y, rows_used;
11356
6.74k
        byte *linebuf;
11357
6.74k
        byte *actual_data;
11358
6.74k
        gx_device_pdf14_accum *tdev = (gx_device_pdf14_accum *)(pdev->target);     /* the printer class clist device used to accumulate */
11359
        /* get the target device we want to send the image to */
11360
6.74k
        gx_device *target = ((pdf14_device *)(tdev->save_p14dev))->target;
11361
6.74k
        gs_image1_t image;
11362
6.74k
        gs_color_space *pcs;
11363
6.74k
        gx_image_enum_common_t *info = NULL;
11364
6.74k
        gx_image_plane_t planes;
11365
6.74k
        gsicc_rendering_param_t render_cond;
11366
6.74k
        cmm_dev_profile_t *dev_profile;
11367
6.74k
        bool save_planar = pdev->num_planar_planes;
11368
6.74k
        gs_devn_params *target_devn_params = dev_proc(target, ret_devn_params)(target);
11369
6.74k
        int save_num_separations;
11370
6.74k
        gs_int_rect rect;
11371
11372
6.74k
        pdev->num_planar_planes = 0;    /* so gx_device_raster is for entire chunky pixel line */
11373
6.74k
        linebuf = gs_alloc_bytes(mem, gx_device_raster((gx_device *)pdev, true), "pdf14-clist_accum pop dev");
11374
6.74k
        pdev->num_planar_planes = save_planar;
11375
11376
        /* As long as we don't have spot colors, we can use ICC colorspace, but spot
11377
         * colors do require devn support
11378
         */
11379
6.74k
        if (tdev->color_info.num_components <= 4 ||
11380
6.74k
             dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) <= 0) {
11381
            /*
11382
             * Set color space in preparation for sending an image.
11383
             */
11384
6.74k
            code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
11385
6.74k
            if (code < 0)
11386
0
                goto put_accum_error;
11387
11388
            /* Need to set this to avoid color management during the
11389
               image color render operation.  Exception is for the special case
11390
               when the destination was CIELAB.  Then we need to convert from
11391
               default RGB to CIELAB in the put image operation.  That will happen
11392
               here as we should have set the profile for the pdf14 device to RGB
11393
               and the target will be CIELAB */
11394
6.74k
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11395
6.74k
            if (code < 0)
11396
0
                goto put_accum_error;
11397
6.74k
            gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile,
11398
6.74k
                                  &(pcs->cmm_icc_profile_data), &render_cond);
11399
            /* pcs takes a reference to the profile data it just retrieved. */
11400
6.74k
            gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_clist_composite");
11401
6.74k
            gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
11402
6.74k
        } else {
11403
             /* DeviceN case -- need to handle spot colors */
11404
0
            code = gs_cspace_new_DeviceN(&pcs, tdev->color_info.num_components,
11405
0
                                         gs_currentcolorspace(pgs), pgs->memory);
11406
0
            if (code < 0)
11407
0
                goto put_accum_error;
11408
            /* set up a usable DeviceN space with info from the tdev->devn_params */
11409
0
            pcs->params.device_n.use_alt_cspace = false;
11410
11411
0
            if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
11412
0
                goto put_accum_error;
11413
0
            }
11414
            /* One last thing -- we need to fudge the pgs->color_component_map */
11415
0
            for (i=0; i < tdev->color_info.num_components; i++)
11416
0
                pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
11417
            /* copy devn_params that were accumulated into the target device's devn_params */
11418
0
            target_devn_params->bitspercomponent = tdev->devn_params.bitspercomponent;
11419
0
            target_devn_params->std_colorant_names = tdev->devn_params.std_colorant_names;
11420
0
            target_devn_params->num_std_colorant_names = tdev->devn_params.num_std_colorant_names;
11421
0
            target_devn_params->max_separations = tdev->devn_params.max_separations;
11422
0
            target_devn_params->page_spot_colors = tdev->devn_params.page_spot_colors;
11423
0
            target_devn_params->num_separation_order_names = tdev->devn_params.num_separation_order_names;
11424
0
            target_devn_params->separations = tdev->devn_params.separations;
11425
0
            memcpy(target_devn_params->separation_order_map, tdev->devn_params.separation_order_map,
11426
0
                   sizeof(gs_separation_map));
11427
0
            target_devn_params->pdf14_separations = tdev->devn_params.pdf14_separations;
11428
0
        }
11429
6.74k
        if (linebuf == NULL) {
11430
0
            code = gs_error_VMerror;
11431
0
            goto put_accum_error;
11432
0
        }
11433
6.74k
        gs_image_t_init_adjust(&image, pcs, false);
11434
6.74k
        image.ImageMatrix.xx = (float)pdev->width;
11435
6.74k
        image.ImageMatrix.yy = (float)pdev->height;
11436
6.74k
        image.Width = pdev->width;
11437
6.74k
        image.Height = pdev->height;
11438
6.74k
        image.BitsPerComponent = 8<<deep;
11439
6.74k
        ctm_only_writable(pgs).xx = (float)pdev->width;
11440
6.74k
        ctm_only_writable(pgs).xy = 0;
11441
6.74k
        ctm_only_writable(pgs).yx = 0;
11442
6.74k
        ctm_only_writable(pgs).yy = (float)pdev->height;
11443
6.74k
        ctm_only_writable(pgs).tx = 0.0;
11444
6.74k
        ctm_only_writable(pgs).ty = 0.0;
11445
6.74k
        code = dev_proc(target, begin_typed_image) (target,
11446
6.74k
                                                    pgs, NULL,
11447
6.74k
                                                    (gs_image_common_t *)&image,
11448
6.74k
                                                    NULL, NULL, NULL,
11449
6.74k
                                                    pgs->memory, &info);
11450
6.74k
        if (code < 0)
11451
0
            goto put_accum_error;
11452
6.74k
        rect.p.x = 0;
11453
6.74k
        rect.q.x = tdev->width;
11454
14.8M
        for (y=0; y < tdev->height; y++) {
11455
14.8M
            gs_get_bits_params_t params;
11456
11457
14.8M
            params.options = (GB_ALIGN_ANY |
11458
14.8M
                              (GB_RETURN_COPY | GB_RETURN_POINTER) |
11459
14.8M
                              GB_OFFSET_0 |
11460
14.8M
                              GB_RASTER_STANDARD | GB_PACKING_CHUNKY |
11461
14.8M
                              GB_COLORS_NATIVE | GB_ALPHA_NONE);
11462
14.8M
            params.x_offset = 0;
11463
14.8M
            params.raster = bitmap_raster(dev->width * dev->color_info.depth);
11464
14.8M
            params.data[0] = linebuf;
11465
14.8M
            rect.p.y = y;
11466
14.8M
            rect.q.y = y+1;
11467
14.8M
            code = dev_proc(tdev, get_bits_rectangle)((gx_device *)tdev,
11468
14.8M
                                                      &rect, &params);
11469
14.8M
            if (code < 0)
11470
6
                goto put_accum_error;
11471
14.8M
            actual_data = params.data[0];
11472
14.8M
            planes.data = actual_data;
11473
14.8M
            planes.data_x = 0;
11474
14.8M
            planes.raster = tdev->width * tdev->color_info.num_components;
11475
14.8M
            if ((code = info->procs->plane_data(info, &planes, 1, &rows_used)) < 0)
11476
0
                goto put_accum_error;
11477
14.8M
        }
11478
11479
6.74k
put_accum_error:
11480
6.74k
        if (info != NULL) {
11481
6.74k
            if (code < 0)
11482
6
                (void)info->procs->end_image(info, true);
11483
6.73k
            else
11484
6.73k
                code = info->procs->end_image(info, true);
11485
6.74k
        }
11486
11487
6.74k
        gs_free_object(pdev->memory, linebuf, "pdf14_put_image");
11488
        /* This will also decrement the device profile */
11489
6.74k
        rc_decrement_only_cs(pcs, "pdf14_put_image");
11490
6.74k
        dev_proc(tdev, close_device)((gx_device *)tdev);  /* frees the prn_device memory */
11491
        /* Now unhook the clist device and hook to the original so we can clean up */
11492
6.74k
        gx_device_set_target((gx_device_forward *)pdev,
11493
6.74k
                             ((gx_device_pdf14_accum *)(pdev->target))->save_p14dev);
11494
6.74k
        pdev->pclist_device = pdev->target;
11495
6.74k
        *pcdev = pdev->target;          /* pass upwards to switch devices */
11496
6.74k
        pdev->color_info = target->color_info;      /* same as in pdf14_disable_clist */
11497
6.74k
        if (target_devn_params != NULL) {
11498
            /* prevent devn_free_params from freeing names still in use by target device */
11499
0
            save_num_separations = tdev->devn_params.separations.num_separations;
11500
0
            tdev->devn_params.separations.num_separations = 0;
11501
0
        }
11502
6.74k
        gs_free_object(tdev->memory, tdev, "popdevice pdf14-accum");
11503
6.74k
        if (target_devn_params != NULL) {
11504
0
            target_devn_params->separations.num_separations = save_num_separations;
11505
0
        }
11506
6.74k
        return code;    /* DON'T perform set_target */
11507
6.74k
    }
11508
1.82M
    if (code == 1) {
11509
        /* We just wrapped pdev->target, so we need to update that.*/
11510
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
11511
0
        code = 0; /* We did not wrap dev. */
11512
0
    }
11513
1.82M
    *pcdev = dev;
11514
1.82M
    return code;
11515
1.82M
}
11516
11517
/*
11518
 * The PDF 1.4 clist compositor is never removed.  (We do not have a 'remove
11519
 * compositor' method.  However the compositor is disabled when we are not
11520
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
11521
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
11522
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
11523
 * to the targer.
11524
 */
11525
static  int
11526
pdf14_clist_forward_composite(gx_device * dev, gx_device * * pcdev,
11527
        const gs_composite_t * pct, gs_gstate * pgs,
11528
        gs_memory_t * mem, gx_device *cdev)
11529
0
{
11530
0
    pdf14_device *pdev = (pdf14_device *)dev;
11531
0
    gx_device * tdev = pdev->target;
11532
0
    gx_device * ndev;
11533
0
    int code;
11534
11535
0
    *pcdev = dev;
11536
0
    if (gs_is_pdf14trans_compositor(pct)) {
11537
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11538
11539
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
11540
0
            return pdf14_clist_composite(dev, &ndev, pct, pgs, mem, cdev);
11541
0
        return 0;
11542
0
    }
11543
0
    code = dev_proc(tdev, composite)(tdev, &ndev, pct, pgs, mem, cdev);
11544
0
    if (code == 1) {
11545
        /* We just wrapped tdev, so update our target. */
11546
0
        gx_device_set_target((gx_device_forward *)pdev, ndev);
11547
0
        code = 0; /* We did not wrap dev. */
11548
0
    }
11549
0
    return code;
11550
0
}
11551
11552
/*
11553
 * If any of the PDF 1.4 transparency blending parameters have changed, we
11554
 * need to send them to the PDF 1.4 compositor on the output side of the clist.
11555
 */
11556
static  int
11557
pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs,
11558
                          bool crop_blend_params,
11559
                          gs_pdf14trans_params_t *group_params)
11560
9.35M
{
11561
9.35M
    gs_pdf14trans_params_t params = { 0 };
11562
9.35M
    gx_device * pcdev;
11563
9.35M
    int changed = 0;
11564
9.35M
    int code = 0;
11565
9.35M
    gs_composite_t *pct_new = NULL;
11566
11567
9.35M
    params.crop_blend_params = crop_blend_params;
11568
11569
9.35M
    params.pdf14_op = PDF14_SET_BLEND_PARAMS;
11570
9.35M
    if (pgs->blend_mode != pdev->blend_mode) {
11571
30.7k
        changed |= PDF14_SET_BLEND_MODE;
11572
30.7k
        params.blend_mode = pdev->blend_mode = pgs->blend_mode;
11573
30.7k
    }
11574
9.35M
    if (pgs->text_knockout != pdev->text_knockout) {
11575
15.9k
        changed |= PDF14_SET_TEXT_KNOCKOUT;
11576
15.9k
        params.text_knockout = pdev->text_knockout = pgs->text_knockout;
11577
15.9k
    }
11578
9.35M
    if (pgs->alphaisshape != pdev->ais) {
11579
5.79k
        changed |= PDF14_SET_AIS;
11580
5.79k
        params.ais = pdev->ais = pgs->alphaisshape;
11581
5.79k
    }
11582
9.35M
    if (pgs->overprint != pdev->overprint) {
11583
34.5k
        changed |= PDF14_SET_OVERPRINT;
11584
34.5k
        params.overprint = pdev->overprint = pgs->overprint;
11585
34.5k
    }
11586
9.35M
    if (pgs->stroke_overprint != pdev->stroke_overprint) {
11587
34.4k
        changed |= PDF14_SET_STROKEOVERPRINT;
11588
34.4k
        params.stroke_overprint = pdev->stroke_overprint = pgs->stroke_overprint;
11589
34.4k
    }
11590
9.35M
    if (pgs->fillconstantalpha != pdev->fillconstantalpha) {
11591
61.6k
        changed |= PDF14_SET_FILLCONSTANTALPHA;
11592
61.6k
        params.fillconstantalpha = pdev->fillconstantalpha = pgs->fillconstantalpha;
11593
61.6k
    }
11594
9.35M
    if (pgs->strokeconstantalpha != pdev->strokeconstantalpha) {
11595
49.8k
        changed |= PDF14_SET_STROKECONSTANTALPHA;
11596
49.8k
        params.strokeconstantalpha = pdev->strokeconstantalpha = pgs->strokeconstantalpha;
11597
49.8k
    }
11598
9.35M
    if ((pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_FILL)) {
11599
99.8k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11600
99.8k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_FILL;
11601
99.8k
        if_debug0m('v', pgs->memory,
11602
99.8k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as PDF14_OP_STATE_FILL \n");
11603
99.8k
    }
11604
9.35M
    if ((!pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_STROKE)) {
11605
101k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11606
101k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_STROKE;
11607
101k
        if_debug0m('v', pgs->memory,
11608
101k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as PDF14_OP_STATE_STROKE \n");
11609
101k
    }
11610
9.35M
    if (crop_blend_params) {
11611
84.9k
        params.ctm = group_params->ctm;
11612
84.9k
        params.bbox = group_params->bbox;
11613
84.9k
    }
11614
9.35M
    params.changed = changed;
11615
    /* Avoid recursion when we have a PDF14_SET_BLEND_PARAMS forced and apply
11616
       now to the target.  Otherwise we send the compositor action
11617
       to the pdf14 device at this time.  This is due to the fact that we
11618
       need to often perform this operation when we are already starting to
11619
       do a compositor action */
11620
9.35M
    if (changed != 0) {
11621
320k
        code = gs_create_pdf14trans(&pct_new, &params, pgs->memory);
11622
320k
        if (code < 0)
11623
0
            return code;
11624
320k
        code = dev_proc(pdev->target, composite)
11625
320k
                    (pdev->target, &pcdev, pct_new, (gs_gstate *)pgs, pgs->memory, NULL);
11626
320k
        gs_free_object(pgs->memory, pct_new, "pdf14_clist_update_params");
11627
320k
    }
11628
9.35M
    return code;
11629
9.35M
}
11630
11631
/*
11632
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11633
 * writing the clist.
11634
 */
11635
static  int
11636
pdf14_clist_fill_path(gx_device *dev, const gs_gstate *pgs,
11637
                           gx_path *ppath, const gx_fill_params *params,
11638
                           const gx_drawing_color *pdcolor,
11639
                           const gx_clip_path *pcpath)
11640
3.24M
{
11641
3.24M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11642
3.24M
    gs_gstate new_pgs = *pgs;
11643
3.24M
    int code;
11644
3.24M
    gs_pattern2_instance_t *pinst = NULL;
11645
3.24M
    gx_device_forward * fdev = (gx_device_forward *)dev;
11646
3.24M
    cmm_dev_profile_t *dev_profile, *fwd_profile;
11647
3.24M
    gsicc_rendering_param_t render_cond;
11648
3.24M
    cmm_profile_t *icc_profile_fwd, *icc_profile_dev;
11649
3.24M
    int push_group = 0;
11650
11651
3.24M
    code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11652
3.24M
    if (code < 0)
11653
0
        return code;
11654
3.24M
    code = dev_proc(fdev->target, get_profile)(fdev->target,  &fwd_profile);
11655
3.24M
    if (code < 0)
11656
0
        return code;
11657
11658
3.24M
    if (dev->color_info.separable_and_linear == GX_CINFO_UNKNOWN_SEP_LIN)
11659
1.33k
        check_device_separable(dev);
11660
11661
3.24M
    gsicc_extract_profile(GS_UNKNOWN_TAG, fwd_profile, &icc_profile_fwd,
11662
3.24M
                          &render_cond);
11663
3.24M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile_dev,
11664
3.24M
                          &render_cond);
11665
11666
    /*
11667
     * Ensure that that the PDF 1.4 reading compositor will have the current
11668
     * blending parameters.  This is needed since the fill_rectangle routines
11669
     * do not have access to the gs_gstate.  Thus we have to pass any
11670
     * changes explictly.
11671
     */
11672
3.24M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11673
3.24M
    if (code < 0)
11674
0
        return code;
11675
    /* If we are doing a shading fill and we are in a transparency group of a
11676
       different color space, then we do not want to do the shading in the
11677
       device color space. It must occur in the source space.  To handle it in
11678
       the device space would require knowing all the nested transparency group
11679
       color space as well as the transparency.  Some of the shading code ignores
11680
       this, so we have to pass on the clist_writer device to enable proper
11681
       mapping to the transparency group color space. */
11682
11683
3.24M
    if (gx_dc_is_pattern2_color(pdcolor)) {
11684
        /* Non-idempotent blends require a transparency
11685
         * group to be pushed because shadings might
11686
         * paint several pixels twice. */
11687
76.3k
        push_group = pgs->fillconstantalpha != 1.0 ||
11688
72.9k
               !blend_is_idempotent(gs_currentblendmode(pgs));
11689
76.3k
        pinst =
11690
76.3k
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11691
76.3k
           pinst->saved->has_transparency = true;
11692
           /* The transparency color space operations are driven by the pdf14
11693
              clist writer device.  */
11694
76.3k
           pinst->saved->trans_device = dev;
11695
76.3k
    }
11696
3.24M
    if (push_group) {
11697
3.44k
        gs_fixed_rect box;
11698
3.44k
        gs_fixed_rect dev_bbox;
11699
11700
3.44k
        if (pcpath) {
11701
3.44k
            gx_cpath_outer_box(pcpath, &box);
11702
3.44k
            (*dev_proc(dev, get_clipping_box)) (dev, &dev_bbox);
11703
3.44k
            rect_intersect(box, dev_bbox);
11704
3.44k
        } else
11705
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11706
11707
3.44k
        if (ppath) {
11708
22
            gs_fixed_rect path_box;
11709
11710
22
            gx_path_bbox(ppath, &path_box);
11711
22
            if (box.p.x < path_box.p.x)
11712
22
                box.p.x = path_box.p.x;
11713
22
            if (box.p.y < path_box.p.y)
11714
22
                box.p.y = path_box.p.y;
11715
22
            if (box.q.x > path_box.q.x)
11716
22
                box.q.x = path_box.q.x;
11717
22
            if (box.q.y > path_box.q.y)
11718
22
                box.q.y = path_box.q.y;
11719
22
        }
11720
11721
3.44k
        if (box.p.y >= box.q.y || box.p.x >= box.q.x) {
11722
            /* No need to do anything */
11723
747
            if (pinst != NULL) {
11724
747
                pinst->saved->trans_device = NULL;
11725
747
            }
11726
747
            return 0;
11727
747
        }
11728
11729
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11730
2.69k
        code = push_shfill_group(pdev, &new_pgs, &box);
11731
2.69k
    } else
11732
3.23M
        update_lop_for_pdf14(&new_pgs, pdcolor);
11733
3.24M
    if (code >= 0) {
11734
3.24M
        new_pgs.trans_device = dev;
11735
3.24M
        new_pgs.has_transparency = true;
11736
3.24M
        if (gx_dc_is_pattern2_color(pdcolor))
11737
75.6k
            code = gx_default_fill_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11738
3.16M
        else
11739
3.16M
            code = gx_forward_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11740
3.24M
        new_pgs.trans_device = NULL;
11741
3.24M
        new_pgs.has_transparency = false;
11742
3.24M
    }
11743
3.24M
    if (code >= 0 && push_group) {
11744
2.69k
        code = pop_shfill_group(&new_pgs);
11745
2.69k
        if (code >= 0)
11746
2.69k
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11747
2.69k
    }
11748
3.24M
    if (pinst != NULL){
11749
75.6k
        pinst->saved->trans_device = NULL;
11750
75.6k
    }
11751
3.24M
    return code;
11752
3.24M
}
11753
11754
/*
11755
 * stroke_path routine for the PDF 1.4 transparency compositor device for
11756
 * writing the clist.
11757
 */
11758
static  int
11759
pdf14_clist_stroke_path(gx_device *dev, const gs_gstate *pgs,
11760
                             gx_path *ppath, const gx_stroke_params *params,
11761
                             const gx_drawing_color *pdcolor,
11762
                             const gx_clip_path *pcpath)
11763
818k
{
11764
818k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11765
818k
    gs_gstate new_pgs = *pgs;
11766
818k
    int code = 0;
11767
818k
    gs_pattern2_instance_t *pinst = NULL;
11768
818k
    int push_group = 0;
11769
11770
    /*
11771
     * Ensure that that the PDF 1.4 reading compositor will have the current
11772
     * blending parameters.  This is needed since the fill_rectangle routines
11773
     * do not have access to the gs_gstate.  Thus we have to pass any
11774
     * changes explictly.
11775
     */
11776
818k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11777
818k
    if (code < 0)
11778
0
        return code;
11779
    /* If we are doing a shading stroke and we are in a transparency group of a
11780
       different color space, then we need to get the proper device information
11781
       passed along so that we use the correct color procs and colorinfo about
11782
       the transparency device and not the final target device */
11783
818k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11784
        /* Non-idempotent blends require a transparency
11785
         * group to be pushed because shadings might
11786
         * paint several pixels twice. */
11787
322
        push_group = pgs->strokeconstantalpha != 1.0 ||
11788
322
               !blend_is_idempotent(gs_currentblendmode(pgs));
11789
322
        if (pdev->color_model_stack != NULL) {
11790
322
            pinst =
11791
322
                (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11792
322
            pinst->saved->has_transparency = true;
11793
            /* The transparency color space operations are driven
11794
              by the pdf14 clist writer device.  */
11795
322
            pinst->saved->trans_device = dev;
11796
322
        }
11797
322
    }
11798
818k
    if (push_group) {
11799
0
        gs_fixed_rect box;
11800
0
        if (pcpath)
11801
0
            gx_cpath_outer_box(pcpath, &box);
11802
0
        else
11803
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11804
0
        if (ppath) {
11805
0
            gs_fixed_rect path_box;
11806
0
            gs_fixed_point expansion;
11807
11808
0
            gx_path_bbox(ppath, &path_box);
11809
            /* Expand the path bounding box by the scaled line width. */
11810
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
11811
                /* The expansion is so large it caused a limitcheck. */
11812
0
                path_box.p.x = path_box.p.y = min_fixed;
11813
0
                path_box.q.x = path_box.q.y = max_fixed;
11814
0
            } else {
11815
0
                expansion.x += pgs->fill_adjust.x;
11816
0
                expansion.y += pgs->fill_adjust.y;
11817
                /*
11818
                 * It's theoretically possible for the following computations to
11819
                 * overflow, so we need to check for this.
11820
                 */
11821
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
11822
0
                                path_box.p.x - expansion.x);
11823
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
11824
0
                                path_box.p.y - expansion.y);
11825
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
11826
0
                                path_box.q.x + expansion.x);
11827
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
11828
0
                                path_box.q.y + expansion.y);
11829
0
            }
11830
0
            if (box.p.x < path_box.p.x)
11831
0
                box.p.x = path_box.p.x;
11832
0
            if (box.p.y < path_box.p.y)
11833
0
                box.p.y = path_box.p.y;
11834
0
            if (box.q.x > path_box.q.x)
11835
0
                box.q.x = path_box.q.x;
11836
0
            if (box.q.y > path_box.q.y)
11837
0
                box.q.y = path_box.q.y;
11838
0
        }
11839
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11840
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
11841
0
        code = push_shfill_group(pdev, &new_pgs, &box);
11842
0
    } else
11843
818k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11844
11845
818k
    if (code >= 0) {
11846
818k
        new_pgs.trans_device = dev;
11847
818k
        new_pgs.has_transparency = true;
11848
818k
        if (gx_dc_is_pattern2_color(pdcolor))
11849
322
            code = gx_default_stroke_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11850
817k
        else
11851
817k
            code = gx_forward_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11852
818k
        new_pgs.trans_device = NULL;
11853
818k
        new_pgs.has_transparency = false;
11854
818k
    }
11855
818k
    if (code >= 0 && push_group) {
11856
0
        code = pop_shfill_group(&new_pgs);
11857
0
        if (code >= 0)
11858
0
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11859
0
    }
11860
818k
    if (pinst != NULL)
11861
322
        pinst->saved->trans_device = NULL;
11862
818k
    return code;
11863
818k
}
11864
11865
/* Set up work for doing shading patterns in fill stroke through
11866
   the clist.  We have to do all the dirty work now since we are
11867
   going through the default fill and stroke operations individually */
11868
static int
11869
pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs, gx_path* ppath,
11870
    const gx_fill_params* params_fill, const gx_drawing_color* pdevc_fill,
11871
    const gx_stroke_params* params_stroke, const gx_drawing_color* pdevc_stroke,
11872
    const gx_clip_path* pcpath)
11873
0
{
11874
0
    union {
11875
0
        const gs_gstate *cpgs;
11876
0
        gs_gstate *pgs;
11877
0
    } const_breaker;
11878
0
    gs_gstate *pgs;
11879
0
    int code, code2;
11880
0
    gs_transparency_group_params_t params = { 0 };
11881
0
    gs_fixed_rect clip_bbox;
11882
0
    gs_rect bbox, group_stroke_box;
11883
0
    float fill_alpha;
11884
0
    float stroke_alpha;
11885
0
    gs_blend_mode_t blend_mode;
11886
0
    gs_fixed_rect path_bbox;
11887
0
    int expansion_code;
11888
0
    gs_fixed_point expansion;
11889
11890
    /* Break const just once, neatly */
11891
0
    const_breaker.cpgs = cpgs;
11892
0
    pgs = const_breaker.pgs;
11893
11894
0
    fill_alpha = pgs->fillconstantalpha;
11895
0
    stroke_alpha = pgs->strokeconstantalpha;
11896
0
    blend_mode = pgs->blend_mode;
11897
11898
0
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
11899
0
    if (code < 0 && code != gs_error_unknownerror)
11900
0
        return code;
11901
0
    if (code == gs_error_unknownerror) {
11902
        /* didn't get clip box from gx_curr_fixed_bbox */
11903
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
11904
0
        clip_bbox.q.x = int2fixed(dev->width);
11905
0
        clip_bbox.q.y = int2fixed(dev->height);
11906
0
    }
11907
0
    if (pcpath)
11908
0
        rect_intersect(clip_bbox, pcpath->outer_box);
11909
11910
    /* expand the ppath using stroke expansion rule, then intersect it */
11911
0
    code = gx_path_bbox(ppath, &path_bbox);
11912
0
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0)
11913
0
        return 0;   /* ignore empty path */
11914
0
    if (code < 0)
11915
0
        return code;
11916
0
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
11917
0
    if (expansion_code >= 0) {
11918
0
        path_bbox.p.x -= expansion.x;
11919
0
        path_bbox.p.y -= expansion.y;
11920
0
        path_bbox.q.x += expansion.x;
11921
0
        path_bbox.q.y += expansion.y;
11922
0
    }
11923
0
    rect_intersect(path_bbox, clip_bbox);
11924
0
    bbox.p.x = fixed2float(path_bbox.p.x);
11925
0
    bbox.p.y = fixed2float(path_bbox.p.y);
11926
0
    bbox.q.x = fixed2float(path_bbox.q.x);
11927
0
    bbox.q.y = fixed2float(path_bbox.q.y);
11928
11929
0
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
11930
0
    if (code < 0)
11931
0
        return code;
11932
11933
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
11934
0
    if (pgs->fillconstantalpha == pgs->strokeconstantalpha &&
11935
0
        pgs->overprint && pgs->stroke_overprint &&
11936
0
        (dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11937
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
11938
11939
0
        params.Isolated = false;
11940
0
        params.group_color_type = UNKNOWN;
11941
0
        params.Knockout = false;
11942
0
        params.page_group = false;
11943
0
        params.group_opacity = fill_alpha;
11944
0
        params.group_shape = 1.0;
11945
11946
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
11947
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11948
0
        if (code < 0)
11949
0
            return code;
11950
11951
        /* Set alpha to 1.0 and compatible overprint mode for actual drawings */
11952
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11953
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
11954
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11955
11956
0
        code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11957
0
        if (code < 0)
11958
0
            goto cleanup;
11959
11960
0
        code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11961
0
        if (code < 0)
11962
0
            goto cleanup;
11963
11964
0
    } else {
11965
        /* Push a non-isolated knockout group. Do not change the alpha or
11966
           blend modes */
11967
0
        params.Isolated = false;
11968
0
        params.group_color_type = UNKNOWN;
11969
0
        params.Knockout = true;
11970
0
        params.page_group = false;
11971
0
        params.group_opacity = 1.0;
11972
0
        params.group_shape = 1.0;
11973
11974
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
11975
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11976
0
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11977
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11978
11979
        /* restore blend mode for actual drawing in the group */
11980
0
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11981
11982
0
        if (fill_alpha > 0.0) {
11983
0
            (void)gs_setfillconstantalpha(pgs, fill_alpha);
11984
11985
            /* If we are in an overprint situation, set the blend mode to compatible
11986
               overprint */
11987
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11988
0
                pgs->overprint &&
11989
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11990
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11991
11992
0
            code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11993
0
            if (code < 0)
11994
0
                goto cleanup;
11995
11996
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11997
0
                pgs->overprint &&
11998
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11999
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
12000
0
        }
12001
12002
0
        if (stroke_alpha > 0.0) {
12003
            /* Note that the stroke can end up looking like a fill here */
12004
0
            (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
12005
0
            (void)gs_setfillconstantalpha(pgs, stroke_alpha);
12006
12007
0
            if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
12008
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
12009
12010
0
            code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
12011
0
            if (code < 0)
12012
0
                goto cleanup;
12013
12014
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
12015
0
                pgs->overprint &&
12016
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
12017
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
12018
0
        }
12019
0
    }
12020
12021
0
cleanup:
12022
    /* Now during the pop do the compositing with alpha of 1.0 and normal blend */
12023
0
    (void)gs_setfillconstantalpha(pgs, 1.0);
12024
0
    (void)gs_setstrokeconstantalpha(pgs, 1.0);
12025
0
    (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
12026
12027
    /* Restore where we were. If an error occured while in the group push
12028
       return that error code but try to do the cleanup */
12029
0
    code2 = gs_end_transparency_group(pgs);
12030
0
    if (code2 < 0) {
12031
        /* At this point things have gone very wrong. We should just shut down */
12032
0
        code = gs_abort_pdf14trans_device(pgs);
12033
0
        return code2;
12034
0
    }
12035
12036
    /* Restore if there were any changes */
12037
0
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
12038
0
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
12039
0
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
12040
12041
0
    return code;
12042
0
}
12043
12044
/*
12045
 * fill_path routine for the PDF 1.4 transaprency compositor device for
12046
 * writing the clist.
12047
 */
12048
static  int
12049
pdf14_clist_fill_stroke_path(gx_device  *dev, const gs_gstate *pgs, gx_path *ppath,
12050
                             const gx_fill_params *params_fill, const gx_drawing_color *pdevc_fill,
12051
                             const gx_stroke_params *params_stroke, const gx_drawing_color *pdevc_stroke,
12052
                             const gx_clip_path *pcpath)
12053
17.0k
{
12054
17.0k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12055
17.0k
    gs_gstate new_pgs = *pgs;
12056
17.0k
    int code;
12057
12058
17.0k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
12059
16.9k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
12060
108
        return 0;
12061
12062
    /*
12063
     * Ensure that that the PDF 1.4 reading compositor will have the current
12064
     * blending parameters.  This is needed since the fill_rectangle routines
12065
     * do not have access to the gs_gstate.  Thus we have to pass any
12066
     * changes explictly.
12067
     */
12068
16.9k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12069
16.9k
    if (code < 0)
12070
0
        return code;
12071
    /* If we are doing a shading fill or stroke, the clist can't
12072
       deal with this and end up in the pdf_fill_stroke operation.
12073
       We will need to break up the fill stroke now and do
12074
       the appropriate group pushes and set up. */
12075
12076
16.9k
    if (gx_dc_is_pattern2_color(pdevc_fill) ||
12077
16.9k
        gx_dc_is_pattern2_color(pdevc_stroke)) {
12078
0
        return pdf14_clist_fill_stroke_path_pattern_setup(dev, pgs, ppath,
12079
0
            params_fill, pdevc_fill, params_stroke, pdevc_stroke, pcpath);
12080
0
    }
12081
16.9k
    update_lop_for_pdf14(&new_pgs, pdevc_fill);
12082
16.9k
    new_pgs.trans_device = dev;
12083
16.9k
    new_pgs.has_transparency = true;
12084
16.9k
    code = gx_forward_fill_stroke_path(dev, &new_pgs, ppath, params_fill, pdevc_fill,
12085
16.9k
                                       params_stroke, pdevc_stroke, pcpath);
12086
16.9k
    new_pgs.trans_device = NULL;
12087
16.9k
    new_pgs.has_transparency = false;
12088
16.9k
    return code;
12089
16.9k
}
12090
12091
/*
12092
 * text_begin routine for the PDF 1.4 transaprency compositor device for
12093
 * writing the clist.
12094
 */
12095
static  int
12096
pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs,
12097
                 const gs_text_params_t * text, gs_font * font,
12098
                 const gx_clip_path * pcpath,
12099
                 gs_text_enum_t ** ppenum)
12100
5.09M
{
12101
5.09M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12102
5.09M
    gs_text_enum_t *penum;
12103
5.09M
    int code;
12104
5.09M
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
12105
5.09M
    float opacity = pgs->fillconstantalpha;
12106
5.09M
    float shape = 1.0;
12107
5.09M
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
12108
5.09M
    bool draw = !(text->operation & TEXT_DO_NONE);
12109
5.09M
    uint text_mode = gs_currenttextrenderingmode(pgs);
12110
5.09M
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
12111
5.09M
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
12112
12113
5.09M
    if_debug0m('v', pgs->memory, "[v]pdf14_clist_text_begin\n");
12114
    /*
12115
     * Ensure that that the PDF 1.4 reading compositor will have the current
12116
     * blending parameters.  This is needed since the fill_rectangle routines
12117
     * do not have access to the gs_gstate.  Thus we have to pass any
12118
     * changes explictly.
12119
     */
12120
5.09M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12121
5.09M
    if (code < 0)
12122
0
        return code;
12123
    /* Pass text_begin to the target */
12124
5.09M
    code = gx_forward_text_begin(dev, pgs, text, font,
12125
5.09M
                                 pcpath, &penum);
12126
5.09M
    if (code < 0)
12127
1.52k
        return code;
12128
12129
   /* Catch case where we already pushed a group and are trying to push another one.
12130
   In that case, we will pop the current one first, as we don't want to be left
12131
   with it. Note that if we have a BT and no other BTs or ETs then this issue
12132
   will not be caught until we do the put_image and notice that the stack is not
12133
   empty. */
12134
5.09M
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
12135
0
        code = gs_end_transparency_group(pgs);
12136
0
        if (code < 0)
12137
0
            return code;
12138
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
12139
0
    }
12140
12141
    /* We may need to push a non-isolated transparency group if the following
12142
    is true.
12143
    1) We are not currently in one that we pushed for text.  This is
12144
    is determined by looking at the pdf14 device.
12145
    2) The blend mode is not Normal or the opacity is not 1.0
12146
    3) Text knockout is set to true
12147
    4) And we are actually drawing text
12148
    */
12149
12150
5.09M
    if (gs_currenttextknockout(pgs) && (blend_issue ||
12151
5.08M
        (pgs->fillconstantalpha != 1.0 && text_fill) ||
12152
5.07M
        (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
12153
17.8k
        text_mode != 3 && /* don't bother with invisible text */
12154
17.7k
        pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED) {
12155
4.12k
        if (draw) {
12156
4.12k
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape, true);
12157
4.12k
            if (code == 0)
12158
4.12k
                pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* Needed during clist writing */
12159
4.12k
        }
12160
4.12k
    }
12161
5.09M
    *ppenum = (gs_text_enum_t *)penum;
12162
5.09M
    return code;
12163
5.09M
}
12164
12165
static  int
12166
pdf14_clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
12167
                           const gs_matrix *pmat, const gs_image_common_t *pic,
12168
                           const gs_int_rect * prect,
12169
                           const gx_drawing_color * pdcolor,
12170
                           const gx_clip_path * pcpath, gs_memory_t * mem,
12171
                           gx_image_enum_common_t ** pinfo)
12172
84.4k
{
12173
84.4k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12174
84.4k
    int code;
12175
84.4k
    gs_gstate * pgs_noconst = (gs_gstate *)pgs; /* Break 'const'. */
12176
84.4k
    const gs_image_t *pim = (const gs_image_t *)pic;
12177
84.4k
    gx_image_enum *penum;
12178
84.4k
    gx_color_tile *ptile;
12179
84.4k
    gs_rect bbox_in, bbox_out;
12180
84.4k
    gs_transparency_group_params_t tgp;
12181
    /*
12182
     * Ensure that that the PDF 1.4 reading compositor will have the current
12183
     * blending parameters.  This is needed since the fill_rectangle routines
12184
     * do not have access to the gs_gstate.  Thus we have to pass any
12185
     * changes explictly.
12186
     */
12187
84.4k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12188
84.4k
    if (code < 0)
12189
0
        return code;
12190
    /* Pass image to the target */
12191
    /* Do a quick change to the gs_gstate so that if we can return with -1 in
12192
       case the clist writer cannot handle this image itself.  In such a case,
12193
       we want to make sure we dont use the target device.  I don't necc. like
12194
       doing it this way.  Probably need to go back and do something a bit
12195
       more elegant. */
12196
84.4k
    pgs_noconst->has_transparency = true;
12197
84.4k
    pgs_noconst->trans_device = dev;
12198
12199
    /* If we are filling an image mask with a pattern that has a transparency
12200
       then we need to do some special handling */
12201
84.4k
    if (pim->ImageMask) {
12202
66
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
12203
21
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
12204
0
                if (dev_proc(dev, begin_typed_image) != pdf14_clist_begin_typed_image) {
12205
0
                    ptile = pdcolor->colors.pattern.p_tile;
12206
                    /* Set up things in the ptile so that we get the proper
12207
                       blending etc */
12208
                    /* Set the blending procs and the is_additive setting based
12209
                       upon the number of channels */
12210
0
                    if (ptile->ttrans->n_chan-1 < 4) {
12211
0
                        ptile->ttrans->blending_procs = &rgb_blending_procs;
12212
0
                        ptile->ttrans->is_additive = true;
12213
0
                    } else {
12214
0
                        ptile->ttrans->blending_procs = &cmyk_blending_procs;
12215
0
                        ptile->ttrans->is_additive = false;
12216
0
                    }
12217
                    /* Set the blending mode in the ptile based upon the current
12218
                       setting in the gs_gstate */
12219
0
                    ptile->blending_mode = pgs->blend_mode;
12220
                    /* Set the procs so that we use the proper filling method. */
12221
                    /* Let the imaging stuff get set up */
12222
0
                    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
12223
0
                                                        prect, pdcolor,
12224
0
                                                        pcpath, mem, pinfo);
12225
0
                    if (code < 0)
12226
0
                        return code;
12227
12228
0
                    penum = (gx_image_enum *) *pinfo;
12229
                    /* Apply inverse of the image matrix to our
12230
                       image size to get our bounding box. */
12231
0
                    bbox_in.p.x = 0;
12232
0
                    bbox_in.p.y = 0;
12233
0
                    bbox_in.q.x = pim->Width;
12234
0
                    bbox_in.q.y = pim->Height;
12235
0
                    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
12236
0
                                                     &bbox_out);
12237
0
                    if (code < 0)
12238
0
                        return code;
12239
                    /* Set up a compositor action for pushing the group */
12240
0
                    if_debug0m('v', pgs->memory, "[v]Pushing special trans group for image\n");
12241
0
                    tgp.Isolated = true;
12242
0
                    tgp.Knockout = false;
12243
0
                    tgp.page_group = false;
12244
0
                    tgp.mask_id = 0;
12245
0
                    tgp.image_with_SMask = false;
12246
0
                    tgp.idle = false;
12247
0
                    tgp.iccprofile = NULL;
12248
0
                    tgp.icc_hashcode = 0;
12249
0
                    tgp.group_color_numcomps = ptile->ttrans->n_chan-1;
12250
0
                    tgp.ColorSpace = NULL;
12251
0
                    tgp.text_group = 0;
12252
0
                    tgp.group_opacity = pgs->fillconstantalpha;
12253
0
                    tgp.group_shape = 1.0;
12254
                    /* This will handle the compositor command */
12255
0
                    gs_begin_transparency_group((gs_gstate *) pgs_noconst, &tgp,
12256
0
                                                &bbox_out, PDF14_BEGIN_TRANS_GROUP);
12257
0
                    ptile->ttrans->image_render = penum->render;
12258
0
                    penum->render = &pdf14_pattern_trans_render;
12259
0
                    ptile->trans_group_popped = false;
12260
0
                    pgs_noconst->has_transparency = false;
12261
0
                    pgs_noconst->trans_device = NULL;
12262
0
                    return code;
12263
0
                }
12264
0
            }
12265
21
        }
12266
66
    }
12267
    /* This basically tries high level images for clist. If that fails
12268
       then we do the default */
12269
84.4k
    code = gx_forward_begin_typed_image(dev, pgs, pmat,
12270
84.4k
                            pic, prect, pdcolor, pcpath, mem, pinfo);
12271
84.4k
    if (code < 0){
12272
24.1k
        code = gx_default_begin_typed_image(dev, pgs, pmat, pic, prect,
12273
24.1k
                                        pdcolor, pcpath, mem, pinfo);
12274
24.1k
        pgs_noconst->has_transparency = false;
12275
24.1k
        pgs_noconst->trans_device = NULL;
12276
24.1k
        return code;
12277
60.3k
    } else {
12278
60.3k
        pgs_noconst->has_transparency = false;
12279
60.3k
        pgs_noconst->trans_device = NULL;
12280
60.3k
        return code;
12281
60.3k
    }
12282
84.4k
}
12283
12284
static int
12285
pdf14_clist_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
12286
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
12287
2.45k
{
12288
2.45k
    int code;
12289
12290
2.45k
    code = gx_forward_copy_planes(dev, data, data_x, raster, id,
12291
2.45k
                                  x, y, w, h, plane_height);
12292
2.45k
    return code;
12293
2.45k
}
12294
12295
static int
12296
gs_pdf14_clist_device_push(gs_memory_t *mem, gs_gstate *pgs, gx_device **pcdev,
12297
                           gx_device *dev, const gs_pdf14trans_t *pdf14pct)
12298
17.2k
{
12299
17.2k
    int code;
12300
17.2k
    pdf14_clist_device *p14dev;
12301
17.2k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12302
12303
17.2k
    code = pdf14_create_clist_device(mem, pgs, pcdev, dev, pdf14pct);
12304
17.2k
    if (code < 0)
12305
0
        return code;
12306
    /*
12307
     * Set the color_info of the clist device to match the compositing
12308
     * device.  We will restore it when the compositor is popped.
12309
     * See pdf14_clist_composite for the restore.  Do the
12310
     * same with the gs_gstate's get_cmap_procs.  We do not want
12311
     * the gs_gstate to use transfer functions on our color values.
12312
     * The transfer functions will be applied at the end after we
12313
     * have done our PDF 1.4 blend operations.
12314
     */
12315
17.2k
    p14dev = (pdf14_clist_device *)(*pcdev);
12316
17.2k
    p14dev->saved_target_color_info = dev->color_info;
12317
17.2k
    dev->color_info = (*pcdev)->color_info;
12318
    /* Make sure that we keep the anti-alias information though */
12319
17.2k
    dev->color_info.anti_alias = p14dev->saved_target_color_info.anti_alias;
12320
17.2k
    p14dev->color_info.anti_alias = dev->color_info.anti_alias;
12321
12322
    /* adjust the clist_color_info now */
12323
17.2k
    cdev->clist_color_info.depth = p14dev->color_info.depth;
12324
17.2k
    cdev->clist_color_info.polarity = p14dev->color_info.polarity;
12325
17.2k
    cdev->clist_color_info.num_components = p14dev->color_info.num_components;
12326
17.2k
    cdev->clist_color_info.max_color = p14dev->color_info.max_color;
12327
17.2k
    cdev->clist_color_info.max_gray = p14dev->color_info.max_gray;
12328
12329
17.2k
    p14dev->saved_target_encode_color = dev_proc(dev, encode_color);
12330
17.2k
    p14dev->saved_target_decode_color = dev_proc(dev, decode_color);
12331
17.2k
    set_dev_proc(dev, encode_color, p14dev->my_encode_color);
12332
17.2k
    set_dev_proc(p14dev, encode_color, p14dev->my_encode_color);
12333
17.2k
    set_dev_proc(dev, decode_color, p14dev->my_decode_color);
12334
17.2k
    set_dev_proc(p14dev, decode_color, p14dev->my_decode_color);
12335
17.2k
    p14dev->saved_target_get_color_mapping_procs =
12336
17.2k
                              dev_proc(dev, get_color_mapping_procs);
12337
17.2k
    p14dev->saved_target_get_color_comp_index =
12338
17.2k
                              dev_proc(dev, get_color_comp_index);
12339
17.2k
    set_dev_proc(dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12340
17.2k
    set_dev_proc(p14dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12341
17.2k
    set_dev_proc(dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12342
17.2k
    set_dev_proc(p14dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12343
17.2k
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
12344
17.2k
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
12345
17.2k
    gx_set_cmap_procs(pgs, dev);
12346
17.2k
    return code;
12347
17.2k
}
12348
/*
12349
 * When we push a PDF 1.4 transparency compositor onto the clist, we also need
12350
 * to create a compositing device for clist writing.  The primary purpose of
12351
 * this device is to provide support for the process color model in which
12352
 * the PDF 1.4 transparency is done.  (This may differ from the process color
12353
 * model of the output device.)  The actual work of compositing the image is
12354
 * done on the output (reader) side of the clist.
12355
 */
12356
static  int
12357
c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev,
12358
                gx_device ** pcdev, gs_gstate * pgs, gs_memory_t * mem)
12359
688k
{
12360
688k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12361
688k
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte;
12362
688k
    int code = 0;
12363
12364
    /* We only handle the push/pop operations */
12365
688k
    switch (pdf14pct->params.pdf14_op) {
12366
17.2k
        case PDF14_PUSH_DEVICE:
12367
17.2k
            code = gs_pdf14_clist_device_push(mem, pgs, pcdev, dev, pdf14pct);
12368
            /* Change (non-error) code to 1 to indicate that we created
12369
             * a device. */
12370
17.2k
            if (code >= 0)
12371
17.2k
                code = 1;
12372
17.2k
            return code;
12373
12374
16.4k
        case PDF14_POP_DEVICE:
12375
16.4k
            code = clist_writer_check_empty_cropping_stack(cdev);
12376
16.4k
            break;
12377
12378
6.80k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12379
84.9k
        case PDF14_BEGIN_TRANS_GROUP:
12380
84.9k
            { /* HACK: store mask_id into our params for subsequent
12381
                   calls of c_pdf14trans_write. To do this we must
12382
                   break const. */
12383
84.9k
                gs_pdf14trans_t * pdf14pct_noconst;
12384
12385
84.9k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12386
                /* What ever the current mask ID is, that is the
12387
                   softmask group through which this transparency
12388
                   group must be rendered. Store it now. */
12389
84.9k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12390
84.9k
                if_debug1m('v', pgs->memory,
12391
84.9k
                           "[v]c_pdf14trans_clist_write_update group mask_id=%d \n",
12392
84.9k
                           cdev->mask_id);
12393
84.9k
            }
12394
84.9k
            break;
12395
80.8k
        case PDF14_END_TRANS_GROUP:
12396
84.9k
        case PDF14_END_TRANS_TEXT_GROUP:
12397
84.9k
            code = 0; /* A place for breakpoint. */
12398
84.9k
            break;
12399
86.6k
        case PDF14_BEGIN_TRANS_MASK:
12400
            /* A new mask has been started */
12401
86.6k
            cdev->mask_id = ++cdev->mask_id_count;
12402
            /* replacing is set everytime that we
12403
               have a zpushtransparencymaskgroup */
12404
86.6k
            { /* HACK: store mask_id into our params for subsequent
12405
                   calls of c_pdf14trans_write. To do this we must
12406
                   break const. */
12407
86.6k
                gs_pdf14trans_t * pdf14pct_noconst;
12408
12409
86.6k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12410
86.6k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12411
86.6k
                if_debug1m('v', pgs->memory,
12412
86.6k
                           "[v]c_pdf14trans_clist_write_update mask mask_id=%d \n",
12413
86.6k
                           cdev->mask_id);
12414
86.6k
            }
12415
86.6k
            break;
12416
39.2k
        case PDF14_END_TRANS_MASK:
12417
39.2k
            code = 0; /* A place for breakpoint. */
12418
39.2k
            break;
12419
0
        case PDF14_PUSH_TRANS_STATE:
12420
0
            code = 0; /* A place for breakpoint. */
12421
0
            break;
12422
37.9k
        case PDF14_POP_TRANS_STATE:
12423
37.9k
            code = 0; /* A place for breakpoint. */
12424
37.9k
            break;
12425
0
        case PDF14_ABORT_DEVICE:
12426
0
            code = 0;
12427
0
            break;
12428
0
        case PDF14_PUSH_SMASK_COLOR:
12429
0
            *pcdev = dev;
12430
0
            return 0;
12431
0
            break;
12432
0
        case PDF14_POP_SMASK_COLOR:
12433
0
            *pcdev = dev;
12434
0
            return 0;
12435
0
            break;
12436
320k
        default:
12437
320k
            break;   /* do nothing for remaining ops */
12438
688k
    }
12439
670k
    *pcdev = dev;
12440
670k
    if (code < 0)
12441
0
        return code;
12442
    /* See c_pdf14trans_write, c_pdf14trans_adjust_ctm, and
12443
       apply_composite. */
12444
670k
    code = gs_gstate_setmatrix(&cdev->gs_gstate, &pdf14pct->params.ctm);
12445
    /* Wrote an extra ctm. */
12446
670k
    cmd_clear_known(cdev, ctm_known);
12447
12448
670k
    return code;
12449
670k
}
12450
12451
/*
12452
 * When we push a PDF 1.4 transparency compositor, we need to make the clist
12453
 * device color_info data match the compositing device.  We need to do this
12454
 * since the PDF 1.4 transparency compositing device may use a different
12455
 * process color model than the output device.  We do not need to modify the
12456
 * color related device procs since the compositing device has its own.  We
12457
 * restore the color_info data when the transparency device is popped.
12458
 */
12459
static  int
12460
c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
12461
                gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem)
12462
50.0M
{
12463
50.0M
    pdf14_device * p14dev = (pdf14_device *)tdev;
12464
50.0M
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12465
50.0M
    gs_devn_params * pclist_devn_params;
12466
50.0M
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)cdev;
12467
50.0M
    cmm_profile_t *cl_icc_profile, *p14_icc_profile;
12468
50.0M
    gsicc_rendering_param_t render_cond;
12469
50.0M
    cmm_dev_profile_t *dev_profile;
12470
12471
50.0M
    dev_proc(cdev, get_profile)(cdev,  &dev_profile);
12472
50.0M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &cl_icc_profile,
12473
50.0M
                          &render_cond);
12474
12475
    /* If we are using the blending color space, then be sure to use that. */
12476
50.0M
    if (p14dev->blend_cs_state == PDF14_BLEND_CS_SPECIFIED &&
12477
0
        dev_profile->blend_profile != NULL)
12478
0
        cl_icc_profile = dev_profile->blend_profile;
12479
50.0M
    else if (p14dev->blend_cs_state == PDF14_BLEND_CS_OUTPUTINTENT &&
12480
0
        dev_profile->oi_profile != NULL)
12481
0
        cl_icc_profile = dev_profile->oi_profile;
12482
12483
50.0M
    dev_proc(p14dev, get_profile)((gx_device *)p14dev,  &dev_profile);
12484
50.0M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &p14_icc_profile,
12485
50.0M
                          &render_cond);
12486
    /*
12487
     * We only handle the push/pop operations. Save and restore the color_info
12488
     * field for the clist device.  This is needed since the process color
12489
     * model of the clist device needs to match the PDF 1.4 compositing
12490
     * device.
12491
     */
12492
50.0M
    switch (pdf14pct->params.pdf14_op) {
12493
1.95M
    case PDF14_PUSH_DEVICE:
12494
        /* Overprint simulation sets the profile at prototype creation, as does
12495
           when the target profile is NCLR. Match the logic in gs_pdf14_device_push */
12496
1.95M
        if (!((p14dev->overprint_sim && cl_icc_profile->data_cs != gsCMYK) ||
12497
1.95M
            cl_icc_profile->data_cs == gsNCHANNEL)) {
12498
1.95M
            gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update");
12499
1.95M
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12500
1.95M
                -1, "c_pdf14trans_clist_read_update");
12501
1.95M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile;
12502
1.95M
        }
12503
            /*
12504
             * If we are blending using spot colors (i.e. the output device
12505
             * supports spot colors) then we need to transfer
12506
             * color info from the clist PDF 1.4 compositing reader device
12507
             * to the clist writer PDF 1.4 compositing device.
12508
             * This info was transfered from that device to the output
12509
             * device as a set of device parameters.  However the clist
12510
             * reader PDF 1.4 compositing device did not exist when the
12511
             * device parameters were read from the clist.  So that info
12512
             * was buffered into the output device.
12513
             */
12514
1.95M
            pclist_devn_params = dev_proc(cdev, ret_devn_params)(cdev);
12515
1.95M
            if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors > 0) {
12516
6.44k
                int num_comp = p14dev->color_info.num_components;
12517
6.44k
                int has_tags = device_encodes_tags((gx_device *)p14dev);
12518
                /*
12519
                 * The number of components for the PDF14 device is the sum
12520
                 * of the process components and the number of spot colors
12521
                 * for the page.  If the color capabilities of the parent
12522
                 * device (which coming into this are the same as the p14dev)
12523
                 * are smaller than the number of page spot colors then
12524
                 * use that for the number of components. Otherwise use
12525
                 * the page_spot_colors.  The exception is, if we had used
12526
                 * the sICCOutputColors setting, then just use that, which
12527
                 * should be already baked into num_comp. With clist patterns,
12528
                 * cdev->icc_struct may be null.
12529
                 */
12530
12531
6.44k
                if (cdev->icc_struct == NULL || cdev->icc_struct->spotnames == NULL) {
12532
6.44k
                    p14dev->devn_params.page_spot_colors =
12533
6.44k
                        pclist_devn_params->page_spot_colors;
12534
6.44k
                    if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
12535
0
                        if (p14dev->num_planar_planes > 0)
12536
0
                            p14dev->num_planar_planes += num_comp - p14dev->color_info.num_components;
12537
0
                        p14dev->color_info.num_components = num_comp;
12538
0
                        assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12539
6.44k
                    } else {
12540
                        /* if page_spot_colors < 0, this will be wrong, so don't update num_components */
12541
6.44k
                        if (p14dev->devn_params.page_spot_colors >= 0) {
12542
6.44k
                            int n = p14dev->num_std_colorants +
12543
6.44k
                                    p14dev->devn_params.page_spot_colors + has_tags;
12544
6.44k
                            if (p14dev->num_planar_planes > 0)
12545
6.44k
                                p14dev->num_planar_planes += n - p14dev->color_info.num_components;
12546
6.44k
                            p14dev->color_info.num_components = n;
12547
6.44k
                            assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12548
6.44k
                        }
12549
6.44k
                    }
12550
6.44k
                }
12551
                /* limit the num_components to the max. */
12552
6.44k
                if (p14dev->color_info.num_components > p14dev->color_info.max_components + has_tags)
12553
0
                    p14dev->color_info.num_components = p14dev->color_info.max_components + has_tags;
12554
                /* Transfer the data for the spot color names
12555
                   But we have to free what may be there before we do this */
12556
6.44k
                devn_free_params((gx_device*) p14dev);
12557
6.44k
                p14dev->devn_params.separations =
12558
6.44k
                    pclist_devn_params->pdf14_separations;
12559
6.44k
                p14dev->free_devicen = false;  /* to avoid freeing the clist ones */
12560
6.44k
                if (num_comp != p14dev->color_info.num_components) {
12561
                    /* Historically, there has been a comment here:
12562
                       "When the pdf14 device is opened it creates a context and some
12563
                       soft mask related objects.  The push device compositor action
12564
                       will have already created these but they are the wrong size.
12565
                       We must destroy them though before reopening the device."
12566
                       I can't see why this is the case, and testing in the cluster
12567
                       doesn't show ill effects from not doing it. Indeed, Bug 707790
12568
                       shows that this freeing/NULLing the ctx here causes problems
12569
                       when the freed ctx is reinserted at the end of clist pattern
12570
                       files. Accordingly, I'm removing the freeing/NULLing for now
12571
                       at least. */
12572
0
                    int code = dev_proc(tdev, open_device) (tdev);
12573
0
                    if (code < 0)
12574
0
                        return code;
12575
0
                }
12576
6.44k
            }
12577
            /* Check if we need to swap out the ICC profile for the pdf14
12578
               device.  This will occur if our source profile for our device
12579
               happens to be something like CIELAB.  Then we will blend in
12580
               RGB (unless a trans group is specified) */
12581
1.95M
            if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) {
12582
0
                gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12583
0
                                        -1, "c_pdf14trans_clist_read_update");
12584
                /* Initial ref count from gsicc_read_serial_icc() is 1, which is what we want */
12585
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
12586
0
                                        gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash);
12587
                /* Keep a pointer to the clist device */
12588
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->dev = (gx_device *) cdev;
12589
0
            }
12590
1.95M
            break;
12591
12592
1.95M
        case PDF14_POP_DEVICE:
12593
#     if 0 /* Disabled because *p14dev has no forwarding methods during
12594
                    the clist playback. This code is not executed while clist
12595
                    writing. */
12596
            cdev->color_info = p14dev->saved_target_color_info;
12597
#     endif
12598
1.95M
           break;
12599
12600
46.1M
        default:
12601
46.1M
            break;   /* do nothing for remaining ops */
12602
50.0M
    }
12603
12604
50.0M
    return 0;
12605
50.0M
}
12606
12607
/*
12608
 * Get cropping for the compositor command.
12609
 */
12610
static  int
12611
c_pdf14trans_get_cropping(const gs_composite_t *pcte, int *ry, int *rheight,
12612
                          int cropping_min, int cropping_max)
12613
688k
{
12614
688k
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12615
688k
    switch (pdf14pct->params.pdf14_op) {
12616
17.2k
        case PDF14_PUSH_DEVICE: return ALLBANDS; /* Applies to all bands. */
12617
16.4k
        case PDF14_POP_DEVICE:  return ALLBANDS; /* Applies to all bands. */
12618
0
        case PDF14_ABORT_DEVICE: return ALLBANDS; /* Applies to all bands */
12619
6.80k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12620
84.9k
        case PDF14_BEGIN_TRANS_GROUP:
12621
84.9k
            { gs_int_rect rect;
12622
12623
                /* Text group always uses parents size*/
12624
84.9k
                if (pdf14pct->params.text_group == PDF14_TEXTGROUP_BT_PUSHED) {
12625
4.12k
                    *ry = cropping_min;
12626
4.12k
                    *rheight = cropping_max - *ry;
12627
80.8k
                } else {
12628
80.8k
                    pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12629
80.8k
                        &pdf14pct->params.bbox, &rect);
12630
                    /* We have to crop this by the parent object.   */
12631
80.8k
                    *ry = max(rect.p.y, cropping_min);
12632
80.8k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12633
80.8k
                }
12634
84.9k
                return PUSHCROP; /* Push cropping. */
12635
6.80k
            }
12636
86.6k
        case PDF14_BEGIN_TRANS_MASK:
12637
86.6k
            { gs_int_rect rect;
12638
12639
86.6k
                pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12640
86.6k
                                                    &pdf14pct->params.bbox, &rect);
12641
                /* We have to crop this by the parent object and worry about the BC outside
12642
                   the range, except for image SMask which don't affect areas outside the image.
12643
                   The presence of a transfer function opens the possibility of issues with this */
12644
86.6k
                if (pdf14pct->params.mask_is_image || (pdf14pct->params.GrayBackground == 1.0 &&
12645
35.8k
                      pdf14pct->params.function_is_identity)) {
12646
                    /* In this case there will not be a background effect to
12647
                       worry about.  The mask will not have any effect outside
12648
                       the bounding box.  This is NOT the default or common case. */
12649
35.8k
                    *ry = max(rect.p.y, cropping_min);
12650
35.8k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12651
35.8k
                    return PUSHCROP; /* Push cropping. */
12652
50.8k
                }  else {
12653
                    /* We need to make the soft mask range as large as the parent
12654
                       due to the fact that the background color can have an impact
12655
                       OUTSIDE the bounding box of the soft mask */
12656
50.8k
                    *ry = cropping_min;
12657
50.8k
                    *rheight = cropping_max - cropping_min;
12658
50.8k
                    if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
12659
47.4k
                        return SAMEAS_PUSHCROP_BUTNOPUSH;
12660
3.36k
                    else
12661
3.36k
                        return PUSHCROP; /* Push cropping. */
12662
50.8k
                }
12663
86.6k
            }
12664
80.8k
        case PDF14_END_TRANS_GROUP: return POPCROP; /* Pop cropping. */
12665
4.10k
        case PDF14_END_TRANS_TEXT_GROUP: return POPCROP; /* Pop cropping. */
12666
39.2k
        case PDF14_END_TRANS_MASK: return POPCROP;   /* Pop the cropping */
12667
0
        case PDF14_PUSH_TRANS_STATE: return CURRBANDS;
12668
37.9k
        case PDF14_POP_TRANS_STATE: return CURRBANDS;
12669
320k
        case PDF14_SET_BLEND_PARAMS: return ALLBANDS;
12670
0
        case PDF14_PUSH_SMASK_COLOR: return POPCROP; /* Pop cropping. */
12671
0
        case PDF14_POP_SMASK_COLOR: return POPCROP;   /* Pop the cropping */
12672
0
        case PDF14_BEGIN_TRANS_TEXT_GROUP: return ALLBANDS; /* should never occur */
12673
688k
    }
12674
0
    return ALLBANDS;
12675
688k
}
12676
12677
/*
12678
 * This routine will check to see if the color component name matches those
12679
 * that are available amoung the current device's color components.  If the
12680
 * color name is known to the output device then we add it to the list of
12681
 * colorants for the PDF 1.4 transparency compositor.
12682
 *
12683
 * Notes:  There are currently three different versions of The PDF 1.4
12684
 * transparency compositor device.  The choice of which one is being used
12685
 * depends upon the process color model of the output device.  This procedure
12686
 * is only used if the output (target) device uses a CMYK, or RGB or Gray
12687
 * plus spot color process color model.
12688
 *
12689
 * Parameters:
12690
 *   dev - pointer to device data structure.
12691
 *   pname - pointer to name (zero termination not required)
12692
 *   nlength - length of the name
12693
 *   number of process colorants (either 1, 3, or 4)
12694
 *
12695
 * This routine returns a positive value (0 to n) which is the device colorant
12696
 * number if the name is found.  It returns GX_DEVICE_COLOR_MAX_COMPONENTS if
12697
 * the colorant is not being used due to a SeparationOrder device parameter.
12698
 * It returns a negative value if not found.
12699
 */
12700
static int
12701
pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname,
12702
    int name_size, int component_type, int num_process_colors, int cmyk)
12703
31.2k
{
12704
31.2k
    pdf14_device *pdev = (pdf14_device *)dev;
12705
31.2k
    gx_device *tdev = pdev->target;
12706
31.2k
    gs_devn_params *pdevn_params = &pdev->devn_params;
12707
31.2k
    gs_separations *pseparations;
12708
31.2k
    int comp_index;
12709
31.2k
    dev_proc_get_color_comp_index(*target_get_color_comp_index);
12710
31.2k
    int offset;
12711
12712
31.2k
    while (tdev->child) {
12713
0
        tdev = tdev->child;
12714
0
    }
12715
    /* If something has gone wrong and this is no longer the pdf14 compositor, */
12716
    /* get the devn_params from the target to avoid accessing using the wrong  */
12717
    /* pointer. Bug 696372.                                                    */
12718
31.2k
    if (tdev == (gx_device *)pdev)
12719
0
        pdevn_params = dev_proc(pdev, ret_devn_params)(dev);
12720
31.2k
    offset = pdevn_params->num_std_colorant_names - num_process_colors;
12721
31.2k
    pseparations = &pdevn_params->separations;
12722
    /* If num_process_colors is 3 or 1 (RGB or Gray) then we are in a situation
12723
     * where we are in a blend color space that is RGB or Gray based and we
12724
     * have a spot colorant.  If the spot colorant name is Cyan, Magenta
12725
     * Yellow or Black, then we should use the alternate tint transform */
12726
31.2k
    if (num_process_colors < 4) {
12727
1.10k
        int k;
12728
5.52k
        for (k = 0; k < pdevn_params->num_std_colorant_names; k++) {
12729
4.41k
            if (strncmp(pname, pdevn_params->std_colorant_names[k], name_size) == 0)
12730
0
                return -1;
12731
4.41k
        }
12732
1.10k
    }
12733
12734
31.2k
    target_get_color_comp_index = dev_proc(tdev, get_color_comp_index);
12735
12736
    /* The pdf14_clist_composite may have set the color procs.
12737
       We need the real target procs, but not if we are doing simulated
12738
       overprint */
12739
31.2k
    if ((target_get_color_comp_index == pdf14_cmykspot_get_color_comp_index ||
12740
0
         target_get_color_comp_index == pdf14_rgbspot_get_color_comp_index) &&
12741
31.2k
        !pdev->overprint_sim)
12742
31.2k
        target_get_color_comp_index =
12743
31.2k
            ((pdf14_clist_device *)pdev)->saved_target_get_color_comp_index;
12744
    /*
12745
    * If this is not a separation name then simply forward it to the target
12746
    * device or return -1 if we are doing overprint simulation.
12747
    * The halftone setup expects this.
12748
    */
12749
31.2k
    if (!pdev->overprint_sim && (component_type == NO_COMP_NAME_TYPE_HT ||
12750
31.2k
        component_type == NO_COMP_NAME_TYPE_OP)) {
12751
23.4k
            if (target_get_color_comp_index != NULL)
12752
23.4k
                return  (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12753
0
            else
12754
0
                return -1;
12755
23.4k
    }
12756
7.83k
    if (pdev->overprint_sim && component_type == NO_COMP_NAME_TYPE_HT) {
12757
0
        return -1;
12758
0
    }
12759
12760
    /*
12761
    * Check if the component is in either the process color model list
12762
    * or in the SeparationNames list.
12763
    */
12764
7.83k
    comp_index = check_pcm_and_separation_names(dev, pdevn_params, pname,
12765
7.83k
        name_size, component_type);
12766
12767
    /* Additive devices should NOT have C/M/Y/K Colorants added to them.
12768
     * This is a decision we take here to avoid problems with PDFI not
12769
     * counting such colorants as spots. */
12770
7.83k
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
12771
69
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12772
0
            return -1;
12773
69
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12774
0
            return -1;
12775
69
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12776
0
            return -1;
12777
69
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12778
0
            return -1;
12779
69
    }
12780
    /* A psdrgb device, with simulate overprint will have become a cmyk
12781
     * device. As such, we don't want to add Black/Cyan/Magenta/Yellow to that
12782
     * either, but we need to return real numbers for them as the underlying
12783
     * routine won't know about these. */
12784
7.83k
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && cmyk) {
12785
10
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12786
0
            return 3;
12787
10
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12788
0
            return 0;
12789
10
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12790
0
            return 1;
12791
10
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12792
0
            return 2;
12793
10
    }
12794
12795
    /*
12796
    * Return the colorant number if we know this name.  Note adjustment for
12797
    * compensating of blend color space.
12798
    */
12799
7.83k
    if (comp_index >= 0)
12800
7.75k
        return comp_index - offset;
12801
12802
    /* Only worry about the target if we are not doing an overprint simulation */
12803
79
    if (!pdev->overprint_sim) {
12804
        /*
12805
        * If we do not know this color, check if the output (target) device does.
12806
        * Note that if the target device has ENABLE_AUTO_SPOT_COLORS this will add
12807
        * the colorant so we will only get < 0 returned when we hit the max. for
12808
        * the target device.
12809
        */
12810
79
        if (target_get_color_comp_index != NULL)
12811
79
            comp_index = (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12812
0
        else
12813
0
            return -1;
12814
        /*
12815
        * Ignore color if unknown to the output device or if color is not being
12816
        * imaged due to the SeparationOrder device parameter.
12817
        */
12818
79
        if (comp_index < 0 || comp_index == GX_DEVICE_COLOR_MAX_COMPONENTS)
12819
0
            return comp_index - offset;
12820
79
    }
12821
12822
    /*
12823
    * This is a new colorant.  Add it to our list of colorants.
12824
    * The limit accounts for the number of process colors (at least 4).
12825
    */
12826
79
    if ((pseparations->num_separations + 1) <
12827
79
            (GX_DEVICE_COLOR_MAX_COMPONENTS - max(num_process_colors, 4))) {
12828
79
        int sep_num = pseparations->num_separations++;
12829
79
        int color_component_number;
12830
79
        byte * sep_name;
12831
12832
79
        sep_name = gs_alloc_bytes(dev->memory->stable_memory,
12833
79
            name_size, "pdf14_spot_get_color_comp_index");
12834
79
        if (sep_name == NULL) {
12835
0
            pseparations->num_separations--;  /* we didn't add it */
12836
0
            return -1;
12837
0
        }
12838
79
        memcpy(sep_name, pname, name_size);
12839
79
        pseparations->names[sep_num].size = name_size;
12840
79
        pseparations->names[sep_num].data = sep_name;
12841
79
        color_component_number = sep_num + num_process_colors;
12842
79
        if (color_component_number >= dev->color_info.max_components)
12843
0
            color_component_number = GX_DEVICE_COLOR_MAX_COMPONENTS;
12844
79
        else
12845
79
            pdevn_params->separation_order_map[color_component_number] =
12846
79
            color_component_number;
12847
12848
        /* Indicate that we need to find equivalent CMYK color. */
12849
79
        pdev->op_pequiv_cmyk_colors.color[sep_num].color_info_valid = false;
12850
79
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
12851
12852
79
        return color_component_number;
12853
79
    }
12854
12855
0
    return GX_DEVICE_COLOR_MAX_COMPONENTS;
12856
79
}
12857
12858
12859
/* CMYK process + spots */
12860
static int
12861
pdf14_cmykspot_get_color_comp_index(gx_device * dev, const char * pname,
12862
    int name_size, int component_type)
12863
30.1k
{
12864
30.1k
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 4, 1);
12865
30.1k
}
12866
12867
/* RGB process + spots */
12868
static int
12869
pdf14_rgbspot_get_color_comp_index(gx_device * dev, const char * pname,
12870
    int name_size, int component_type)
12871
1.10k
{
12872
1.10k
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 3, 0);
12873
1.10k
}
12874
12875
/* Gray process + spots */
12876
static int
12877
pdf14_grayspot_get_color_comp_index(gx_device * dev, const char * pname,
12878
    int name_size, int component_type)
12879
0
{
12880
0
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 1, 0);
12881
0
}
12882
12883
/* These functions keep track of when we are dealing with soft masks.
12884
   In such a case, we set the default color profiles to ones that ensure
12885
   proper soft mask rendering. */
12886
static int
12887
pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev)
12888
56.7k
{
12889
56.7k
    pdf14_device * pdev = (pdf14_device *) dev;
12890
56.7k
    pdf14_smaskcolor_t *result;
12891
56.7k
    gsicc_smask_t *smask_profiles = pgs->icc_manager->smask_profiles;
12892
56.7k
    int k;
12893
12894
    /* See if we have profiles already in place.   Note we also have to
12895
       worry about a corner case where this device does not have a
12896
       smaskcolor stucture to store the profiles AND the profiles were
12897
       already swapped out in the icc_manager.  This can occur when we
12898
       pushed a transparency mask and then inside the mask we have a pattern
12899
       which also has a transparency mask.   The state of the icc_manager
12900
       is that it already has done the swap and there is no need to fool
12901
       with any of this while dealing with the soft mask within the pattern */
12902
56.7k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12903
56.6k
        pgs->icc_manager->smask_profiles->swapped) {
12904
0
            return 0;
12905
0
    }
12906
56.7k
    if (pdev->smaskcolor != NULL) {
12907
134
        pdev->smaskcolor->ref_count++;
12908
134
        if_debug1m(gs_debug_flag_icc, dev->memory,
12909
134
                   "[icc] Increment smask color now %d\n",
12910
134
                   pdev->smaskcolor->ref_count);
12911
56.6k
    } else {
12912
        /* Allocate and swap out the current profiles.  The softmask
12913
           profiles should already be in place */
12914
56.6k
        result = gs_alloc_struct(pdev->memory->stable_memory, pdf14_smaskcolor_t,
12915
56.6k
                                &st_pdf14_smaskcolor,
12916
56.6k
                                "pdf14_increment_smask_color");
12917
56.6k
        if (result == NULL)
12918
0
            return gs_error_VMerror;
12919
12920
56.6k
        result->profiles = gsicc_new_iccsmask(pdev->memory->stable_memory);
12921
56.6k
        if (result->profiles == NULL)
12922
0
            return gs_error_VMerror;
12923
12924
56.6k
        pdev->smaskcolor = result;
12925
12926
56.6k
        result->profiles->smask_gray = pgs->icc_manager->default_gray;
12927
56.6k
        result->profiles->smask_rgb = pgs->icc_manager->default_rgb;
12928
56.6k
        result->profiles->smask_cmyk = pgs->icc_manager->default_cmyk;
12929
56.6k
        pgs->icc_manager->default_gray = smask_profiles->smask_gray;
12930
56.6k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "pdf14_increment_smask_color");
12931
56.6k
        pgs->icc_manager->default_rgb = smask_profiles->smask_rgb;
12932
56.6k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "pdf14_increment_smask_color");
12933
56.6k
        pgs->icc_manager->default_cmyk = smask_profiles->smask_cmyk;
12934
56.6k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_increment_smask_color");
12935
56.6k
        pgs->icc_manager->smask_profiles->swapped = true;
12936
56.6k
        if_debug0m(gs_debug_flag_icc, pgs->memory,
12937
56.6k
                   "[icc] Initial creation of smask color. Ref count 1\n");
12938
56.6k
        pdev->smaskcolor->ref_count = 1;
12939
        /* We also need to update the profile that is currently in the
12940
           color spaces of the graphic state.  Otherwise this can be
12941
           referenced, which will result in a mismatch.  What we want to do
12942
           is see if it was the original default and only swap in that case. */
12943
169k
        for (k = 0; k < 2; k++) {
12944
113k
            gs_color_space *pcs     = pgs->color[k].color_space;
12945
113k
            cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12946
113k
            if (profile != NULL) {
12947
109k
                switch(profile->data_cs) {
12948
60.2k
                    case gsGRAY:
12949
60.2k
                        if (profile->hashcode ==
12950
60.2k
                            result->profiles->smask_gray->hashcode) {
12951
56.5k
                                profile = pgs->icc_manager->default_gray;
12952
56.5k
                        }
12953
60.2k
                        break;
12954
48.8k
                    case gsRGB:
12955
48.8k
                        if (profile->hashcode ==
12956
48.8k
                            result->profiles->smask_rgb->hashcode) {
12957
21.3k
                                profile = pgs->icc_manager->default_rgb;
12958
21.3k
                        }
12959
48.8k
                        break;
12960
919
                    case gsCMYK:
12961
919
                        if (profile->hashcode ==
12962
919
                            result->profiles->smask_cmyk->hashcode) {
12963
919
                                profile = pgs->icc_manager->default_cmyk;
12964
919
                        }
12965
919
                        break;
12966
0
                    default:
12967
12968
0
                        break;
12969
109k
                }
12970
109k
                if (pcs->cmm_icc_profile_data != profile) {
12971
78.8k
                    gsicc_adjust_profile_rc(profile, 1, "pdf14_increment_smask_color");
12972
78.8k
                    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_increment_smask_color");
12973
78.8k
                    pcs->cmm_icc_profile_data = profile;
12974
78.8k
                }
12975
109k
            }
12976
113k
        }
12977
56.6k
    }
12978
56.7k
    return 0;
12979
56.7k
}
12980
12981
static int
12982
pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev)
12983
73.1k
{
12984
73.1k
    pdf14_device * pdev = (pdf14_device *) dev;
12985
73.1k
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
12986
73.1k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
12987
73.1k
    int k;
12988
12989
    /* See comment in pdf14_increment_smask_color to understand this one */
12990
73.1k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12991
8.40k
        pgs->icc_manager->smask_profiles->swapped) {
12992
0
            return 0;
12993
0
    }
12994
73.1k
    if (smaskcolor != NULL) {
12995
56.7k
        smaskcolor->ref_count--;
12996
56.7k
        if_debug1m(gs_debug_flag_icc, pgs->memory,
12997
56.7k
                   "[icc] Decrement smask color.  Now %d\n",
12998
56.7k
                   smaskcolor->ref_count);
12999
56.7k
        if (smaskcolor->ref_count == 0) {
13000
56.6k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reset smask color.\n");
13001
            /* Lets return the profiles and clean up */
13002
            /* First see if we need to "reset" the profiles that are in
13003
               the graphic state */
13004
56.6k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reseting graphic state color spaces\n");
13005
169k
            for (k = 0; k < 2; k++) {
13006
113k
                gs_color_space *pcs = pgs->color[k].color_space;
13007
113k
                cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
13008
113k
                if (profile != NULL) {
13009
109k
                    switch(profile->data_cs) {
13010
60.2k
                        case gsGRAY:
13011
60.2k
                            if (profile->hashcode ==
13012
60.2k
                                pgs->icc_manager->default_gray->hashcode) {
13013
56.5k
                                    profile =
13014
56.5k
                                        smaskcolor->profiles->smask_gray;
13015
56.5k
                            }
13016
60.2k
                            break;
13017
48.8k
                        case gsRGB:
13018
48.8k
                            if (profile->hashcode ==
13019
48.8k
                                pgs->icc_manager->default_rgb->hashcode) {
13020
21.3k
                                    profile =
13021
21.3k
                                        smaskcolor->profiles->smask_rgb;
13022
21.3k
                            }
13023
48.8k
                            break;
13024
919
                        case gsCMYK:
13025
919
                            if (profile->hashcode ==
13026
919
                                pgs->icc_manager->default_cmyk->hashcode) {
13027
919
                                    profile =
13028
919
                                        smaskcolor->profiles->smask_cmyk;
13029
919
                            }
13030
919
                            break;
13031
0
                        default:
13032
13033
0
                            break;
13034
109k
                    }
13035
109k
                    if (pcs->cmm_icc_profile_data != profile) {
13036
78.8k
                        gsicc_adjust_profile_rc(profile, 1, "pdf14_decrement_smask_color");
13037
78.8k
                        gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_decrement_smask_color");
13038
78.8k
                        pcs->cmm_icc_profile_data = profile;
13039
78.8k
                    }
13040
109k
                }
13041
113k
            }
13042
13043
56.6k
            gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "pdf14_decrement_smask_color");
13044
56.6k
            icc_manager->default_gray = smaskcolor->profiles->smask_gray;
13045
56.6k
            gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "pdf14_decrement_smask_color");
13046
56.6k
            icc_manager->default_rgb = smaskcolor->profiles->smask_rgb;
13047
56.6k
            gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "pdf14_decrement_smask_color");
13048
56.6k
            icc_manager->default_cmyk = smaskcolor->profiles->smask_cmyk;
13049
56.6k
            icc_manager->smask_profiles->swapped = false;
13050
            /* We didn't increment the reference count when we assigned these
13051
             * so NULL them to avoid decrementing when smaskcolor is freed
13052
             */
13053
56.6k
            smaskcolor->profiles->smask_gray =
13054
56.6k
              smaskcolor->profiles->smask_rgb =
13055
56.6k
              smaskcolor->profiles->smask_cmyk = NULL;
13056
13057
56.6k
            pdf14_free_smask_color(pdev);
13058
56.6k
        }
13059
56.7k
    }
13060
73.1k
    return 0;
13061
73.1k
}
13062
13063
static void
13064
pdf14_free_smask_color(pdf14_device * pdev)
13065
56.6k
{
13066
56.6k
    if (pdev->smaskcolor != NULL) {
13067
56.6k
        if ( pdev->smaskcolor->profiles != NULL) {
13068
            /* Do not decrement the profiles - the references were moved
13069
               here and moved back again, so the ref counts don't change
13070
             */
13071
56.6k
            gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor->profiles,
13072
56.6k
                        "pdf14_free_smask_color");
13073
56.6k
        }
13074
56.6k
        gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor, "pdf14_free_smask_color");
13075
56.6k
        pdev->smaskcolor = NULL;
13076
56.6k
    }
13077
56.6k
}
13078
13079
static void
13080
pdf14_device_finalize(const gs_memory_t *cmem, void *vptr)
13081
1.97M
{
13082
1.97M
    gx_device * const dev = (gx_device *)vptr;
13083
1.97M
    pdf14_device * pdev = (pdf14_device *)dev;
13084
1.97M
    int k;
13085
13086
1.97M
    pdf14_cleanup_group_color_profiles (pdev);
13087
13088
1.97M
    if (pdev->ctx) {
13089
17
        pdf14_ctx_free(pdev->ctx);
13090
17
        pdev->ctx = NULL;
13091
17
    }
13092
13093
1.97M
    while (pdev->color_model_stack) {
13094
23
        pdf14_pop_group_color(dev, NULL);
13095
23
    }
13096
13097
1.97M
    for (k = 0; k < pdev->devn_params.separations.num_separations; k++) {
13098
79
        if (pdev->devn_params.separations.names[k].data) {
13099
79
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.separations.names[k].data, "pdf14_device_finalize");
13100
79
            pdev->devn_params.separations.names[k].data = NULL;
13101
79
        }
13102
79
    }
13103
13104
1.97M
    for (k = 0; k < pdev->devn_params.pdf14_separations.num_separations; k++) {
13105
0
        if (pdev->devn_params.pdf14_separations.names[k].data) {
13106
0
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.pdf14_separations.names[k].data, "pdf14_device_finalize");
13107
0
            pdev->devn_params.pdf14_separations.names[k].data = NULL;
13108
0
        }
13109
0
    }
13110
13111
1.97M
    gx_device_finalize(cmem, vptr);
13112
1.97M
}
13113
13114
#if DUMP_MASK_STACK
13115
13116
static void
13117
dump_mask_stack(pdf14_mask_t *mask_stack)
13118
{
13119
    pdf14_mask_t *curr_mask = mask_stack;
13120
    int level = 0;
13121
13122
    while (curr_mask != NULL) {
13123
        if_debug1m('v', curr_mask->memory, "[v]mask_level, %d\n", level);
13124
        if_debug1m('v', curr_mask->memory, "[v]mask_buf, %p\n", curr_mask->rc_mask->mask_buf);
13125
        if_debug1m('v', curr_mask->memory, "[v]rc_count, %ld\n", curr_mask->rc_mask->rc.ref_count);
13126
        level++;
13127
        curr_mask = curr_mask->previous;
13128
    }
13129
}
13130
13131
/* A function to display the current state of the mask stack */
13132
static void
13133
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13134
{
13135
    if_debug1m('v', ctx->memory, "[v]ctx_maskstack, %p\n", ctx->mask_stack);
13136
    if (ctx->mask_stack != NULL) {
13137
        dump_mask_stack(ctx->mask_stack);
13138
    }
13139
    if_debug1m('v', ctx->memory, "[v]ctx_stack, %p\n", ctx->stack);
13140
    if (ctx->stack != NULL) {
13141
        if_debug1m('v', ctx->memory, "[v]ctx_stack_maskstack, %p\n", ctx->stack->mask_stack);
13142
        if (ctx->stack->mask_stack != NULL) {
13143
            dump_mask_stack(ctx->stack->mask_stack);
13144
        }
13145
    }
13146
}
13147
13148
#else
13149
13150
#ifdef DEBUG
13151
static void
13152
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13153
{
13154
    return;
13155
}
13156
#endif
13157
13158
#endif /* DUMP_MASK_STACK */