Coverage Report

Created: 2025-08-28 07:06

/src/ghostpdl/base/gdevdsha.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2024 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
23.4M
{
27
23.4M
    int k;
28
29
39.0M
    for (k = 0; k < num; k++) {
30
38.0M
        if (devn1[k] != devn2[k]) {
31
22.5M
            return true;
32
22.5M
        }
33
38.0M
    }
34
952k
    return false;
35
23.4M
}
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
10.3M
{
42
10.3M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
43
10.3M
    frac31 curr[GX_DEVICE_COLOR_MAX_COMPONENTS];
44
10.3M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
45
10.3M
    int i, i1 = i0 + w, bi = i0, k;
46
10.3M
    const gx_device_color_info *cinfo = &dev->color_info;
47
10.3M
    int n = cinfo->num_components;
48
10.3M
    int si, ei, di, code;
49
10.3M
    gs_fixed_rect rect;
50
10.3M
    gx_device_color devc;
51
52
    /* Note: All the stepping math is done with frac color values */
53
54
10.3M
    devc.type = gx_dc_type_devn;
55
56
10.3M
    if (j < fixed2int(fa->clip->p.y) ||
57
10.3M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
58
0
        return 0;
59
48.1M
    for (k = 0; k < n; k++) {
60
37.8M
        curr[k] = c[k] = c0[k];
61
37.8M
        f[k] = c0f[k];
62
37.8M
    }
63
33.8M
    for (i = i0 + 1, di = 1; i < i1; i += di) {
64
23.4M
        if (di == 1) {
65
            /* Advance colors by 1 pixel. */
66
100M
            for (k = 0; k < n; k++) {
67
77.4M
                if (cg_num[k]) {
68
55.1M
                    int32_t m = f[k] + cg_num[k];
69
70
55.1M
                    c[k] += m / cg_den;
71
55.1M
                    m -= m / cg_den * cg_den;
72
55.1M
                    if (m < 0) {
73
25.5M
                        c[k]--;
74
25.5M
                        m += cg_den;
75
25.5M
                    }
76
55.1M
                    f[k] = m;
77
55.1M
                }
78
77.4M
            }
79
23.4M
        } else {
80
            /* Advance colors by di pixels. */
81
0
            for (k = 0; k < n; k++) {
82
0
                if (cg_num[k]) {
83
0
                    int64_t M = f[k] + (int64_t)cg_num[k] * di;
84
0
                    int32_t m;
85
86
0
                    c[k] += (frac31)(M / cg_den);
87
0
                    m = (int32_t)(M - M / cg_den * cg_den);
88
0
                    if (m < 0) {
89
0
                        c[k]--;
90
0
                        m += cg_den;
91
0
                    }
92
0
                    f[k] = m;
93
0
                }
94
0
            }
95
0
        }
96
23.4M
        if (gx_devn_diff(c, curr, n)) {
97
22.5M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
98
22.5M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
99
22.5M
            if (si < ei) {
100
21.3M
                if (fa->swap_axes) {
101
0
                    rect.p.x = int2fixed(j);
102
0
                    rect.p.y = int2fixed(si);
103
0
                    rect.q.x = int2fixed(j + 1);
104
0
                    rect.q.y = int2fixed(ei);
105
21.3M
                } else {
106
21.3M
                    rect.p.x = int2fixed(si);
107
21.3M
                    rect.p.y = int2fixed(j);
108
21.3M
                    rect.q.x = int2fixed(ei);
109
21.3M
                    rect.q.y = int2fixed(j + 1);
110
21.3M
                }
111
91.6M
                for (k = 0; k < n; k++) {
112
70.2M
                    devc.colors.devn.values[k] = frac312cv(curr[k]);
113
70.2M
                }
114
21.3M
                devc.tag = device_current_tag(dev);
115
21.3M
                code = dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
116
21.3M
                if (code < 0)
117
0
                    return code;
118
21.3M
            }
119
22.5M
            bi = i;
120
96.9M
            for (k = 0; k < n; k++) {
121
74.3M
                curr[k] = c[k];
122
74.3M
            }
123
22.5M
            di = 1;
124
22.5M
        } else if (i == i1) {
125
0
            i++;
126
0
            break;
127
952k
        } else {
128
            /* Compute a color change pixel analytically. */
129
952k
            di = i1 - i;
130
4.06M
            for (k = 0; k < n; k++) {
131
3.11M
                int32_t a;
132
3.11M
                int64_t x;
133
3.11M
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
134
3.11M
                frac31 u = c[k] & (v - 1);
135
136
3.11M
                if (cg_num[k] == 0) {
137
                    /* No change. */
138
3.11M
                    continue;
139
3.11M
                } if (cg_num[k] > 0) {
140
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == v - u, x]  */
141
0
                    a = v - u;
142
0
                } else {
143
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == - u - 1, x]  */
144
0
                    a = -u - 1;
145
0
                }
146
0
                x = ((int64_t)a * cg_den - f[k]) / cg_num[k];
147
0
                if (i + x >= i1)
148
0
                    continue;
149
0
                else if (x < 0)
150
0
                    return_error(gs_error_unregistered); /* Must not happen. */
151
0
                else if (di > (int)x) {
152
0
                    di = (int)x;
153
0
                    if (di <= 1) {
154
0
                        di = 1;
155
0
                        break;
156
0
                    }
157
0
                }
158
0
            }
159
952k
        }
160
23.4M
    }
