Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/gstrans.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2022 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14
*/
15
16
17
/* Implementation of transparency, other than rendering */
18
#include "math_.h"
19
#include "memory_.h"
20
#include "gx.h"
21
#include "gserrors.h"
22
#include "gstrans.h"
23
#include "gsutil.h"
24
#include "gzstate.h"
25
#include "gxdevcli.h"
26
#include "gdevdevn.h"
27
#include "gxblend.h"
28
#include "gdevp14.h"
29
#include "gscspace.h"
30
#include "gxarith.h"
31
#include "gxclist.h"
32
#include "gsicc_manage.h"
33
#include "gsicc_cache.h"
34
#include "gxdevsop.h"
35
36
/* ------ Transparency-related graphics state elements ------ */
37
38
int
39
gs_setblendmode(gs_gstate *pgs, gs_blend_mode_t mode)
40
718k
{
41
#ifdef DEBUG
42
    if (gs_debug_c('v')) {
43
        static const char *const bm_names[] = { GS_BLEND_MODE_NAMES };
44
45
        dmlprintf1(pgs->memory, "[v]("PRI_INTPTR")blend_mode = ", (intptr_t)pgs);
46
        if (mode >= 0 && mode < countof(bm_names))
47
            dmprintf1(pgs->memory, "%s\n", bm_names[mode]);
48
        else
49
            dmprintf1(pgs->memory, "%d??\n", (int)mode);
50
    }
51
#endif
52
    /* Map Compatible to Normal so other code treats Compatible as Normal */
53
    /* Often BLEND_MODE_Normal is checked for optimized handling, and     */
54
    /* Compatible is now specified to be the same.                        */
55
718k
    if (mode == BLEND_MODE_Compatible)
56
652k
        mode = BLEND_MODE_Normal;
57
718k
    if ((int)mode < 0 || (int)mode > MAX_BLEND_MODE)
58
0
        return_error(gs_error_rangecheck);
59
718k
    pgs->blend_mode = mode;
60
718k
    return 0;
61
718k
}
62
63
gs_blend_mode_t
64
gs_currentblendmode(const gs_gstate *pgs)
65
6.54M
{
66
6.54M
    return pgs->blend_mode;
67
6.54M
}
68
69
int
70
gs_settextknockout(gs_gstate *pgs, bool knockout)
71
641k
{
72
641k
    if_debug2m('v', pgs->memory, "[v]("PRI_INTPTR")text_knockout = %s\n",
73
641k
              (intptr_t)pgs, (knockout ? "true" : "false"));
74
641k
    pgs->text_knockout = knockout;
75
641k
    return 0;
76
641k
}
77
78
bool
79
gs_currenttextknockout(const gs_gstate *pgs)
80
1.51M
{
81
1.51M
    return pgs->text_knockout;
82
1.51M
}
83
84
/* This is used to keep pdf14 compositor actions from the interpreter from
85
   corrupting pattern renderings.  For example, if the file has a softmask,
86
   the intrepter will send push and pop transparency state commands when
87
   q and Q operations are encountered.  If we are writing out to a pattern
88
   clist that has no trasparency we do not want these state changes to
89
   be entered as compositor actions in the pattern clist */
90
91
static int
92
check_for_nontrans_pattern(gs_gstate *pgs, unsigned char *comp_name)
93
1.20M
{
94
1.20M
    gx_device * dev = pgs->device;
95
1.20M
    bool is_patt_clist = gx_device_is_pattern_clist(dev);
96
1.20M
    bool is_patt_acum = gx_device_is_pattern_accum(dev);
97
98
    /* Check if we are collecting data for a pattern that has no
99
       transparency.  In that case, we need to ignore the state changes */
100
1.20M
    if (is_patt_clist || is_patt_acum) {
101
1.34k
        if (is_patt_clist) {
102
554
            gx_device_clist_writer *clwdev = (gx_device_clist_writer*) dev;
103
554
            const gs_pattern1_instance_t *pinst = clwdev->pinst;
104
105
554
            if (!(pinst->templat.uses_transparency)) {
106
554
                if_debug1m('v', pgs->memory,
107
554
                           "[v]%s NOT sending in pattern\n",comp_name);
108
554
                return(1);
109
554
            }
110
554
        }
111
792
        if (is_patt_acum) {
112
792
            gx_device_pattern_accum *padev = (gx_device_pattern_accum*) dev;
113
792
            const gs_pattern1_instance_t *pinst = padev->instance;
114
115
792
            if (!(pinst->templat.uses_transparency)) {
116
792
                if_debug1m('v', pgs->memory,
117
792
                           "[v]%s NOT sending in pattern\n",comp_name);
118
792
                return(1);
119
792
            }
120
792
        }
121
792
    }
122
1.20M
    return(0);
123
1.20M
}
124
125
/*
126
 * Push a PDF 1.4 transparency compositor onto the current device. Note that
127
 * if the current device already is a PDF 1.4 transparency compositor, the
128
 * composite will update its parameters but not create a new
129
 * compositor device.
130
 */
