Coverage Report

Created: 2025-06-10 06:49

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