Coverage Report

Created: 2026-04-09 07:06

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
9.85M
{
27
9.85M
    int k;
28
29
17.3M
    for (k = 0; k < num; k++) {
30
16.9M
        if (devn1[k] != devn2[k]) {
31
9.50M
            return true;
32
9.50M
        }
33
16.9M
    }
34
351k
    return false;
35
9.85M
}
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
11.3M
{
42
11.3M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
43
11.3M
    frac31 curr[GX_DEVICE_COLOR_MAX_COMPONENTS];
44
11.3M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
45
11.3M
    int i, i1 = i0 + w, bi = i0, k;
46
11.3M
    const gx_device_color_info *cinfo = &dev->color_info;
47
11.3M
    int n = cinfo->num_components;
48
11.3M
    int si, ei, di, code;
49
11.3M
    gs_fixed_rect rect;
50
11.3M
    gx_device_color devc;
51
52
    /* Note: All the stepping math is done with frac color values */
53
54
11.3M
    devc.type = gx_dc_type_devn;
55
695M
    for (i = n; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
56
684M
         devc.colors.devn.values[i] = 0;
57
58
11.3M
    if (j < fixed2int(fa->clip->p.y) ||
59
11.3M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
60
0
        return 0;
61
55.3M
    for (k = 0; k < n; k++) {
62
43.9M
        curr[k] = c[k] = c0[k];
63
43.9M
        f[k] = c0f[k];
64
43.9M
    }
65
21.2M
    for (i = i0 + 1, di = 1; i < i1; i += di) {
66
9.85M
        if (di == 1) {
67
            /* Advance colors by 1 pixel. */
68
43.1M
            for (k = 0; k < n; k++) {
69
33.2M
                if (cg_num[k]) {
70
24.8M
                    int32_t m = f[k] + cg_num[k];
71
72
24.8M
                    c[k] += m / cg_den;
73
24.8M
                    m -= m / cg_den * cg_den;
74
24.8M
                    if (m < 0) {
75
8.93M
                        c[k]--;
76
8.93M
                        m += cg_den;
77
8.93M
                    }
78
24.8M
                    f[k] = m;
79
24.8M
                }
80
33.2M
            }
81
9.85M
        } 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
9.85M
        if (gx_devn_diff(c, curr, n)) {
99
9.50M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
100
9.50M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
101
9.50M
            if (si < ei) {
102
8.84M
                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
8.84M
                } else {
108
8.84M
                    rect.p.x = int2fixed(si);
109
8.84M
                    rect.p.y = int2fixed(j);
110
8.84M
                    rect.q.x = int2fixed(ei);
111
8.84M
                    rect.q.y = int2fixed(j + 1);
112
8.84M
                }
113
38.7M
                for (k = 0; k < n; k++) {
114
29.8M
                    devc.colors.devn.values[k] = frac312cv(curr[k]);
115
29.8M
                }
116
8.84M
                devc.tag = device_current_tag(dev);
117
8.84M
                code = dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
118
8.84M
                if (code < 0)
119
0
                    return code;
120
8.84M
            }
121
9.50M
            bi = i;
122
41.6M
            for (k = 0; k < n; k++) {
123
32.1M
                curr[k] = c[k];
124
32.1M
            }
125
9.50M
            di = 1;
126
9.50M
        } else if (i == i1) {
127
0
            i++;
128
0
            break;
129
351k
        } else {
130
            /* Compute a color change pixel analytically. */
131
351k
            di = i1 - i;
132
1.43M
            for (k = 0; k < n; k++) {
133
1.08M
                int32_t a;
134
1.08M
                int64_t x;
135
1.08M
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
136
1.08M
                frac31 u = c[k] & (v - 1);
137
138
1.08M
                if (cg_num[k] == 0) {
139
                    /* No change. */
140
1.08M
                    continue;
141
1.08M
                } 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
351k
        }
162
9.85M
    }
163
11.3M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
164
11.3M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
165
11.3M
    if (si < ei) {
166
10.6M
        if (fa->swap_axes) {
167
1.14M
            rect.p.x = int2fixed(j);
168
1.14M
            rect.p.y = int2fixed(si);
169
1.14M
            rect.q.x = int2fixed(j + 1);
170
1.14M
            rect.q.y = int2fixed(ei);
171
9.50M
        } else {
172
9.50M
            rect.p.x = int2fixed(si);
173
9.50M
            rect.p.y = int2fixed(j);
174
9.50M
            rect.q.x = int2fixed(ei);
175
9.50M
            rect.q.y = int2fixed(j + 1);
176
9.50M
        }
177
51.7M
        for (k = 0; k < n; k++) {
178
41.1M
            devc.colors.devn.values[k] = frac312cv(curr[k]);
179
41.1M
        }
180
10.6M
        devc.tag = device_current_tag(dev);
181
10.6M
        return dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
182
10.6M
    }
183
738k
    return 0;
184
11.3M
}
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
76.7M
{
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
76.7M
    bool devn = dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0);
199
76.7M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
200
76.7M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
201
76.7M
    int i, i1 = i0 + w, bi = i0, k;
202
76.7M
    gx_color_index ci0 = 0, ci1;
203
76.7M
    const gx_device_color_info *cinfo = &dev->color_info;
204
76.7M
    int n = cinfo->num_components;
205
76.7M
    int si, ei, di, code;
206
207
    /* Todo: set this up to vector earlier */
208
76.7M
    if (devn)  /* Note, PDF14 could be additive and doing devn */
209
11.3M
        return gx_hl_fill_linear_color_scanline(dev, fa, i0, j, w, c0, c0f,
210
11.3M
                                                cg_num, cg_den);
211
65.3M
    if (j < fixed2int(fa->clip->p.y) ||
212
65.3M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
213
0
        return 0;
214
238M
    for (k = 0; k < n; k++) {
215
173M
        int shift = cinfo->comp_shift[k];
216
173M
        int bits = cinfo->comp_bits[k];
217
218
173M
        c[k] = c0[k];
219
173M
        f[k] = c0f[k];
220
173M
        ci0 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
221
173M
    }
222
1.46G
    for (i = i0 + 1, di = 1; i < i1; i += di) {
223
1.39G
        if (di == 1) {
224
            /* Advance colors by 1 pixel. */
225
1.38G
            ci1 = 0;
226
4.98G
            for (k = 0; k < n; k++) {
227
3.60G
                int shift = cinfo->comp_shift[k];
228
3.60G
                int bits = cinfo->comp_bits[k];
229
230
3.60G
                if (cg_num[k]) {
231
1.96G
                    int32_t m = f[k] + cg_num[k];
232
233
1.96G
                    c[k] += m / cg_den;
234
1.96G
                    m -= m / cg_den * cg_den;
235
1.96G
                    if (m < 0) {
236
1.44G
                        c[k]--;
237
1.44G
                        m += cg_den;
238
1.44G
                    }
239
1.96G
                    f[k] = m;
240
1.96G
                }
241
3.60G
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
242
3.60G
            }
243
1.38G
        } else {
244
            /* Advance colors by di pixels. */
245
13.8M
            ci1 = 0;
246
49.8M
            for (k = 0; k < n; k++) {
247
35.9M
                int shift = cinfo->comp_shift[k];
248
35.9M
                int bits = cinfo->comp_bits[k];
249
250
35.9M
                if (cg_num[k]) {
251
14.0M
                    int64_t M = f[k] + (int64_t)cg_num[k] * di;
252
14.0M
                    int32_t m;
253
254
14.0M
                    c[k] += (frac31)(M / cg_den);
255
14.0M
                    m = (int32_t)(M - M / cg_den * cg_den);
256
14.0M
                    if (m < 0) {
257
0
                        c[k]--;
258
0
                        m += cg_den;
259
0
                    }
260
14.0M
                    f[k] = m;
261
14.0M
                }
262
35.9M
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
263
35.9M
            }
264
13.8M
        }
265
1.39G
        if (ci1 != ci0) {
266
103M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
267
103M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
268
103M
            if (si < ei) {
269
53.0M
                if (fa->swap_axes) {
270
0
                    code = dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
271
53.0M
                } else {
272
53.0M
                    code = dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
273
53.0M
                }
274
53.0M
                if (code < 0)
275
0
                    return code;
276
53.0M
            }
277
103M
            bi = i;
278
103M
            ci0 = ci1;
279
103M
            di = 1;
280
1.29G
        } else if (i == i1) {
281
0
            i++;
282
0
            break;
283
1.29G
        } else {
284
            /* Compute a color change pixel analitically. */
285
1.29G
            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
793M
                    continue;
295
1.47G
                } if (cg_num[k] > 0) {
296
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == v - u, x]  */
297
262M
                    a = v - u;
298
1.21G
                } else {
299
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == - u - 1, x]  */
300
1.21G
                    a = -u - 1;
301
1.21G
                }
302
1.47G
                x = ((int64_t)a * cg_den - f[k]) / cg_num[k];
303
1.47G
                if (i + x >= i1)
304
15.5M
                    continue;
305
1.46G
                else if (x < 0)
306
0
                    return_error(gs_error_unregistered); /* Must not happen. */
307
1.46G
                else if (di > (int)x) {
308
1.38G
                    di = (int)x;
309
1.38G
                    if (di <= 1) {
310
1.27G
                        di = 1;
311
1.27G
                        break;
312
1.27G
                    }
313
1.38G
                }
314
1.47G
            }
315
1.29G
        }
316
1.39G
    }
317
65.3M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
318
65.3M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
319
65.3M
    if (si < ei) {
320
54.2M
        if (fa->swap_axes) {
321
20.5M
            return dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
322
33.6M
        } else {
323
33.6M
            return dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
324
33.6M
        }
325
54.2M
    }
326
11.0M
    return 0;
327
65.3M
}