Coverage Report

Created: 2025-06-10 07:26

/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
2.77M
{
37
2.77M
    return (x + y) / 2;
38
2.77M
}
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
40.8k
{
46
40.8k
    os_ptr op = osp;
47
40.8k
    gs_colorscreen_halftone cscreen;
48
40.8k
    ref sprocs[4];
49
40.8k
    gs_halftone *pht;
50
40.8k
    gx_device_halftone *pdht;
51
40.8k
    int i;
52
40.8k
    int code = 0;
53
40.8k
    int space = 0;
54
40.8k
    gs_memory_t *mem;
55
40.8k
    gs_memory_t *currmem = (gs_memory_t *)idmemory->current;
56
57
204k
    for (i = 0; i < 4; i++) {
58
163k
        os_ptr op1 = op - 9 + i * 3;
59
163k
        int code = zscreen_params(op1, &cscreen.screens.indexed[i]);
60
61
163k
        if (code < 0)
62
0
            return code;
63
163k
        cscreen.screens.indexed[i].spot_function = spot_dummy;
64
163k
        sprocs[i] = *op1;
65
163k
        space = max(space, r_space_index(op1));
66
163k
    }
67
40.8k
    mem = (gs_memory_t *)idmemory->spaces_indexed[space];
68
    /* We must have the currentglobal consistent through the sampling process */
69
40.8k
    ialloc_set_space(idmemory, (mem == (gs_memory_t *)idmemory->spaces.memories.named.global ? avm_global : avm_local));
70
40.8k
    check_estack(9);   /* for sampling screens */
71
40.8k
    rc_alloc_struct_0(pht, gs_halftone, &st_halftone,
72
40.8k
                      mem, pht = 0, "setcolorscreen(halftone)");
73
40.8k
    rc_alloc_struct_0(pdht, gx_device_halftone, &st_device_halftone,
74
40.8k
                      mem, pdht = 0, "setcolorscreen(device halftone)");
75
40.8k
    if (pht == 0 || pdht == 0)
76
0
        code = gs_note_error(gs_error_VMerror);
77
40.8k
    else {
78
40.8k
        pht->type = ht_type_colorscreen;
79
40.8k
        pht->objtype = HT_OBJTYPE_DEFAULT;
80
40.8k
        pht->params.colorscreen = cscreen;
81
40.8k
        code = gs_sethalftone_prepare(igs, pht, pdht);
82
40.8k
    }
83
40.8k
    if (code >= 0) {   /* Schedule the sampling of the screens. */
84
40.8k
        es_ptr esp0 = esp; /* for backing out */
85
86
40.8k
        esp += 9;
87
40.8k
        make_mark_estack(esp - 8, es_other, setcolorscreen_cleanup);
88
40.8k
        make_bool(esp - 7, (currmem == (gs_memory_t *)idmemory->spaces.memories.named.global));
89
40.8k
        memcpy(esp - 6, sprocs, sizeof(ref) * 4); /* procs */
90
40.8k
        make_istruct(esp - 2, 0, pht);
91
40.8k
        make_istruct(esp - 1, 0, pdht);
92
40.8k
        make_op_estack(esp, setcolorscreen_finish);
93
204k
        for (i = 0; i < 4; i++) {
94
            /* Shuffle the indices to correspond to */
95
            /* the component order. */
96
163k
            code = zscreen_enum_init(i_ctx_p,
97
163k
                                     &pdht->components[(i + 1) & 3].corder,
98
163k
                                &pht->params.colorscreen.screens.indexed[i],
99
163k
                                     &sprocs[i], 0, 0, space);
100
163k
            if (code < 0) {
101
0
                esp = esp0;
102
0
                break;
103
0
            }
104
163k
        }
105
40.8k
    }
106
40.8k
    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
40.8k
    pop(12);
112
40.8k
    return o_push_estack;
113
40.8k
}
114
/* Install the color screen after sampling. */
115
static int
116
setcolorscreen_finish(i_ctx_t *i_ctx_p)
117
40.8k
{
118
40.8k
    gx_device_halftone *pdht = r_ptr(esp, gx_device_halftone);
119
40.8k
    int code;
120
121
40.8k
    pdht->order = pdht->components[0].corder;
122
40.8k
    code = gx_ht_install(igs, r_ptr(esp - 1, gs_halftone), pdht);
123
40.8k
    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
40.8k
    istate->screen_procs.red   = esp[-5];
134
40.8k
    istate->screen_procs.green = esp[-4];
135
40.8k
    istate->screen_procs.blue  = esp[-3];
136
40.8k
    istate->screen_procs.gray  = esp[-2];
137
40.8k
    make_null(&istate->halftone);
138
40.8k
    esp -= 8;
139
40.8k
    setcolorscreen_cleanup(i_ctx_p);
140
40.8k
    return o_pop_estack;
141
40.8k
}
142
/* Clean up after installing the color screen. */
143
static int
144
setcolorscreen_cleanup(i_ctx_t *i_ctx_p)
145
40.8k
{
146
40.8k
    gs_halftone *pht = r_ptr(esp + 7, gs_halftone);
147
40.8k
    gx_device_halftone *pdht = r_ptr(esp + 8, gx_device_halftone);
148
40.8k
    bool global = (esp + 2)->value.boolval;
149
150
40.8k
    gs_free_object(pdht->rc.memory, pdht,
151
40.8k
                   "setcolorscreen_cleanup(device halftone)");
152
40.8k
    gs_free_object(pht->rc.memory, pht,
153
40.8k
                   "setcolorscreen_cleanup(halftone)");
154
    /* See bug #707007, explicitly freed structures on the stacks need to be made NULL */
155
40.8k
    make_null(esp + 6);
156
40.8k
    make_null(esp + 7);
157
40.8k
    ialloc_set_space(idmemory, (global ? avm_global : avm_local));
158
40.8k
    return 0;
159
40.8k
}
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
};