Coverage Report

Created: 2025-06-10 07:27

/src/ghostpdl/base/gxhldevc.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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
/* High level device color save/compare procedures */
17
18
/*
19
 * See comments at the start of gxhldevc.h for more explanation of the
20
 * purpose and operation of these procedures.
21
 */
22
#include "gx.h"
23
#include "gzstate.h"
24
#include "gscspace.h"
25
#include "gxcspace.h"
26
#include "gxhldevc.h"
27
#include "memory_.h"
28
#include "gxpcolor.h"
29
#include "gsptype1.h"
30
#include "gsptype2.h"
31
32
/*
33
 * Initiailze a high level saved color to null
34
 */
35
void gx_hld_saved_color_init(gx_hl_saved_color * psc)
36
208k
{
37
208k
    gx_device_color temp_devc;
38
39
208k
    memset(psc, 0, sizeof(*psc)); /* clear the entire structure */
40
208k
    psc->color_space_id = psc->pattern_id = gs_no_id;
41
208k
    color_set_null(&temp_devc);
42
208k
    temp_devc.type->save_dc(&temp_devc, &(psc->saved_dev_color));
43
208k
}
44
45
/*
46
 * Save the device color information including the color space id and
47
 * client color data (if available).
48
 *
49
 * More description in src/gxhldevc.h
50
 */
51
bool
52
gx_hld_save_color(const gs_gstate * pgs, const gx_device_color * pdevc,
53
                gx_hl_saved_color * psc)
54
88.7M
{
55
88.7M
    memset(psc, 0, sizeof(*psc)); /* clear the entire structure */
56
57
88.7M
    if (pdevc == NULL) {
58
        /* No device color given, should not happen */
59
23.2k
        gx_hld_saved_color_init(psc); /* revert to unknown color */
60
23.2k
        return false;
61
88.7M
    } else if (pgs == NULL) {
62
        /* No color space, simply save device color specific info */
63
74.6M
        psc->color_space_id = psc->pattern_id = gs_no_id;
64
74.6M
        pdevc->type->save_dc(pdevc, &(psc->saved_dev_color));
65
74.6M
        return false;
66
74.6M
    } else {
67
        /*
68
         * Have color space, save id,  ccolor, & device color specific info.
69
         * Also save the high level colors since two gx_color_index values
70
         * may be the same but for differing high level colors (due to the
71
         * usual lower resolution of the gx_color_index values.
72
         */
73
14.1M
        const gs_color_space * pcs = gs_currentcolorspace_inline(pgs);
74
14.1M
        int i = gs_color_space_num_components(pcs);
75
76
14.1M
        psc->color_space_id = pcs->id;
77
14.1M
        pdevc->type->save_dc(pdevc, &(psc->saved_dev_color));
78
14.1M
        if (pdevc->type == gx_dc_type_pattern2)
79
27.6k
            i = 0;
80
14.1M
        else if (i < 0)
81
52.1k
            i = -i - 1; /* See gx_num_components_Pattern. */
82
37.9M
        for (i--; i >= 0; i--)
83
23.8M
            psc->ccolor.paint.values[i] = pdevc->ccolor.paint.values[i];
84
85
        /* Save the pattern id - if present */
86
14.1M
        if ((pdevc->type == gx_dc_type_pattern
87
14.1M
           || pdevc->type == gx_dc_type_pattern2) && pdevc->ccolor_valid)
88
44.2k
            psc->pattern_id = pdevc->ccolor.pattern->pattern_id;
89
14.0M
        else
90
14.0M
            psc->pattern_id = gs_no_id;
91
14.1M
        return true;
92
14.1M
    }
93
88.7M
}
94
95
/*
96
 * Compare two saved colors to check if match.
97
 * This routine used to be a simple memcmp(), but
98
 * that is insufficient, the checks must be explicit.
99
 */
100
bool gx_hld_saved_color_equal(const gx_hl_saved_color * psc1,
101
                           const gx_hl_saved_color * psc2)