131
static int
132
gs_gstate_update_pdf14trans2(gs_gstate * pgs, gs_pdf14trans_params_t * pparams, bool retain_on_create)
133
524k
{
134
524k
    gx_device * dev = pgs->device;
135
524k
    gx_device *pdf14dev = NULL;
136
524k
    int code;
137
524k
    int curr_num = dev->color_info.num_components;
138
139
    /*
140
     * Send the PDF 1.4 create compositor action specified by the parameters.
141
     */
142
524k
    code = send_pdf14trans(pgs, dev, &pdf14dev, pparams, pgs->memory);
143
524k
    if (code < 0)
144
15
        return code;
145
    /*
146
     * If we created a new PDF 1.4 compositor device then we need to install it
147
     * into the graphics state.
148
     */
149
524k
    if (code == 1) {
150
8.99k
        gx_set_device_only(pgs, pdf14dev);
151
8.99k
        gx_device_retain(pdf14dev, retain_on_create);
152
8.99k
        code = 0;
153
8.99k
    }
154
155
    /* If we had a color space change and we are in overprint, then we need to
156
       update the drawn_comps */
157
524k
    if (pgs->overprint && curr_num != pdf14dev->color_info.num_components) {
158
74
        code = gs_do_set_overprint(pgs);
159
74
    }
160
161
524k
    return code;
162
524k
}
163
164
static int
165
gs_gstate_update_pdf14trans(gs_gstate * pgs, gs_pdf14trans_params_t * pparams)
166
515k
{
167
515k
    return gs_gstate_update_pdf14trans2(pgs, pparams, true);
168
515k
}
169
170
void
171
gs_trans_group_params_init(gs_transparency_group_params_t *ptgp, float opacity)
172
18.5k
{
173
18.5k
    ptgp->ColorSpace = NULL;    /* bogus, but can't do better */
174
18.5k
    ptgp->Isolated = false;
175
18.5k
    ptgp->Knockout = false;
176
18.5k
    ptgp->page_group = false;
177
18.5k
    ptgp->text_group = PDF14_TEXTGROUP_NO_BT;
178
18.5k
    ptgp->image_with_SMask = false;
179
18.5k
    ptgp->mask_id = 0;
180
18.5k
    ptgp->iccprofile = NULL;
181
18.5k
    ptgp->group_opacity = opacity;
182
18.5k
    ptgp->group_shape = 1.0;
183
18.5k
    ptgp->shade_group = false;
184
18.5k
}
185
186
int
187
gs_update_trans_marking_params(gs_gstate * pgs)
188
0
{
189
0
    gs_pdf14trans_params_t params = { 0 };
190
191
0
    if_debug0m('v', pgs->memory, "[v]gs_update_trans_marking_params\n");
192
0
    params.pdf14_op = PDF14_SET_BLEND_PARAMS;
193
0
    return gs_gstate_update_pdf14trans(pgs, &params);
194
0
}
195
196
int
197
gs_begin_transparency_group(gs_gstate *pgs,
198
                            const gs_transparency_group_params_t *ptgp,
199
                            const gs_rect *pbbox, pdf14_compositor_operations group_type)
