Coverage Report

Created: 2026-09-14 07:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gdevdsha.c
Line
Count
Source
1
/* Copyright (C) 2001-2025 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
/* Default shading drawing device procedures. */
17
18
#include "gx.h"
19
#include "gserrors.h"
20
#include "gxdevice.h"
21
#include "gxcindex.h"
22
#include "gxdevsop.h"
23
24
static bool
25
gx_devn_diff(frac31 devn1[], frac31 devn2[], int num)
26
6.18M
{
27
6.18M
    int k;
28
29
7.52M
    for (k = 0; k < num; k++) {
30
7.35M
        if (devn1[k] != devn2[k]) {
31
6.01M
            return true;
32
6.01M
        }
33
7.35M
    }
34
163k
    return false;
35
6.18M
}
36
37
int
38
gx_hl_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa,
39
        int i0, int j, int w, const frac31 *c0, const int32_t *c0f,
40
        const int32_t *cg_num, int32_t cg_den)
41
9.76M
{
42
9.76M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
43
9.76M
    frac31 curr[GX_DEVICE_COLOR_MAX_COMPONENTS];
44
9.76M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
45
9.76M
    int i, i1 = i0 + w, bi = i0, k;
46
9.76M
    const gx_device_color_info *cinfo = &dev->color_info;
47
9.76M
    int n = cinfo->num_components;
48
9.76M
    int si, ei, di, code;
49
9.76M
    gs_fixed_rect rect;
50
9.76M
    gx_device_color devc;
51
52
    /* Note: All the stepping math is done with frac color values */
53
54
9.76M
    devc.type = gx_dc_type_devn;
55
596M
    for (i = n; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
56
586M
         devc.colors.devn.values[i] = 0;
57
58
9.76M
    if (j < fixed2int(fa->clip->p.y) ||
59
9.76M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
60
0
        return 0;
61
48.3M
    for (k = 0; k < n; k++) {
62
38.5M
        curr[k] = c[k] = c0[k];
63
38.5M
        f[k] = c0f[k];
64
38.5M
    }
65
15.9M
    for (i = i0 + 1, di = 1; i < i1; i += di) {
66
6.18M
        if (di == 1) {
67
            /* Advance colors by 1 pixel. */
68
30.3M
            for (k = 0; k < n; k++) {
69
24.2M
                if (cg_num[k]) {
70
21.9M
                    int32_t m = f[k] + cg_num[k];
71
72
21.9M
                    c[k] += m / cg_den;
73
21.9M
                    m -= m / cg_den * cg_den;
74
21.9M
                    if (m < 0) {
75
8.24M
                        c[k]--;
76
8.24M
                        m += cg_den;
77
8.24M
                    }
78
21.9M
                    f[k] = m;
79
21.9M
                }
80
24.2M
            }
81
6.18M
        } else {
82
            /* Advance colors by di pixels. */
83
0
            for (k = 0; k < n; k++) {
84
0
                if (cg_num[k]) {
85
0
                    int64_t M = f[k] + (int64_t)cg_num[k] * di;
86
0
                    int32_t m;
87
88
0
                    c[k] += (frac31)(M / cg_den);
89
0
                    m = (int32_t)(M - M / cg_den * cg_den);
90
0
                    if (m < 0) {
91
0
                        c[k]--;
92
0
                        m += cg_den;
93
0
                    }
94
0
                    f[k] = m;
95
0
                }
96
0
            }
97
0
        }
98
6.18M
        if (gx_devn_diff(c, curr, n)) {
99
6.01M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
100
6.01M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
101
6.01M
            if (si < ei) {
102
5.78M
                if (fa->swap_axes) {
103
0
                    rect.p.x = int2fixed(j);
104
0
                    rect.p.y = int2fixed(si);
105
0
                    rect.q.x = int2fixed(j + 1);
106
0
                    rect.q.y = int2fixed(ei);
107
5.78M
                } else {
108
5.78M
                    rect.p.x = int2fixed(si);
109
5.78M
                    rect.p.y = int2fixed(j);
110
5.78M
                    rect.q.x = int2fixed(ei);
111
5.78M
                    rect.q.y = int2fixed(j + 1);
112
5.78M
                }
113
28.5M
                for (k = 0; k < n; k++) {
114
22.8M
                    devc.colors.devn.values[k] = frac312cv(curr[k]);
115
22.8M
                }
116
5.78M
                devc.tag = device_current_tag(dev);
117
5.78M
                code = dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
118
5.78M
                if (code < 0)
119
0
                    return code;
120
5.78M
            }
121
6.01M
            bi = i;
122
29.7M
            for (k = 0; k < n; k++) {
123
23.6M
                curr[k] = c[k];
124
23.6M
            }
125
6.01M
            di = 1;
126
6.01M
        } else if (i == i1) {
127
0
            i++;
128
0
            break;
129
163k
        } else {
130
            /* Compute a color change pixel analytically. */
131
163k
            di = i1 - i;
132
682k
            for (k = 0; k < n; k++) {
133
518k
                int32_t a;
134
518k
                int64_t x;
135
518k
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
136
518k
                frac31 u = c[k] & (v - 1);
137
138
518k
                if (cg_num[k] == 0) {
139
                    /* No change. */
140
518k
                    continue;
141
518k
                } if (cg_num[k] > 0) {
142
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == v - u, x]  */
143
0
                    a = v - u;
144
0
                } else {
145
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == - u - 1, x]  */
146
0
                    a = -u - 1;
147
0
                }
148
0
                x = ((int64_t)a * cg_den - f[k]) / cg_num[k];
149
0
                if (i + x >= i1)
150
0
                    continue;
151
0
                else if (x < 0)
152
0
                    return_error(gs_error_unregistered); /* Must not happen. */
153
0
                else if (di > (int)x) {
154
0
                    di = (int)x;
155
0
                    if (di <= 1) {
156
0
                        di = 1;
157
0
                        break;
158
0
                    }
159
0
                }
160
0
            }
161
163k
        }
162
6.18M
    }
163
9.76M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
164
9.76M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
165
9.76M
    if (si < ei) {
166
9.30M
        if (fa->swap_axes) {
167
724k
            rect.p.x = int2fixed(j);
168
724k
            rect.p.y = int2fixed(si);
169
724k
            rect.q.x = int2fixed(j + 1);
170
724k
            rect.q.y = int2fixed(ei);
171
8.57M
        } else {
172
8.57M
            rect.p.x = int2fixed(si);
173
8.57M
            rect.p.y = int2fixed(j);
174
8.57M
            rect.q.x = int2fixed(ei);
175
8.57M
            rect.q.y = int2fixed(j + 1);
176
8.57M
        }
177
46.0M
        for (k = 0; k < n; k++) {
178
36.7M
            devc.colors.devn.values[k] = frac312cv(curr[k]);
179
36.7M
        }
180
9.30M
        devc.tag = device_current_tag(dev);
181
9.30M
        return dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
182
9.30M
    }
183
462k
    return 0;
184
9.76M
}
185
186
int
187
gx_default_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa,
188
        int i0, int j, int w,