102
88.3M
{
103
104
88.3M
    int i;
105
106
88.3M
    if (psc1->saved_dev_color.type != psc2->saved_dev_color.type
107
88.3M
     || psc1->color_space_id != psc2->color_space_id
108
88.3M
     || psc1->pattern_id != psc2->pattern_id
109
88.3M
     || psc1->ccolor_valid != psc2->ccolor_valid
110
88.3M
     || psc1->ccolor.pattern != psc2->ccolor.pattern
111
88.3M
     || psc1->saved_dev_color.phase.x != psc2->saved_dev_color.phase.x
112
88.3M
     || psc1->saved_dev_color.phase.y != psc2->saved_dev_color.phase.y) {
113
114
1.07M
        return(false);
115
1.07M
    }
116
117
    /* early bailout for pattern comparison */
118
87.2M
    if (gx_dc_is_pattern1_color((gx_device_color *)(&psc1->saved_dev_color.type))) {
119
120
138
        if (psc1->saved_dev_color.colors.pattern.id != psc2->saved_dev_color.colors.pattern.id)
121
0
            return(false);
122
138
        else
123
138
            return true;
124
138
    }
125
87.2M
    if (gx_dc_is_pattern2_color((gx_device_color *)(&psc1->saved_dev_color.type))) {
126
21
        if (psc1->saved_dev_color.colors.pattern2.id != psc2->saved_dev_color.colors.pattern2.id
127
21
         || psc1->saved_dev_color.colors.pattern2.shfill != psc2->saved_dev_color.colors.pattern2.shfill)
128
0
            return(false);
129
21
        else
130
21
            return true;
131
21
    }
132
133
5.58G
    for (i = 0; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++) {
134
5.49G
        if (psc1->ccolor.paint.values[i] != psc2->ccolor.paint.values[i]) {
135
1.42M
            return(false);
136
1.42M
        }
137
5.49G
    }
138
    /* NAFF: only gx_dc_pure_masked doesn't have a type checker */
139
85.8M
    if (gx_dc_is_pure(&psc1->saved_dev_color) || psc1->saved_dev_color.type == &gx_dc_pure_masked) {
140
85.7M
        if (psc1->saved_dev_color.colors.pure != psc2->saved_dev_color.colors.pure) {
141
32.5M
            return(false);
142
32.5M
        }
143
85.7M
    }
144
93.9k
    else if (gx_dc_is_binary_halftone(&psc1->saved_dev_color)) {
145
146
0
        if ((psc1->saved_dev_color.colors.binary.b_color[0] != psc2->saved_dev_color.colors.binary.b_color[0])
147
0
             || (psc1->saved_dev_color.colors.binary.b_color[1] != psc2->saved_dev_color.colors.binary.b_color[1])
148
0
             || (psc1->saved_dev_color.colors.binary.b_level != psc2->saved_dev_color.colors.binary.b_level)
149
0
             || (psc1->saved_dev_color.colors.binary.b_index != psc2->saved_dev_color.colors.binary.b_index)) {
150
151
0
            return(false);
152
0
        }
153
0
    }
154
93.9k
    else if (gx_dc_is_colored_halftone(&psc1->saved_dev_color)) {
155
156
0
        for (i = 0; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++) {
157
0
            if (psc1->saved_dev_color.colors.colored.c_base[i] != psc2->saved_dev_color.colors.colored.c_base[i]
158
0
              || psc1->saved_dev_color.colors.colored.c_level[i] != psc2->saved_dev_color.colors.colored.c_level[i]) {
159
160
0
                return(false);
161
0
            }
162
0
        }
163
0
    }
164
93.9k
    else if (gx_dc_is_devn(&psc1->saved_dev_color)) {
165
166
0
        for (i = 0; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++) {
167
0
             if (psc1->saved_dev_color.colors.devn.values[i] != psc2->saved_dev_color.colors.devn.values[i]) {
168
169
0
                 return(false);
170
0
             }
171
0
        }
172
0
    }
173
174
53.2M
    return (true);
175
85.8M
}
176
177
/*
178
 * Check whether two saved colors have same color space.
179
 */