200
22.0k
{
201
22.0k
    gs_pdf14trans_params_t params = { 0 };
202
22.0k
    const gs_color_space *blend_color_space;
203
22.0k
    cmm_profile_t *profile;
204
205
22.0k
    if (check_for_nontrans_pattern(pgs,
206
22.0k
                  (unsigned char *)"gs_begin_transparency_group")) {
207
1
        return(0);
208
1
    }
209
    /*
210
     * Put parameters into a compositor parameter and then call the
211
     * composite.  This will pass the data to the PDF 1.4
212
     * transparency device.
213
     */
214
22.0k
    params.pdf14_op = group_type;
215
22.0k
    params.Isolated = ptgp->Isolated;
216
22.0k
    params.Knockout = ptgp->Knockout;
217
22.0k
    if (group_type == PDF14_BEGIN_TRANS_PAGE_GROUP)
218
1.00k
        params.page_group = true;
219
22.0k
    params.image_with_SMask = ptgp->image_with_SMask;
220
22.0k
    params.opacity = ptgp->group_opacity;
221
22.0k
    params.shape = ptgp->group_shape;
222
22.0k
    params.blend_mode = pgs->blend_mode;
223
22.0k
    params.text_group = ptgp->text_group;
224
22.0k
    params.shade_group = ptgp->shade_group;
225
22.0k
    params.ColorSpace = ptgp->ColorSpace;
226
    /* This function is called during the c-list writer side.
227
       Store some information so that we know what the color space is
228
       so that we can adjust according later during the clist reader.
229
       We currently will use the concrete space for any space other than a
230
       device space.  However, if the device is a sep device it will blend
231
       in DeviceN color space as required.  */
232
22.0k
    blend_color_space = gs_currentcolorspace_inline(pgs);
233
22.0k
    if (gs_color_space_get_index(blend_color_space) > gs_color_space_index_DeviceCMYK) {
234
        /* ICC and PS CIE based case.  Note that unidirectional PS CIE color
235
           spaces should not be allowed but end up occuring when processing
236
           PDF files with -dUseCIEColor.  We will end up using the appropriate
237
           ICC default color space in these cases. */
238
22.0k
        blend_color_space = gs_currentcolorspace_inline(pgs);
239
22.0k
    } else {
240
0
        blend_color_space = cs_concrete_space(blend_color_space, pgs);
241
0
        if (!blend_color_space)
242
0
            return_error(gs_error_undefined);
243
0
    }
244
    /* Note that if the /CS parameter was NOT present in the push
245
       of the transparency group, then we must actually inherent
246
       the previous group color space, or the color space of the
247
       target device (process color model).  Here we just want
248
       to set it as a unknown type for clist writing, as we will take care
249
       of using the parent group color space later during clist reading.
250
       Also, if the group was not isolated we MUST use the parent group
251
       color space regardless of what the group color space is specified to be.
252
       Note that the page group should always be isolated */
253
22.0k
    if (group_type == PDF14_BEGIN_TRANS_PAGE_GROUP)
254
1.00k
        params.Isolated = true;
255
256
22.0k
    if (ptgp->ColorSpace == NULL || params.Isolated != true) {
257
20.8k
        params.group_color_type = UNKNOWN;
258
20.8k
        params.group_color_numcomps = 0;
259
20.8k
    } else {
260
        /* The /CS parameter was present.  Use what was set.  Currently
261
           all our Device spaces are actually ICC based.  The other options
262
           are if -dUseCIEColor is set, in which case it could be
263
           coming in as a PS CIE color space, which should not be allowed
264
           but should default to one of the default ICC color spaces.  Note
265
           that CalRGB and CalGray, which are valid bidirectional color spaces
266
           are converted to ICC profiles during installation. PS CIE building
267
           to ICC is delayed. */
268
1.22k
        if ( gs_color_space_is_ICC(blend_color_space) ) {
269
            /* Blending space is ICC based.  If we are doing c-list rendering
270
               we will need to write this color space into the clist.
271
               */
272
1.22k
            params.group_color_type = ICC;
273
1.22k
            params.group_color_numcomps =
274
1.22k
                blend_color_space->cmm_icc_profile_data->num_comps;
275
            /* Get the ICC profile */
276
1.22k
            params.iccprofile = blend_color_space->cmm_icc_profile_data;
277
1.22k
            params.icc_hash = gsicc_get_hash(blend_color_space->cmm_icc_profile_data);
278
1.22k
        } else {
279
            /* Color space was NOT ICC based.  PS CIE space and DeviceN are the only
280
               other option.  Use the ICC default based upon the component count. */
281
0
            switch (cs_num_components(blend_color_space)) {
282
0
                case 1:
283
0
                    profile =  pgs->icc_manager->default_gray;
284
0
                    break;
285
0
                case 3:
286
0
                    profile =  pgs->icc_manager->default_rgb;
287
0
                    break;
288
0
                case 4:
289
0
                    profile =  pgs->icc_manager->default_cmyk;
290
0
                break;
291
0
                default:
292
                    /* We can end up here if we are in a deviceN color space and
293
                       we have a sep output device */
294
0
                    profile = NULL;
295
0
                    params.group_color_type = DEVICEN;
296
0
                    params.group_color_numcomps = cs_num_components(blend_color_space);
297
0
                break;
298
0
            }
299
0
            if (profile != NULL) {
300
0
                params.group_color_type = ICC;
301
0
                params.group_color_numcomps = profile->num_comps;
302
0
                params.iccprofile = profile;
303
0
                params.icc_hash = gsicc_get_hash(profile);
304
0
            }
305
0
        }
306
1.22k
    }
307
#ifdef DEBUG
308
    if (gs_debug_c('v')) {
309
        static const char *const cs_names[] = {
310
            GS_COLOR_SPACE_TYPE_NAMES
311
        };
312
        dmlprintf6(pgs->memory, "[v]("PRI_INTPTR")begin_transparency_group [%g %g %g %g] Num_grp_clr_comp = %d\n",
313
                   (intptr_t)pgs, pbbox->p.x, pbbox->p.y, pbbox->q.x, pbbox->q.y,params.group_color_numcomps);
314
        if (ptgp->ColorSpace)
315
            dmprintf1(pgs->memory, "     CS = %s",
316
                cs_names[(int)gs_color_space_get_index(ptgp->ColorSpace)]);
317
        else
318
            dmputs(pgs->memory, "     (no CS)");
319
320
        dmprintf4(pgs->memory, "  Isolated = %d  Knockout = %d text_group = %d page_group = %d\n",
321
                 ptgp->Isolated, ptgp->Knockout, ptgp->text_group, ptgp->page_group);
322
    }
323
#endif
324
22.0k
    params.bbox = *pbbox;
325
22.0k
    return gs_gstate_update_pdf14trans(pgs, &params);
326
22.0k
}
327
328
int
329
gx_begin_transparency_group(gs_gstate * pgs, gx_device * pdev,
330
                                const gs_pdf14trans_params_t * pparams)