189
        const frac31 *c0, const int32_t *c0f, const int32_t *cg_num, int32_t cg_den)
190
57.4M
{
191
    /* This default implementation decomposes the area into constant color rectangles.
192
       Devices may supply optimized implementations with
193
       the inversed nesting of the i,k cicles,
194
       i.e. with enumerating planes first, with a direct writing to the raster,
195
       and with a fixed bits per component.
196
     */
197
    /* First determine if we are doing high level style colors or pure colors */
198
57.4M
    bool devn = dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0);
199
57.4M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
200
57.4M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
201
57.4M
    int i, i1 = i0 + w, bi = i0, k;
202
57.4M
    gx_color_index ci0 = 0, ci1;
203
57.4M
    const gx_device_color_info *cinfo = &dev->color_info;
204
57.4M
    int n = cinfo->num_components;
205
57.4M
    int si, ei, di, code;
206
207
    /* Todo: set this up to vector earlier */
208
57.4M
    if (devn)  /* Note, PDF14 could be additive and doing devn */
209
9.76M
        return gx_hl_fill_linear_color_scanline(dev, fa, i0, j, w, c0, c0f,
210
9.76M
                                                cg_num, cg_den);
211
47.6M
    if (j < fixed2int(fa->clip->p.y) ||
212
47.6M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
213
0
        return 0;
214
173M
    for (k = 0; k < n; k++) {
215
125M
        int shift = cinfo->comp_shift[k];
216
125M
        int bits = cinfo->comp_bits[k];
217
218
125M
        c[k] = c0[k];
219
125M
        f[k] = c0f[k];
220
125M
        ci0 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
221
125M
    }
222
1.36G
    for (i = i0 + 1, di = 1; i < i1; i += di) {
223
1.31G
        if (di == 1) {
224
            /* Advance colors by 1 pixel. */
225
1.30G
            ci1 = 0;
226
4.98G
            for (k = 0; k < n; k++) {
227
3.68G
                int shift = cinfo->comp_shift[k];
228
3.68G
                int bits = cinfo->comp_bits[k];
229
230
3.68G
                if (cg_num[k]) {
231
1.92G
                    int32_t m = f[k] + cg_num[k];
232
233
1.92G
                    c[k] += m / cg_den;
234
1.92G
                    m -= m / cg_den * cg_den;
235
1.92G
                    if (m < 0) {
236
1.37G
                        c[k]--;
237
1.37G
                        m += cg_den;
238
1.37G
                    }
239
1.92G
                    f[k] = m;
240
1.92G
                }
241
3.68G
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
242
3.68G
            }
243
1.30G
        } else {
244
            /* Advance colors by di pixels. */
245
12.4M
            ci1 = 0;
246
46.9M
            for (k = 0; k < n; k++) {
247
34.5M
                int shift = cinfo->comp_shift[k];
248
34.5M
                int bits = cinfo->comp_bits[k];
249
250
34.5M
                if (cg_num[k]) {
251
12.5M
                    int64_t M = f[k] + (int64_t)cg_num[k] * di;
252
12.5M
                    int32_t m;
253
254
12.5M
                    c[k] += (frac31)(M / cg_den);
255
12.5M
                    m = (int32_t)(M - M / cg_den * cg_den);
256
12.5M
                    if (m < 0) {
257
0
                        c[k]--;
258
0
                        m += cg_den;
259
0
                    }
260
12.5M
                    f[k] = m;
261
12.5M
                }
262
34.5M
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
263
34.5M
            }
264
12.4M
        }
265
1.31G
        if (ci1 != ci0) {
266
101M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
267
101M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
268
101M
            if (si < ei) {
269
50.3M
                if (fa->swap_axes) {
270
0
                    code = dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
271
50.3M
                } else {
272
50.3M
                    code = dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
273
50.3M
                }
274
50.3M
                if (code < 0)
275
0
                    return code;
276
50.3M
            }
277
101M
            bi = i;
278
101M
            ci0 = ci1;
279
101M
            di = 1;
280
1.21G
        } else if (i == i1) {
281
0
            i++;
282
0
            break;
283
1.21G
        } else {
284
            /* Compute a color change pixel analitically. */
285
1.21G
            di = i1 - i;
286
2.29G
            for (k = 0; k < n; k++) {
287
2.27G
                int32_t a;
288
2.27G
                int64_t x;
289
2.27G
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
290
2.27G
                frac31 u = c[k] & (v - 1);
291
292
2.27G
                if (cg_num[k] == 0) {
293
                    /* No change. */
294
861M
                    continue;
295
1.41G
                } if (cg_num[k] > 0) {
296
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == v - u, x]  */
297
278M
                    a = v - u;
298
1.13G
                } else {
299
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == - u - 1, x]  */
300
1.13G
                    a = -u - 1;
301
1.13G
                }
302
1.41G
                x = ((int64_t)a * cg_den - f[k]) / cg_num[k];
303
1.41G
                if (i + x >= i1)
304
18.3M
                    continue;
305
1.39G
                else if (x < 0)
306
0
                    return_error(gs_error_unregistered); /* Must not happen. */
307
1.39G
                else if (di > (int)x) {
308
1.31G
                    di = (int)x;
309
1.31G
                    if (di <= 1) {
310
1.19G
                        di = 1;
311
1.19G
                        break;
312
1.19G
                    }
313
1.31G
                }
314
1.41G
            }
315
1.21G
        }
316
1.31G
    }
317
47.6M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
318
47.6M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
319
47.6M
    if (si < ei) {
320
38.8M
        if (fa->swap_axes) {
321
14.5M
            return dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
322
24.2M
        } else {
323
24.2M
            return dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
324
24.2M
        }
325
38.8M
    }
326
8.80M
    return 0;
327
47.6M
}