Coverage Report

Created: 2026-02-14 07:09

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
4.85M
{
27
4.85M
    int k;
28
29
8.26M
    for (k = 0; k < num; k++) {
30
7.29M
        if (devn1[k] != devn2[k]) {
31
3.88M
            return true;
32
3.88M
        }
33
7.29M
    }
34
973k
    return false;
35
4.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
5.00M
{
42
5.00M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
43
5.00M
    frac31 curr[GX_DEVICE_COLOR_MAX_COMPONENTS];
44
5.00M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
45
5.00M
    int i, i1 = i0 + w, bi = i0, k;
46
5.00M
    const gx_device_color_info *cinfo = &dev->color_info;
47
5.00M
    int n = cinfo->num_components;
48
5.00M
    int si, ei, di, code;
49
5.00M
    gs_fixed_rect rect;
50
5.00M
    gx_device_color devc;
51
52
    /* Note: All the stepping math is done with frac color values */
53
54
5.00M
    devc.type = gx_dc_type_devn;
55
307M
    for (i = n; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
56
302M
         devc.colors.devn.values[i] = 0;
57
58
5.00M
    if (j < fixed2int(fa->clip->p.y) ||
59
5.00M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
60
0
        return 0;
61
22.3M
    for (k = 0; k < n; k++) {
62
17.3M
        curr[k] = c[k] = c0[k];
63
17.3M
        f[k] = c0f[k];
64
17.3M
    }
65
9.86M
    for (i = i0 + 1, di = 1; i < i1; i += di) {
66
4.85M
        if (di == 1) {
67
            /* Advance colors by 1 pixel. */
68
22.9M
            for (k = 0; k < n; k++) {
69
18.0M
                if (cg_num[k]) {
70
13.9M
                    int32_t m = f[k] + cg_num[k];
71
72
13.9M
                    c[k] += m / cg_den;
73
13.9M
                    m -= m / cg_den * cg_den;
74
13.9M
                    if (m < 0) {
75
6.28M
                        c[k]--;
76
6.28M
                        m += cg_den;
77
6.28M
                    }
78
13.9M
                    f[k] = m;
79
13.9M
                }
80
18.0M
            }
81
4.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
4.85M
        if (gx_devn_diff(c, curr, n)) {
99
3.88M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
100
3.88M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
101
3.88M
            if (si < ei) {
102
3.85M
                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
3.85M
                } else {
108
3.85M
                    rect.p.x = int2fixed(si);
109
3.85M
                    rect.p.y = int2fixed(j);
110
3.85M
                    rect.q.x = int2fixed(ei);
111
3.85M
                    rect.q.y = int2fixed(j + 1);
112
3.85M
                }
113
18.8M
                for (k = 0; k < n; k++) {
114
14.9M
                    devc.colors.devn.values[k] = frac312cv(curr[k]);
115
14.9M
                }
116
3.85M
                devc.tag = device_current_tag(dev);
117
3.85M
                code = dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
118
3.85M
                if (code < 0)
119
0
                    return code;
120
3.85M
            }
121
3.88M
            bi = i;
122
18.9M
            for (k = 0; k < n; k++) {
123
15.0M
                curr[k] = c[k];
124
15.0M
            }
125
3.88M
            di = 1;
126
3.88M
        } else if (i == i1) {
127
0
            i++;
128
0
            break;
129
973k
        } else {
130
            /* Compute a color change pixel analytically. */
131
973k
            di = i1 - i;
132
3.97M
            for (k = 0; k < n; k++) {
133
2.99M
                int32_t a;
134
2.99M
                int64_t x;
135
2.99M
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
136
2.99M
                frac31 u = c[k] & (v - 1);
137
138
2.99M
                if (cg_num[k] == 0) {
139
                    /* No change. */
140
2.99M
                    continue;
141
2.99M
                } 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
973k
        }
162
4.85M
    }
163
5.00M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
164
5.00M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
165
5.00M
    if (si < ei) {
166
4.84M
        if (fa->swap_axes) {
167
683k
            rect.p.x = int2fixed(j);
168
683k
            rect.p.y = int2fixed(si);
169
683k
            rect.q.x = int2fixed(j + 1);
170
683k
            rect.q.y = int2fixed(ei);
171
4.16M
        } else {
172
4.16M
            rect.p.x = int2fixed(si);
173
4.16M
            rect.p.y = int2fixed(j);
174
4.16M
            rect.q.x = int2fixed(ei);
175
4.16M
            rect.q.y = int2fixed(j + 1);
176
4.16M
        }
177
21.6M
        for (k = 0; k < n; k++) {
178
16.8M
            devc.colors.devn.values[k] = frac312cv(curr[k]);
179
16.8M
        }
180
4.84M
        devc.tag = device_current_tag(dev);
181
4.84M
        return dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
182
4.84M
    }
183
153k
    return 0;
184
5.00M
}
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
73.1M
{
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
73.1M
    bool devn = dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0);
199
73.1M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
200
73.1M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
201
73.1M
    int i, i1 = i0 + w, bi = i0, k;
202
73.1M
    gx_color_index ci0 = 0, ci1;
203
73.1M
    const gx_device_color_info *cinfo = &dev->color_info;
204
73.1M
    int n = cinfo->num_components;
205
73.1M
    int si, ei, di, code;
206
207
    /* Todo: set this up to vector earlier */
208
73.1M
    if (devn)  /* Note, PDF14 could be additive and doing devn */
209
5.00M
        return gx_hl_fill_linear_color_scanline(dev, fa, i0, j, w, c0, c0f,
210
5.00M
                                                cg_num, cg_den);
211
68.1M
    if (j < fixed2int(fa->clip->p.y) ||
212
68.1M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
213
0
        return 0;
214
235M
    for (k = 0; k < n; k++) {
215
167M
        int shift = cinfo->comp_shift[k];
216
167M
        int bits = cinfo->comp_bits[k];
217
218
167M
        c[k] = c0[k];
219
167M
        f[k] = c0f[k];
220
167M
        ci0 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
221
167M
    }
222
1.63G
    for (i = i0 + 1, di = 1; i < i1; i += di) {
223
1.56G
        if (di == 1) {
224
            /* Advance colors by 1 pixel. */
225
1.55G
            ci1 = 0;
226
5.53G
            for (k = 0; k < n; k++) {
227
3.98G
                int shift = cinfo->comp_shift[k];
228
3.98G
                int bits = cinfo->comp_bits[k];
229
230
3.98G
                if (cg_num[k]) {
231
2.16G
                    int32_t m = f[k] + cg_num[k];
232
233
2.16G
                    c[k] += m / cg_den;
234
2.16G
                    m -= m / cg_den * cg_den;
235
2.16G
                    if (m < 0) {
236
1.61G
                        c[k]--;
237
1.61G
                        m += cg_den;
238
1.61G
                    }
239
2.16G
                    f[k] = m;
240
2.16G
                }
241
3.98G
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
242
3.98G
            }
243
1.55G
        } else {
244
            /* Advance colors by di pixels. */
245
14.9M
            ci1 = 0;
246
54.1M
            for (k = 0; k < n; k++) {
247
39.1M
                int shift = cinfo->comp_shift[k];
248
39.1M
                int bits = cinfo->comp_bits[k];
249
250
39.1M
                if (cg_num[k]) {
251
15.0M
                    int64_t M = f[k] + (int64_t)cg_num[k] * di;
252
15.0M
                    int32_t m;
253
254
15.0M
                    c[k] += (frac31)(M / cg_den);
255
15.0M
                    m = (int32_t)(M - M / cg_den * cg_den);
256
15.0M
                    if (m < 0) {
257
0
                        c[k]--;
258
0
                        m += cg_den;
259
0
                    }
260
15.0M
                    f[k] = m;
261
15.0M
                }
262
39.1M
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
263
39.1M
            }
264
14.9M
        }
265
1.56G
        if (ci1 != ci0) {
266
83.6M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
267
83.6M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
268
83.6M
            if (si < ei) {
269
26.8M
                if (fa->swap_axes) {
270
0
                    code = dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
271
26.8M
                } else {
272
26.8M
                    code = dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
273
26.8M
                }
274
26.8M
                if (code < 0)
275
0
                    return code;
276
26.8M
            }
277
83.6M
            bi = i;
278
83.6M
            ci0 = ci1;
279
83.6M
            di = 1;
280
1.48G
        } else if (i == i1) {
281
0
            i++;
282
0
            break;
283
1.48G
        } else {
284
            /* Compute a color change pixel analitically. */
285
1.48G
            di = i1 - i;
286
2.61G
            for (k = 0; k < n; k++) {
287
2.58G
                int32_t a;
288
2.58G
                int64_t x;
289
2.58G
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
290
2.58G
                frac31 u = c[k] & (v - 1);
291
292
2.58G
                if (cg_num[k] == 0) {
293
                    /* No change. */
294
886M
                    continue;
295
1.69G
                } if (cg_num[k] > 0) {
296
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == v - u, x]  */
297
287M
                    a = v - u;
298
1.40G
                } else {
299
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == - u - 1, x]  */
300
1.40G
                    a = -u - 1;
301
1.40G
                }
302
1.69G
                x = ((int64_t)a * cg_den - f[k]) / cg_num[k];
303
1.69G
                if (i + x >= i1)
304
28.0M
                    continue;
305
1.66G
                else if (x < 0)
306
0
                    return_error(gs_error_unregistered); /* Must not happen. */
307
1.66G
                else if (di > (int)x) {
308
1.57G
                    di = (int)x;
309
1.57G
                    if (di <= 1) {
310
1.45G
                        di = 1;
311
1.45G
                        break;
312
1.45G
                    }
313
1.57G
                }
314
1.69G
            }
315
1.48G
        }
316
1.56G
    }
317
68.1M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
318
68.1M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
319
68.1M
    if (si < ei) {
320
58.7M
        if (fa->swap_axes) {
321
14.9M
            return dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
322
43.8M
        } else {
323
43.8M
            return dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
324
43.8M
        }
325
58.7M
    }
326
9.40M
    return 0;
327
68.1M
}