331
548k
{
332
548k
    gs_transparency_group_params_t tgp = {0};
333
548k
    gs_rect bbox;
334
335
548k
    if (pparams->Background_components != 0 &&
336
548k
        pparams->Background_components != pdev->color_info.num_components)
337
0
        return_error(gs_error_rangecheck);
338
548k
    tgp.Isolated = pparams->Isolated;
339
548k
    tgp.Knockout = pparams->Knockout;
340
548k
    tgp.page_group = pparams->page_group;
341
548k
    tgp.idle = pparams->idle;
342
548k
    tgp.mask_id = pparams->mask_id;
343
548k
    tgp.text_group = pparams->text_group;
344
548k
    tgp.shade_group = pparams->shade_group;
345
346
    /* Needed so that we do proper blending */
347
548k
    tgp.group_color_type = pparams->group_color_type;
348
548k
    tgp.group_color_numcomps = pparams->group_color_numcomps;
349
548k
    tgp.iccprofile = pparams->iccprofile;
350
548k
    tgp.icc_hashcode = pparams->icc_hash;
351
352
548k
    tgp.group_opacity = pparams->opacity;
353
548k
    tgp.group_shape = pparams->shape;
354
355
548k
    if (tgp.Knockout && tgp.text_group == PDF14_TEXTGROUP_BT_PUSHED &&
356
548k
        ((pgs->overprint && pgs->is_fill_color) || (pgs->stroke_overprint && !pgs->is_fill_color)))
357
6
        pgs->blend_mode = BLEND_MODE_CompatibleOverprint;
358
548k
    else
359
548k
        pgs->blend_mode = pparams->blend_mode;
360
548k
    bbox = pparams->bbox;
361
#ifdef DEBUG
362
    if (gs_debug_c('v')) {
363
        static const char *const cs_names[] = {
364
            GS_COLOR_SPACE_TYPE_NAMES
365
        };
366
        dmlprintf6(pdev->memory, "[v]("PRI_INTPTR")gx_begin_transparency_group [%g %g %g %g] Num_grp_clr_comp = %d\n",
367
                   (intptr_t)pgs, bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y,
368
                   pparams->group_color_numcomps);
369
        dmlprintf2(pdev->memory, "     opacity = %g shape = %g\n", pparams->opacity, pparams->shape);
370
        if (tgp.ColorSpace)
371
            dmprintf1(pdev->memory, "     CS = %s",
372
                cs_names[(int)gs_color_space_get_index(tgp.ColorSpace)]);
373
        else
374
            dmputs(pdev->memory, "     (no CS)");
375
        dmprintf3(pdev->memory, "  Isolated = %d  Knockout = %d  page_group = %d\n",
376
                 tgp.Isolated, tgp.Knockout, tgp.page_group);
377
        if (tgp.iccprofile)
378
            dmprintf(pdev->memory, "     Have ICC Profile for blending\n");
379
380
    }
381
#endif
382
548k
    return (*dev_proc(pdev, begin_transparency_group)) (pdev, &tgp, &bbox, pgs,
383
548k
                                                            NULL);
384
548k
}
385
386
int
387
gs_end_transparency_group(gs_gstate *pgs)
388
21.5k
{
389
21.5k
    gs_pdf14trans_params_t params = { 0 };
390
391
21.5k
    if (check_for_nontrans_pattern(pgs,
392
21.5k
                  (unsigned char *)"gs_end_transparency_group")) {
393
1
        return(0);
394
1
    }
395
21.5k
    if_debug0m('v', pgs->memory, "[v]gs_end_transparency_group\n");
396
21.5k
    params.pdf14_op = PDF14_END_TRANS_GROUP;  /* Other parameters not used */
397
21.5k
    return gs_gstate_update_pdf14trans(pgs, &params);
398
21.5k
}
399
400
int
401
gs_end_transparency_text_group(gs_gstate *pgs)
402
211k
{
403
211k
    gs_pdf14trans_params_t params = { 0 };
404
405
211k
    if (check_for_nontrans_pattern(pgs,
406
211k
        (unsigned char *)"gs_end_transparency_text_group")) {
407
0
        return(0);
408
0
    }
409
211k
    if_debug0m('v', pgs->memory, "[v]gs_end_transparency_text_group\n");
410
211k
    params.pdf14_op = PDF14_END_TRANS_TEXT_GROUP;  /* Other parameters not used */
411
211k
    return gs_gstate_update_pdf14trans(pgs, &params);
412
211k
}
413
414
int
415
gs_begin_transparency_text_group(gs_gstate *pgs)
416
180k
{
417
180k
    gs_pdf14trans_params_t params = { 0 };
418
419
180k
    if (check_for_nontrans_pattern(pgs,
420
180k
        (unsigned char *)"gs_begin_transparency_text_group")) {
421
0
        return(0);
422
0
    }
423
180k
    if_debug0m('v', pgs->memory, "[v]gs_begin_transparency_text_group\n");
424
180k
    params.pdf14_op = PDF14_BEGIN_TRANS_TEXT_GROUP;  /* Other parameters not used */
425
180k
    return gs_gstate_update_pdf14trans(pgs, &params);
426
180k
}
427
428
int
429
gx_end_transparency_group(gs_gstate * pgs, gx_device * pdev)
430
548k
{
431
548k
    if_debug0m('v', pgs->memory, "[v]gx_end_transparency_group\n");
432
548k
    return (*dev_proc(pdev, end_transparency_group)) (pdev, pgs);
433
548k
}
434
435
/* Commands for handling q softmask Q in graphic states */
436
437
int
438
gs_push_transparency_state(gs_gstate *pgs)
439
381k
{
440
381k
    gs_pdf14trans_params_t params = { 0 };
441
381k
    int code;
442
443
381k
    if (check_for_nontrans_pattern(pgs,
444
381k
                  (unsigned char *)"gs_push_transparency_state")) {
445
672
        return(0);
446
672
    }
447
    /* Set the pending flag to true, which indicates
448
       that we need to watch for end transparency
449
       soft masks when we are at this graphic state
450
       level */
451
    /* pgs->trans_flags.xstate_pending = true; */
452
    /* Actually I believe the above flag is not
453
       needed.  We really should be watching for
454
       the softmask even at the base level.  What
455
       we need to watch for are q operations after
456
       a soft mask end has occured. */
457
    /* Check if we have a change flag set to true.
458
       this indicates that a softmask is present.
459
       We will need to send a push state to save
460
       the current soft mask, so that we can
461
       restore it later */
462
381k
    if (pgs->trans_flags.xstate_change) {
463
0
        if_debug0m('v', pgs->memory, "[v]gs_push_transparency_state sending\n");
464
0
        params.pdf14_op = PDF14_PUSH_TRANS_STATE;
465
0
        code = gs_gstate_update_pdf14trans(pgs, &params);
466
0
        if (code < 0)
467
0
            return(code);
468
381k
    } else {
469
381k
        if_debug0m('v', pgs->memory, "[v]gs_push_transparency_state NOT sending\n");
470
381k
    }
471
381k
    return(0);
472
381k
}
473
474
int
475
gs_pop_transparency_state(gs_gstate *pgs, bool force)
476
348k
{
477
348k
    gs_pdf14trans_params_t params = { 0 };
478
348k
    int code;
479
480
348k
    if (check_for_nontrans_pattern(pgs,
481
348k
                  (unsigned char *)"gs_pop_transparency_state")) {
482
672
        return(0);
483
672
    }
484
    /* Check if flag is set, which indicates that we have
485
       an active softmask for the graphic state.  We
486
       need to communicate to the compositor to pop
487
       the softmask */
488
347k
    if ( pgs->trans_flags.xstate_change || force) {
489
12.5k
        if_debug0m('v', pgs->memory, "[v]gs_pop_transparency_state sending\n");
490
12.5k
        params.pdf14_op = PDF14_POP_TRANS_STATE;
491
12.5k
        code = gs_gstate_update_pdf14trans(pgs, &params);
492
12.5k
        if ( code < 0 )
493
0
            return (code);
494
335k
    } else {
495
335k
        if_debug0m('v', pgs->memory, "[v]gs_pop_transparency_state NOT sending\n");
496
335k
    }
497
    /* There is no reason to reset any of the flags since
498
       they will be reset by the graphic state restore */
499
347k
    return(0);
500
347k
}
501
502
int
503
gx_pop_transparency_state(gs_gstate * pgs, gx_device * pdev)
504
1.00M
{
505
1.00M
    if_debug0m('v', pgs->memory, "[v]gx_pop_transparency_state\n");
506
1.00M
    return (*dev_proc(pdev, pop_transparency_state)) (pdev, pgs);
507
1.00M
}
508
509
int
510
gx_push_transparency_state(gs_gstate * pgs, gx_device * pdev)
511
0
{
512
0
    if_debug0m('v', pgs->memory, "[v]gx_push_transparency_state\n");
513
0
    return (*dev_proc(pdev, push_transparency_state)) (pdev, pgs);
514
0
}
515
516
/*
517
 * Handler for identity mask transfer functions.
518
 */