161
10.3M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
162
10.3M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
163
10.3M
    if (si < ei) {
164
9.38M
        if (fa->swap_axes) {
165
2.51M
            rect.p.x = int2fixed(j);
166
2.51M
            rect.p.y = int2fixed(si);
167
2.51M
            rect.q.x = int2fixed(j + 1);
168
2.51M
            rect.q.y = int2fixed(ei);
169
6.87M
        } else {
170
6.87M
            rect.p.x = int2fixed(si);
171
6.87M
            rect.p.y = int2fixed(j);
172
6.87M
            rect.q.x = int2fixed(ei);
173
6.87M
            rect.q.y = int2fixed(j + 1);
174
6.87M
        }
175
43.7M
        for (k = 0; k < n; k++) {
176
34.3M
            devc.colors.devn.values[k] = frac312cv(curr[k]);
177
34.3M
        }
178
9.38M
        devc.tag = device_current_tag(dev);
179
9.38M
        return dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
180
9.38M
    }
181
950k
    return 0;
182
10.3M
}
183
184
int
185
gx_default_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa,
186
        int i0, int j, int w,
187
        const frac31 *c0, const int32_t *c0f, const int32_t *cg_num, int32_t cg_den)
188
138M
{
189
    /* This default implementation decomposes the area into constant color rectangles.
190
       Devices may supply optimized implementations with
191
       the inversed nesting of the i,k cicles,
192
       i.e. with enumerating planes first, with a direct writing to the raster,
193
       and with a fixed bits per component.
194
     */
195
    /* First determine if we are doing high level style colors or pure colors */
196
138M
    bool devn = dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0);
197
138M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
198
138M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
199
138M
    int i, i1 = i0 + w, bi = i0, k;
200
138M
    gx_color_index ci0 = 0, ci1;
201
138M
    const gx_device_color_info *cinfo = &dev->color_info;
202
138M
    int n = cinfo->num_components;
203
138M
    int si, ei, di, code;
204
205
    /* Todo: set this up to vector earlier */
206
138M
    if (devn)  /* Note, PDF14 could be additive and doing devn */
207
10.3M
        return gx_hl_fill_linear_color_scanline(dev, fa, i0, j, w, c0, c0f,
208
10.3M
                                                cg_num, cg_den);
