Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/psi/zht1.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2024 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
17
/* setcolorscreen operator */
18
#include "ghost.h"
19
#include "memory_.h"
20
#include "oper.h"
21
#include "estack.h"
22
#include "gsstruct.h"   /* must precede igstate.h, */
23
                                        /* because of #ifdef in gsht.h */
24
#include "ialloc.h"
25
#include "igstate.h"
26
#include "gsmatrix.h"
27
#include "gxdevice.h"   /* for gzht.h */
28
#include "gzht.h"
29
#include "gsstate.h"
30
#include "iht.h"
31
#include "store.h"
32
33
/* Dummy spot function */
34
static float
35
spot_dummy(double x, double y)
36
22.2M
{
37
22.2M
    return (x + y) / 2;
38
22.2M
}
39
40
/* <red_freq> ... <gray_proc> setcolorscreen - */
41
static int setcolorscreen_finish(i_ctx_t *);
42
static int setcolorscreen_cleanup(i_ctx_t *);
43
static int
44
zsetcolorscreen(i_ctx_t *i_ctx_p)
45
326k
{
46
326k
    os_ptr op = osp;
47
326k
    gs_colorscreen_halftone cscreen;
48
326k
    ref sprocs[4];
49
326k
    gs_halftone *pht;
50
326k
    gx_device_halftone *pdht;
51
326k
    int i;
52
326k
    int code = 0;
53
326k
    int space = 0;
54
326k
    gs_memory_t *mem;
55
326k
    gs_memory_t *currmem = (gs_memory_t *)idmemory->current;
56
57
1.63M
    for (i = 0; i < 4; i++) {
58
1.30M
        os_ptr op1 = op - 9 + i * 3;
59
1.30M
        int code = zscreen_params(op1, &cscreen.screens.indexed[i]);
60
61
1.30M
        if (code < 0)
62
0
            return code;
63
1.30M
        cscreen.screens.indexed[i].spot_function = spot_dummy;
64
1.30M
        sprocs[i] = *op1;
65
1.30M
        space = max(space, r_space_index(op1));
66
1.30M
    }
67
326k
    mem = (gs_memory_t *)idmemory->spaces_indexed[space];
68
    /* We must have the currentglobal consistent through the sampling process */
69
326k
    ialloc_set_space(idmemory, (mem == (gs_memory_t *)idmemory->spaces.memories.named.global ? avm_global : avm_local));
70
326k
    check_estack(9);   /* for sampling screens */
71
326k
    rc_alloc_struct_0(pht, gs_halftone, &st_halftone,
72
326k
                      mem, pht = 0, "setcolorscreen(halftone)");
73
326k
    rc_alloc_struct_0(pdht, gx_device_halftone, &st_device_halftone,
74
326k
                      mem, pdht = 0, "setcolorscreen(device halftone)");
75
326k
    if (pht == 0 || pdht == 0)
76
0
        code = gs_note_error(gs_error_VMerror);
77
326k
    else {
78
326k
        pht->type = ht_type_colorscreen;
79
326k
        pht->objtype = HT_OBJTYPE_DEFAULT;
80
326k
        pht->params.colorscreen = cscreen;
81
326k
        code = gs_sethalftone_prepare(igs, pht, pdht);
82
326k
    }
83
326k
    if (code >= 0) {   /* Schedule the sampling of the screens. */
84
326k
        es_ptr esp0 = esp; /* for backing out */
85
86
326k
        esp += 9;
87
326k
        make_mark_estack(esp - 8, es_other, setcolorscreen_cleanup);
88
326k
        make_bool(esp - 7, (currmem == (gs_memory_t *)idmemory->spaces.memories.named.global));
89
326k
        memcpy(esp - 6, sprocs, sizeof(ref) * 4); /* procs */
90
326k
        make_istruct(esp - 2, 0, pht);
91
326k
        make_istruct(esp - 1, 0, pdht);
92
326k
        make_op_estack(esp, setcolorscreen_finish);
93
1.63M
        for (i = 0; i < 4; i++) {
94
            /* Shuffle the indices to correspond to */
95
            /* the component order. */
96
1.30M
            code = zscreen_enum_init(i_ctx_p,
97
1.30M
                                     &pdht->components[(i + 1) & 3].corder,
98
1.30M
                                &pht->params.colorscreen.screens.indexed[i],
99
1.30M
                                     &sprocs[i], 0, 0, space);
100
1.30M
            if (code < 0) {
101
0
                esp = esp0;
102
0
                break;
103
0
            }
104
1.30M
        }
105
326k
    }
106
326k
    if (code < 0) {
107
0
        gs_free_object(mem, pdht, "setcolorscreen(device halftone)");
108
0
        gs_free_object(mem, pht, "setcolorscreen(halftone)");
109
0
        return code;
110
0
    }
111
326k
    pop(12);
112
326k
    return o_push_estack;
113
326k
}
114
/* Install the color screen after sampling. */
115
static int
116
setcolorscreen_finish(i_ctx_t *i_ctx_p)
117
326k
{
118
326k
    gx_device_halftone *pdht = r_ptr(esp, gx_device_halftone);
119
326k
    int code;
120
121
326k
    pdht->order = pdht->components[0].corder;
122
326k
    code = gx_ht_install(igs, r_ptr(esp - 1, gs_halftone), pdht);
123
326k
    if (code < 0) {
124
        /* We need the stack correct for setcolorscreen_cleanup() but we need it back
125
           where we started before we return the error.
126
         */
127
0
        es_ptr esp0 = esp;
128
0
        esp -= 8;
129
0
        setcolorscreen_cleanup(i_ctx_p);
130
0
        esp = esp0;
131
0
        return code;
132
0
    }
133
326k
    istate->screen_procs.red   = esp[-5];
134
326k
    istate->screen_procs.green = esp[-4];
135
326k
    istate->screen_procs.blue  = esp[-3];
136
326k
    istate->screen_procs.gray  = esp[-2];
137
326k
    make_null(&istate->halftone);
138
326k
    esp -= 8;
139
326k
    setcolorscreen_cleanup(i_ctx_p);
140
326k
    return o_pop_estack;
141
326k
}
142
/* Clean up after installing the color screen. */
143
static int
144
setcolorscreen_cleanup(i_ctx_t *i_ctx_p)
145
326k
{
146
326k
    gs_halftone *pht = r_ptr(esp + 7, gs_halftone);
147
326k
    gx_device_halftone *pdht = r_ptr(esp + 8, gx_device_halftone);
148
326k
    bool global = (esp + 2)->value.boolval;
149
150
326k
    gs_free_object(pdht->rc.memory, pdht,
151
326k
                   "setcolorscreen_cleanup(device halftone)");
152
326k
    gs_free_object(pht->rc.memory, pht,
153
326k
                   "setcolorscreen_cleanup(halftone)");
154
    /* See bug #707007, explicitly freed structures on the stacks need to be made NULL */
155
326k
    make_null(esp + 6);
156
326k
    make_null(esp + 7);
157
326k
    ialloc_set_space(idmemory, (global ? avm_global : avm_local));
158
326k
    return 0;
159
326k
}
160
161
/* ------ Initialization procedure ------ */
162
163
const op_def zht1_op_defs[] =
164
{
165
    {"<setcolorscreen", zsetcolorscreen},
166
                /* Internal operators */
167
    {"0%setcolorscreen_finish", setcolorscreen_finish},
168
    op_def_end(0)
169
};