519
static int
520
mask_transfer_identity(double in, float *out, void *proc_data)
521
3.23M
{
522
3.23M
    *out = (float) in;
523
3.23M
    return 0;
524
3.23M
}
525
526
void
527
gs_trans_mask_params_init(gs_transparency_mask_params_t *ptmp,
528
                          gs_transparency_mask_subtype_t subtype)
529
25.9k
{
530
25.9k
    ptmp->ColorSpace = 0;
531
25.9k
    ptmp->subtype = subtype;
532
25.9k
    ptmp->Background_components = 0;
533
25.9k
    ptmp->Matte_components = 0;
534
25.9k
    ptmp->GrayBackground = 0.0;
535
25.9k
    ptmp->TransferFunction = mask_transfer_identity;
536
25.9k
    ptmp->TransferFunction_data = 0;
537
25.9k
    ptmp->replacing = false;
538
25.9k
    ptmp->iccprofile = NULL;
539
25.9k
}
540
541
int
542
gs_begin_transparency_mask(gs_gstate * pgs,
543
                           const gs_transparency_mask_params_t * ptmp,
544
                           const gs_rect * pbbox, bool mask_is_image)
545
25.8k
{
546
25.8k
    gs_pdf14trans_params_t params = { 0 };
547
25.8k
    gs_pdf14trans_params_t params_color = { 0 };
548
25.8k
    const int l = sizeof(params.Background[0]) * ptmp->Background_components;
549
25.8k
    const int m = sizeof(params.Matte[0]) * ptmp->Matte_components;
550
25.8k
    int i, code;
551
25.8k
    gs_color_space *blend_color_space;
552
25.8k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
553
25.8k
    bool deep = device_is_deep(pgs->device);
554
555
25.8k
    if (check_for_nontrans_pattern(pgs,
556
25.8k
                  (unsigned char *)"gs_pop_transparency_state")) {
557
0
        return(0);
558
0
    }
559
25.8k
    params.pdf14_op = PDF14_BEGIN_TRANS_MASK;
560
25.8k
    params.bbox = *pbbox;
561
25.8k
    params.subtype = ptmp->subtype;
562
25.8k
    params.Background_components = ptmp->Background_components;
563
25.8k
    memcpy(params.Background, ptmp->Background, l);
564
25.8k
    params.ColorSpace = ptmp->ColorSpace;
565
25.8k
    params.Matte_components = ptmp->Matte_components;
566
25.8k
    memcpy(params.Matte, ptmp->Matte, m);
567
25.8k
    params.GrayBackground = ptmp->GrayBackground;
568
25.8k
    params.transfer_function = ptmp->TransferFunction_data;
569
25.8k
    params.function_is_identity =
570
25.8k
            (ptmp->TransferFunction == mask_transfer_identity);
571
25.8k
    params.mask_is_image = mask_is_image;
572
25.8k
    params.replacing = ptmp->replacing;
573
574
    /* The eventual state that we want this smask to be moved to
575
       is always gray.  This should provide us with a significant
576
       speed improvement over the old code.  This does not keep us
577
       from having groups within the softmask getting blended in different
578
       color spaces, it just makes the final space be gray, which is what
579
       we will need to get to eventually anyway. In this way we avoid a
580
       final color conversion on a potentially large buffer. */
581
    /* Also check if we have loaded in the transparency icc profiles.  If not
582
       go ahead and take care of that now */
583
25.8k
    if (icc_manager->smask_profiles == NULL) {
584
731
        code = gsicc_initialize_iccsmask(icc_manager);
585
731
        if (code < 0)
586
4
            return(code);
587
731
    }
588
    /* A new soft mask group,  make sure the profiles are set */
589
25.8k
    if_debug0m('v', pgs->memory, "[v]pushing soft mask color sending\n");
590
25.8k
    if (params.subtype != TRANSPARENCY_MASK_None) {
591
12.7k
        params_color.pdf14_op = PDF14_PUSH_SMASK_COLOR;
592
12.7k
        code = gs_gstate_update_pdf14trans(pgs, &params_color);
593
12.7k
        if (code < 0)
594
0
            return(code);
595
12.7k
        blend_color_space = gs_cspace_new_DeviceGray(pgs->memory);
596
12.7k
        if (blend_color_space == NULL)
597
0
            return_error(gs_error_VMerror);
598
12.7k
        blend_color_space->cmm_icc_profile_data = pgs->icc_manager->default_gray;
599
12.7k
        gsicc_adjust_profile_rc(blend_color_space->cmm_icc_profile_data, 1, "gs_begin_transparency_mask");
600
12.7k
        if_debug9m('v', pgs->memory, "[v]("PRI_INTPTR")gs_begin_transparency_mask [%g %g %g %g]\n"
601
12.7k
                   "      subtype = %d  Background_components = %d, Matte_components = %d, %s\n",
602
12.7k
                  (intptr_t)pgs, pbbox->p.x, pbbox->p.y, pbbox->q.x, pbbox->q.y,
603
12.7k
                  (int)ptmp->subtype, ptmp->Background_components,
604
12.7k
                  ptmp->Matte_components,
605
12.7k
                  (ptmp->TransferFunction == mask_transfer_identity ? "no TR" :
606
12.7k
                   "has TR"));
607
        /* Sample the transfer function */
608
        /* For non-deep cases, we sample at 00,01,02..fe,ff.
609
         * For deep cases, we sample from 0000,0100,0200..fe00,ff00 and a final one at ffff.
610
         * This enables us to interpolate easily.
611
         */
612
12.7k
        if (deep) {
613
0
            uint16_t *trans16 = (uint16_t *)params.transfer_fn;
614
0
            float out;
615
0
            for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
616
0
                float in = (float)(i * (1.0 / MASK_TRANSFER_FUNCTION_SIZE));
617
618
0
                ptmp->TransferFunction(in, &out, ptmp->TransferFunction_data);
619
0
                trans16[i] = (uint16_t)floor((double)(out * 65535 + 0.5));
620
0
            }
621
0
            ptmp->TransferFunction(1.0, &out, ptmp->TransferFunction_data);
622
0
            trans16[MASK_TRANSFER_FUNCTION_SIZE] = (uint16_t)floor((double)(out * 65535 + 0.5));
623
12.7k
        } else {
624
3.27M
            for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
625
3.25M
                float in = (float)(i * (1.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)));
626
3.25M
                float out;
627
628
3.25M
                ptmp->TransferFunction(in, &out, ptmp->TransferFunction_data);
629
3.25M
                params.transfer_fn[i] = (byte)floor((double)(out * 255 + 0.5));
630
3.25M
            }
