Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/gxhldevc.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2021 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
/* 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
131k
{
37
131k
    gx_device_color temp_devc;
38
39
131k
    memset(psc, 0, sizeof(*psc)); /* clear the entire structure */
40
131k
    psc->color_space_id = psc->pattern_id = gs_no_id;
41
131k
    color_set_null(&temp_devc);
42
131k
    temp_devc.type->save_dc(&temp_devc, &(psc->saved_dev_color));
43
131k
}
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
51.4M
{
55
51.4M
    memset(psc, 0, sizeof(*psc)); /* clear the entire structure */
56
57
51.4M
    if (pdevc == NULL) {
58
        /* No device color given, should not happen */
59
38.2k
        gx_hld_saved_color_init(psc); /* revert to unknown color */
60
38.2k
        return false;
61
51.3M
    } else if (pgs == NULL) {
62
        /* No color space, simply save device color specific info */
63
46.7M
        psc->color_space_id = psc->pattern_id = gs_no_id;
64
46.7M
        pdevc->type->save_dc(pdevc, &(psc->saved_dev_color));
65
46.7M
        return false;
66
46.7M
    } 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
4.60M
        const gs_color_space * pcs = gs_currentcolorspace_inline(pgs);
74
4.60M
        int i = gs_color_space_num_components(pcs);
75
76
4.60M
        psc->color_space_id = pcs->id;
77
4.60M
        pdevc->type->save_dc(pdevc, &(psc->saved_dev_color));
78
4.60M
        if (pdevc->type == gx_dc_type_pattern2)
79
5.05k
            i = 0;
80
4.59M
        else if (i < 0)
81
4.72k
            i = -i - 1; /* See gx_num_components_Pattern. */
82
14.4M
        for (i--; i >= 0; i--)
83
9.87M
            psc->ccolor.paint.values[i] = pdevc->ccolor.paint.values[i];
84
85
        /* Save the pattern id - if present */
86
4.60M
        if ((pdevc->type == gx_dc_type_pattern
87
4.60M
           || pdevc->type == gx_dc_type_pattern2) && pdevc->ccolor_valid)
88
6.06k
            psc->pattern_id = pdevc->ccolor.pattern->pattern_id;
89
4.59M
        else
90
4.59M
            psc->pattern_id = gs_no_id;
91
4.60M
        return true;
92
4.60M
    }
93
51.4M
}
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
51.3M
{
103
104
51.3M
    int i;
105
106
51.3M
    if (psc1->saved_dev_color.type != psc2->saved_dev_color.type
107
51.3M
     || psc1->color_space_id != psc2->color_space_id
108
51.3M
     || psc1->pattern_id != psc2->pattern_id
109
51.3M
     || psc1->ccolor_valid != psc2->ccolor_valid
110
51.3M
     || psc1->ccolor.pattern != psc2->ccolor.pattern
111
51.3M
     || psc1->saved_dev_color.phase.x != psc2->saved_dev_color.phase.x
112
51.3M
     || psc1->saved_dev_color.phase.y != psc2->saved_dev_color.phase.y) {
113
114
513k
        return(false);
115
513k
    }
116
117
    /* early bailout for pattern comparison */
118
50.8M
    if (gx_dc_is_pattern1_color((gx_device_color *)(&psc1->saved_dev_color.type))) {
119
120
0
        if (psc1->saved_dev_color.colors.pattern.id != psc2->saved_dev_color.colors.pattern.id)
121
0
            return(false);
122
0
        else
123
0
            return true;
124
0
    }
125
50.8M
    if (gx_dc_is_pattern2_color((gx_device_color *)(&psc1->saved_dev_color.type))) {
126
30
        if (psc1->saved_dev_color.colors.pattern2.id != psc2->saved_dev_color.colors.pattern2.id
127
30
         || psc1->saved_dev_color.colors.pattern2.shfill != psc2->saved_dev_color.colors.pattern2.shfill)
128
0
            return(false);
129
30
        else
130
30
            return true;
131
30
    }
132
133
3.26G
    for (i = 0; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++) {
134
3.20G
        if (psc1->ccolor.paint.values[i] != psc2->ccolor.paint.values[i]) {
135
673k
            return(false);
136
673k
        }
137
3.20G
    }
138
    /* NAFF: only gx_dc_pure_masked doesn't have a type checker */
139
50.1M
    if (gx_dc_is_pure(&psc1->saved_dev_color) || psc1->saved_dev_color.type == &gx_dc_pure_masked) {
140
50.1M
        if (psc1->saved_dev_color.colors.pure != psc2->saved_dev_color.colors.pure) {
141
14.4M
            return(false);
142
14.4M
        }
143
50.1M
    }
144
0
    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
0
    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
0
    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
35.6M
    return (true);
175
50.1M
}
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
22.7k
{
183
22.7k
    if (psc1->color_space_id != psc2->color_space_id)
184
12.2k
        return false;
185
10.4k
    if (psc1->pattern_id != psc2->pattern_id)
186
0
        return false;
187
10.4k
    if (psc1->ccolor_valid != psc2->ccolor_valid)
188
0
        return false;
189
10.4k
    if (psc1->color_space_id != psc2->color_space_id)
190
0
        return false;
191
10.4k
    return true;
192
10.4k
}
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
1.42M
{
201
1.42M
    if (pgs != NULL && pdevc != NULL && pdevc->type != gx_dc_type_null && pdevc->ccolor_valid)
202
779k
        return true;
203
643k
    return false;
204
1.42M
}
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
759k
{
216
    /* Check if the current color space was used to build the device color */
217
759k
    if (gx_hld_is_hl_color_available(pgs, pdevc)) {
218
757k
        const gs_color_space * pcs = gs_currentcolorspace_inline(pgs);
219
220
757k
        *ppcs = pcs;
221
757k
        *ppcc = &(pdevc->ccolor);
222
757k
        if (pdevc->type == gx_dc_type_pattern
223
757k
           || pdevc->type == &gx_dc_pure_masked
224
757k
           || pdevc->type == gx_dc_type_pattern2)
225
3.01k
            return pattern_color_space;
226
754k
        else {
227
754k
            return non_pattern_color_space;
228
754k
        }
229
757k
    }
230
    /* No color space */
231
1.86k
    *ppcs = NULL;
232
1.86k
    *ppcc = NULL;
233
1.86k
    return use_process_color;
234
759k
}
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
499k
{
244
499k
    if (pgs != NULL) {
245
499k
        const gs_color_space * pcs = gs_currentcolorspace_inline(pgs);
246
499k
        int n = gs_color_space_num_components(pcs);
247
248
499k
        return (n >= 0 ? n : -n - 1);
249
499k
    } else
250
0
        return -1;
251
499k
}
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
}