209
127M
    if (j < fixed2int(fa->clip->p.y) ||
210
127M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
211
0
        return 0;
212
472M
    for (k = 0; k < n; k++) {
213
344M
        int shift = cinfo->comp_shift[k];
214
344M
        int bits = cinfo->comp_bits[k];
215
216
344M
        c[k] = c0[k];
217
344M
        f[k] = c0f[k];
218
344M
        ci0 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
219
344M
    }
220
3.40G
    for (i = i0 + 1, di = 1; i < i1; i += di) {
221
3.27G
        if (di == 1) {
222
            /* Advance colors by 1 pixel. */
223
3.24G
            ci1 = 0;
224
9.33G
            for (k = 0; k < n; k++) {
225
6.09G
                int shift = cinfo->comp_shift[k];
226
6.09G
                int bits = cinfo->comp_bits[k];
227
228
6.09G
                if (cg_num[k]) {
229
4.03G
                    int32_t m = f[k] + cg_num[k];
230
231
4.03G
                    c[k] += m / cg_den;
232
4.03G
                    m -= m / cg_den * cg_den;
233
4.03G
                    if (m < 0) {
234
3.28G
                        c[k]--;
235
3.28G
                        m += cg_den;
236
3.28G
                    }
237
4.03G
                    f[k] = m;
238
4.03G
                }
239
6.09G
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
240
6.09G
            }
241
3.24G
        } else {
242
            /* Advance colors by di pixels. */
243
33.2M
            ci1 = 0;
244
93.1M
            for (k = 0; k < n; k++) {
245
59.9M
                int shift = cinfo->comp_shift[k];
246
59.9M
                int bits = cinfo->comp_bits[k];
247
248
59.9M
                if (cg_num[k]) {
249
33.7M
                    int64_t M = f[k] + (int64_t)cg_num[k] * di;
250
33.7M
                    int32_t m;
251
252
33.7M
                    c[k] += (frac31)(M / cg_den);
253
33.7M
                    m = (int32_t)(M - M / cg_den * cg_den);
254
33.7M
                    if (m < 0) {
255
0
                        c[k]--;
256
0
                        m += cg_den;
257
0
                    }
258
33.7M
                    f[k] = m;
259
33.7M
                }
260
59.9M
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
261
59.9M
            }
262
33.2M
        }
263
3.27G
        if (ci1 != ci0) {
264
187M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
265
187M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
266
187M
            if (si < ei) {
267
106M
                if (fa->swap_axes) {
268
0
                    code = dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
269
106M
                } else {
270
106M
                    code = dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
271
106M
                }
272
106M
                if (code < 0)
273
0
                    return code;
274
106M
            }
275
187M
            bi = i;
276
187M
            ci0 = ci1;
277
187M
            di = 1;
278
3.08G
        } else if (i == i1) {
279
0
            i++;
280
0
            break;
281
3.08G
        } else {
282
            /* Compute a color change pixel analitically. */
283
3.08G
            di = i1 - i;
284
4.36G
            for (k = 0; k < n; k++) {
285
4.31G
                int32_t a;
286
4.31G
                int64_t x;
287
4.31G
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
288
4.31G
                frac31 u = c[k] & (v - 1);
289
290
4.31G
                if (cg_num[k] == 0) {
291
                    /* No change. */
292
981M
                    continue;
293
3.33G
                } if (cg_num[k] > 0) {
294
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == v - u, x]  */
295
374M
                    a = v - u;
296
2.95G
                } else {
297
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == - u - 1, x]  */
298
2.95G
                    a = -u - 1;
299
2.95G
                }
300
3.33G
                x = ((int64_t)a * cg_den - f[k]) / cg_num[k];
301
3.33G
                if (i + x >= i1)
302
31.8M
                    continue;
303
3.29G
                else if (x < 0)
304
0
                    return_error(gs_error_unregistered); /* Must not happen. */
305
3.29G
                else if (di > (int)x) {
306
3.20G
                    di = (int)x;
307
3.20G
                    if (di <= 1) {
308
3.03G
                        di = 1;
309
3.03G
                        break;
310
3.03G
                    }
311
3.20G
                }
312
3.33G
            }
313
3.08G
        }
314
3.27G
    }
315
127M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
316
127M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
317
127M
    if (si < ei) {
318
98.6M
        if (fa->swap_axes) {
319
33.1M
            return dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
320
65.5M
        } else {
321
65.5M
            return dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
322
65.5M
        }
323
98.6M
    }
324
29.2M
    return 0;
325
127M
}