631
12.7k
        }
632
        /* Note:  This function is called during the c-list writer side. */
633
12.7k
        if ( blend_color_space->cmm_icc_profile_data != NULL ) {
634
        /* Blending space is ICC based.  If we are doing c-list rendering we will
635
           need to write this color space into the clist. */
636
12.7k
            params.group_color_type = ICC;
637
12.7k
            params.group_color_numcomps =
638
12.7k
                    blend_color_space->cmm_icc_profile_data->num_comps;
639
            /* Get the ICC profile */
640
            /* We don't reference count this - see comment in
641
             * pdf14_update_device_color_procs_pop_c()
642
             */
643
12.7k
            params.iccprofile = blend_color_space->cmm_icc_profile_data;
644
12.7k
            params.icc_hash = gsicc_get_hash(blend_color_space->cmm_icc_profile_data);
645
12.7k
        } else {
646
0
            params.group_color_type = GRAY_SCALE;
647
0
            params.group_color_numcomps = 1;  /* Need to check */
648
0
        }
649
        /* Explicitly decrement the profile data since blend_color_space may not
650
         * be an ICC color space object.
651
         */
652
12.7k
        gsicc_adjust_profile_rc(blend_color_space->cmm_icc_profile_data, -1, "gs_begin_transparency_mask");
653
12.7k
        rc_decrement_only_cs(blend_color_space, "gs_begin_transparency_mask");
654
12.7k
    }
655
25.8k
    return gs_gstate_update_pdf14trans(pgs, &params);
656
25.8k
}
657
658
/* This occurs on the c-list reader side */
659
660
int
661
gx_begin_transparency_mask(gs_gstate * pgs, gx_device * pdev,
662
                                const gs_pdf14trans_params_t * pparams)
663
1.22M
{
664
1.22M
    gx_transparency_mask_params_t tmp;
665
1.22M
    const int l = sizeof(pparams->Background[0]) * pparams->Background_components;
666
1.22M
    const int m = sizeof(pparams->Matte[0]) * pparams->Matte_components;
667
668
1.22M
    tmp.group_color_type = pparams->group_color_type;
669
1.22M
    tmp.subtype = pparams->subtype;
670
1.22M
    tmp.group_color_numcomps = pparams->group_color_numcomps;
671
1.22M
    tmp.Background_components = pparams->Background_components;
672
1.22M
    memcpy(tmp.Background, pparams->Background, l);
673
1.22M
    tmp.Matte_components = pparams->Matte_components;
674
1.22M
    memcpy(tmp.Matte, pparams->Matte, m);
675
1.22M
    tmp.GrayBackground = pparams->GrayBackground;
676
1.22M
    tmp.function_is_identity = pparams->function_is_identity;
677
1.22M
    tmp.idle = pparams->idle;
678
1.22M
    tmp.replacing = pparams->replacing;
679
1.22M
    tmp.mask_id = pparams->mask_id;
680
681
1.22M
    if (tmp.group_color_type == ICC ) {
682
        /* Do I need to ref count here? */
683
137k
        tmp.iccprofile = pparams->iccprofile;
684
137k
        tmp.icc_hashcode = pparams->icc_hash;
685
1.08M
    } else {
686
1.08M
        tmp.iccprofile = NULL;
687
1.08M
        tmp.icc_hashcode = 0;
688
1.08M
    }
689
1.22M
    memcpy(tmp.transfer_fn, pparams->transfer_fn, size_of(tmp.transfer_fn));
690
1.22M
    if_debug10m('v', pgs->memory,
691
1.22M
               "[v]("PRI_INTPTR")gx_begin_transparency_mask [%g %g %g %g]\n"
692
1.22M
               "      subtype = %d  Background_components = %d Matte_components = %d Num_grp_clr_comp = %d %s\n",
693
1.22M
              (intptr_t)pgs, pparams->bbox.p.x, pparams->bbox.p.y,
694
1.22M
              pparams->bbox.q.x, pparams->bbox.q.y,
695
1.22M
              (int)tmp.subtype, tmp.Background_components, tmp.Matte_components,
696
1.22M
              tmp.group_color_numcomps,
697
1.22M
              (tmp.function_is_identity ? "no TR" :
698
1.22M
               "has TR"));
699
1.22M
    return (*dev_proc(pdev, begin_transparency_mask))
700
1.22M
                        (pdev, &tmp, &(pparams->bbox), pgs, NULL);
701
1.22M
}
702
703
int
704
gs_end_transparency_mask(gs_gstate *pgs,
705
                         gs_transparency_channel_selector_t csel)