180
bool gx_hld_saved_color_same_cspace(const gx_hl_saved_color * psc1,
181
                           const gx_hl_saved_color * psc2)
182
51.8k
{
183
51.8k
    if (psc1->color_space_id != psc2->color_space_id)
184
33.6k
        return false;
185
18.2k
    if (psc1->pattern_id != psc2->pattern_id)
186
0
        return false;
187
18.2k
    if (psc1->ccolor_valid != psc2->ccolor_valid)
188
0
        return false;
189
18.2k
    if (psc1->color_space_id != psc2->color_space_id)
190
0
        return false;
191
18.2k
    return true;
192
18.2k
}
193
194
/*
195
 * Check if a high level color is availavble.
196
 */
197
bool
198
gx_hld_is_hl_color_available(const gs_gstate * pgs,
199
                const gx_device_color * pdevc)
200
5.13M
{
201
5.13M
    if (pgs != NULL && pdevc != NULL && pdevc->type != gx_dc_type_null && pdevc->ccolor_valid)
202
1.94M
        return true;
203
3.18M
    return false;
204
5.13M
}
205
206
/*
207
 * Get pointers to the current color space and client color.
208
 *
209
 * More description in src/gxhldevc.h
210
 */
211
gx_hld_get_color_space_and_ccolor_status
212
gx_hld_get_color_space_and_ccolor(const gs_gstate * pgs,
213
                const gx_device_color * pdevc, const gs_color_space ** ppcs,
214
                const gs_client_color ** ppcc)
215
2.27M
{
216
    /* Check if the current color space was used to build the device color */
217
2.27M
    if (gx_hld_is_hl_color_available(pgs, pdevc)) {
218
1.89M
        const gs_color_space * pcs = gs_currentcolorspace_inline(pgs);
219
220
1.89M
        *ppcs = pcs;
221
1.89M
        *ppcc = &(pdevc->ccolor);
222
1.89M
        if (pdevc->type == gx_dc_type_pattern
223
1.89M
           || pdevc->type == &gx_dc_pure_masked
224
1.89M
           || pdevc->type == gx_dc_type_pattern2)
225
22.1k
            return pattern_color_space;
226
1.87M
        else {
227
1.87M
            return non_pattern_color_space;
228
1.87M
        }
229
1.89M
    }
230
    /* No color space */
231
379k
    *ppcs = NULL;
232
379k
    *ppcc = NULL;
233
379k
    return use_process_color;
234
2.27M
}
235
236
/*
237
 * Get the number of components in the current color space.
238
 *
239
 * More description in src/gxhldevc.h
240
 */
241
int
242
gx_hld_get_number_color_components(const gs_gstate * pgs)
243
909k
{
244
909k
    if (pgs != NULL) {
245
909k
        const gs_color_space * pcs = gs_currentcolorspace_inline(pgs);
246
909k
        int n = gs_color_space_num_components(pcs);
247
248
909k
        return (n >= 0 ? n : -n - 1);
249
909k
    } else
250
0
        return -1;
251
909k
}
252
253
/*
254
 * Get the requested high level color value.
255
 *
256
 * More description in src/gxhldevc.h
257
 */
258
gx_hld_get_color_component_status
259
gx_hld_get_color_component(const gs_gstate * pgs,
260
                          const gx_device_color * pdevc,
261
                          int comp_num, float * output)
262
0
{
263
0
    if (pdevc != NULL && pdevc->ccolor_valid) {
264
0
        int ncomp = gx_hld_get_number_color_components(pgs);
265
266
0
        if (ncomp < 0)
267
0
            return invalid_color_info;
268
0
        if (comp_num < 0 || comp_num >= ncomp)
269
0
            return invalid_component_requested;
270
0
        *output = pdevc->ccolor.paint.values[comp_num];
271
0
        return valid_result;
272
0
    }
273
0
    return invalid_color_info;
274
0
}