706
12.7k
{
707
12.7k
    gs_pdf14trans_params_t params = { 0 };
708
12.7k
    gs_pdf14trans_params_t params_color = { 0 };
709
12.7k
    int code;
710
711
12.7k
    if (check_for_nontrans_pattern(pgs,
712
12.7k
                  (unsigned char *)"gs_end_transparency_mask")) {
713
0
        return(0);
714
0
    }
715
    /* If we have done a q then set a flag to watch for any Qs */
716
   /* if (pgs->trans_flags.xstate_pending)
717
        pgs->trans_flags.xstate_change = true; */
718
    /* This should not depend upon if we have encountered a q
719
       operation.  We could be setting a softmask, before
720
       there is any q operation.  Unlikely but it could happen.
721
       Then if we encouter a q operation (and this flag
722
       is true) we will need to
723
       push the mask graphic state (PDF14_PUSH_TRANS_STATE). */
724
12.7k
    pgs->trans_flags.xstate_change = true;
725
12.7k
    if_debug1m('v', pgs->memory,
726
12.7k
               "[v]xstate_changed set true, gstate level is %d\n", pgs->level);
727
12.7k
    if_debug2m('v', pgs->memory,
728
12.7k
               "[v]("PRI_INTPTR")gs_end_transparency_mask(%d)\n", (intptr_t)pgs,
729
12.7k
               (int)csel);
730
12.7k
    params.pdf14_op = PDF14_END_TRANS_MASK;  /* Other parameters not used */
731
12.7k
    params.csel = csel;
732
    /* If this is the outer end then return us to our normal defaults */
733
12.7k
    if_debug0m('v', pgs->memory, "[v]popping soft mask color sending\n");
734
12.7k
    params_color.pdf14_op = PDF14_POP_SMASK_COLOR;
735
12.7k
    code = gs_gstate_update_pdf14trans(pgs, &params_color);
736
12.7k
    if (code < 0)
737
0
        return(code);
738
12.7k
    return gs_gstate_update_pdf14trans(pgs, &params);
739
12.7k
}
740
741
int
742
gx_end_transparency_mask(gs_gstate * pgs, gx_device * pdev,
743
                                const gs_pdf14trans_params_t * pparams)
744
137k
{
745
137k
    if_debug2m('v', pgs->memory,
746
137k
               "[v]("PRI_INTPTR")gx_end_transparency_mask(%d)\n", (intptr_t)pgs,
747
137k
               (int)pparams->csel);
748
137k
    return (*dev_proc(pdev, end_transparency_mask)) (pdev, pgs);
749
137k
}
750
751
/*
752
 * We really only care about the number of spot colors when we have
753
 * a device which supports spot colors.  With the other devices we use
754
 * the tint transform function for DeviceN and Separation color spaces
755
 * and convert spot colors into process colors.
756
 */
757
static int
758
get_num_pdf14_spot_colors(gs_gstate * pgs)
759
9.14k
{
760
9.14k
    gx_device * dev = pgs->device;
761
9.14k
    gs_devn_params * pclist_devn_params = dev_proc(dev, ret_devn_params)(dev);
762
763
    /*
764
     * Devices which support spot colors store the PageSpotColors device
765
     * parameter inside their devn_params structure.  (This is done by the
766
     * devn_put_params routine.)  The PageSpotColors device parameter is
767
     * set by pdf_main whenever a PDF page is being processed.  See
768
     * countspotcolors in lib/pdf_main.ps.
769
     */
770
9.14k
    if (pclist_devn_params != NULL) {
771
        /* If the sep order names were specified, then we should only allocate
772
           for those.  But only the nonstandard colorants that are stored
773
           in num_separations.  See devn_put_params for details on this.
774
           Right now, the PDF14 device will always include CMYK.  A future
775
           optimization is to be able to NOT have those included in the buffer
776
           allocations if we don't specify them.  It would then be possible to
777
           output 8 separations at a time without using compressed color. */
778
6.90k
        if (pclist_devn_params->num_separation_order_names == 0) {
779
6.90k
            return pclist_devn_params->page_spot_colors;
780
6.90k
        }
781
0
        return (pclist_devn_params->separations.num_separations);
782
6.90k
    }
783
2.24k
    return 0;
784
9.14k
}
785
786
int
787
gs_push_pdf14trans_device(gs_gstate * pgs, bool is_pattern, bool retain,
788
                          int depth, int spot_color_count)
789
9.14k
{
790
9.14k
    gs_pdf14trans_params_t params = { 0 };
791
9.14k
    cmm_profile_t *icc_profile;
792
9.14k
    gsicc_rendering_param_t render_cond;
793
9.14k
    int code;
794
9.14k
    cmm_dev_profile_t *dev_profile;
795
9.14k
    unsigned char pattern_opsim_setting[2];
796
797
9.14k
    code = dev_proc(pgs->device, get_profile)(pgs->device,  &dev_profile);
798
9.14k
    if (code < 0)
799
0
        return code;
800
9.14k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
801
9.14k
                          &render_cond);
802
9.14k
    params.pdf14_op = PDF14_PUSH_DEVICE;
803
    /*
804
     * We really only care about the number of spot colors when we have
805
     * a device which supports spot colors.  With the other devices we use
806
     * the tint transform function for DeviceN and Separation color spaces
807
     * and convert spot colors into process colors.
808
     */
809
9.14k
    params.num_spot_colors = get_num_pdf14_spot_colors(pgs);
810
9.14k
    params.is_pattern = is_pattern;
811
812
    /* If pattern, get overprint simulation information from
813
       the pattern accumulators target device */
814
9.14k
    if (is_pattern && dev_proc(pgs->device, dev_spec_op)(pgs->device, gxdso_overprintsim_state, &pattern_opsim_setting, sizeof(pattern_opsim_setting))) {
815
        /* Use the target device setting */
816
6.36k
        params.overprint_sim_push = pattern_opsim_setting[0];
817
6.36k
        params.num_spot_colors_int = pattern_opsim_setting[1];
818
6.36k
    } else {
819
        /* Use information from interpreter */
820
2.78k
        params.num_spot_colors_int = spot_color_count;
821
2.78k
        if (depth < 0)
822
0
            params.overprint_sim_push = true;
823
2.78k
    }
824
825
    /* If we have an NCLR ICC profile, the extra spot colorants do
826
    *  get included in the transparency buffers. Trying to avoid
827
    * including them became a rube goldberg mess in terms of knowing
828
    * which colorants are on the page vs what has been specified and
829
    * any aliasing between these two.  Just too many things to go wrong.
830
    * So we allocate all and carry around. If you are doing special
831
    * spot handling with transparency this is the cost. */
832
833
9.14k
    if (dev_profile->spotnames != NULL && dev_profile->spotnames->count > 4) {
834
        /* Making an assumption here, that list is CMYK + extra.
835
           An error should have been thrown by the target device if not. */
836
0
        int avail_page_spots = pgs->device->color_info.num_components - 4;
837
0
        params.num_spot_colors_int = avail_page_spots;
838
0
        params.num_spot_colors = avail_page_spots;
839
840
        /* This should not be possible, but lets be safe. We can't have a negative
841
          number of source spots to carry forward, so apply threshold. */
842
0
        if (params.num_spot_colors_int < 0)
843
0
            params.num_spot_colors_int = 0;
844
0
        if (params.num_spot_colors < 0)
845
0
            params.num_spot_colors = 0;
846
0
    }
847
848
    /* If we happen to be in a situation where we are going out to a device
849
       whose profile is CIELAB then we will need to make sure that we
850
       do our blending in RGB and convert to CIELAB when we do the put_image
851
       command */
852
9.14k
    if (icc_profile->data_cs == gsCIELAB ||
853
9.14k
        icc_profile->islab) {
854
0
        params.iccprofile = pgs->icc_manager->default_rgb;
855
0
    }
856
    /* Note: Other parameters not used */
857
9.14k
    return gs_gstate_update_pdf14trans2(pgs, &params, retain);
858
9.14k
}
859
860
int
861
gs_pop_pdf14trans_device(gs_gstate * pgs, bool is_pattern)
862
2.84k
{
863
2.84k
    gs_pdf14trans_params_t params = { 0 };
864
865
2.84k
    params.is_pattern = is_pattern;
866
2.84k
    params.pdf14_op = PDF14_POP_DEVICE;  /* Other parameters not used */
867
2.84k
    return gs_gstate_update_pdf14trans(pgs, &params);
868
2.84k
}
869
870
int
871
gs_abort_pdf14trans_device(gs_gstate * pgs)
872
0
{
873
0
    gs_pdf14trans_params_t params = { 0 };
874
875
0
    params.pdf14_op = PDF14_ABORT_DEVICE;  /* Other parameters not used */
876
0
    return gs_gstate_update_pdf14trans(pgs, &params);
877
0
}
878
879
/* Something has gone wrong have the device clean up everything */
880
881
int
882
gx_abort_trans_device(gs_gstate * pgs, gx_device * pdev)
883
0
{
884
0
    if_debug1m('v', pgs->memory, "[v]("PRI_INTPTR")gx_abort_trans_device\n", (intptr_t)pgs);
885
0
    return (*dev_proc(pdev, discard_transparency_layer)) (pdev, pgs);
886
0
}
887
888
int gs_setstrokeconstantalpha(gs_gstate *pgs, float alpha)
889
875k
{
890
875k
    pgs->strokeconstantalpha = alpha;
891
875k
    return 0;
892
875k
}
893
894
float gs_getstrokeconstantalpha(const gs_gstate *pgs)
895
22.2k
{
896
22.2k
    return pgs->strokeconstantalpha;
897
22.2k
}
898
899
int gs_setfillconstantalpha(gs_gstate *pgs, float alpha)
900
880k
{
901
880k
    pgs->fillconstantalpha = (float)alpha;
902
880k
    return 0;
903
880k
}
904
905
float gs_getfillconstantalpha(const gs_gstate *pgs)
906
40.6k
{
907
40.6k
    return pgs->fillconstantalpha;
908
40.6k
}
909
910
int gs_setalphaisshape(gs_gstate *pgs, bool AIS)
911
796k
{
912
796k
    pgs->alphaisshape = AIS;
913
796k
    return 0;
914
796k
}
915
916
bool gs_getalphaisshape(gs_gstate *pgs)
917
356k
{
918
356k
    return pgs->alphaisshape;
919
356k
}