Coverage Report

Created: 2026-07-24 07:44

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.72M
{
27
9.72M
    int k;
28
29
11.3M
    for (k = 0; k < num; k++) {
30
11.1M
        if (devn1[k] != devn2[k]) {
31
9.51M
            return true;
32
9.51M
        }
33
11.1M
    }
34
216k
    return false;
35
9.72M
}
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.0M
{
42
10.0M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
43
10.0M
    frac31 curr[GX_DEVICE_COLOR_MAX_COMPONENTS];
44
10.0M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
45
10.0M
    int i, i1 = i0 + w, bi = i0, k;
46
10.0M
    const gx_device_color_info *cinfo = &dev->color_info;
47
10.0M
    int n = cinfo->num_components;
48
10.0M
    int si, ei, di, code;
49
10.0M
    gs_fixed_rect rect;
50
10.0M
    gx_device_color devc;
51
52
    /* Note: All the stepping math is done with frac color values */
53
54
10.0M
    devc.type = gx_dc_type_devn;
55
615M
    for (i = n; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
56
605M
         devc.colors.devn.values[i] = 0;
57
58
10.0M
    if (j < fixed2int(fa->clip->p.y) ||
59
10.0M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
60
0
        return 0;
61
49.8M
    for (k = 0; k < n; k++) {
62
39.7M
        curr[k] = c[k] = c0[k];
63
39.7M
        f[k] = c0f[k];
64
39.7M
    }
65
19.8M
    for (i = i0 + 1, di = 1; i < i1; i += di) {
66
9.72M
        if (di == 1) {
67
            /* Advance colors by 1 pixel. */
68
46.6M
            for (k = 0; k < n; k++) {
69
36.9M
                if (cg_num[k]) {
70
31.6M
                    int32_t m = f[k] + cg_num[k];
71
72
31.6M
                    c[k] += m / cg_den;
73
31.6M
                    m -= m / cg_den * cg_den;
74
31.6M
                    if (m < 0) {
75
12.9M
                        c[k]--;
76
12.9M
                        m += cg_den;
77
12.9M
                    }
78
31.6M
                    f[k] = m;
79
31.6M
                }
80
36.9M
            }
81
9.72M
        } 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.72M
        if (gx_devn_diff(c, curr, n)) {
99
9.51M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
100
9.51M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
101
9.51M
            if (si < ei) {
102
9.25M
                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
9.25M
                } else {
108
9.25M
                    rect.p.x = int2fixed(si);
109
9.25M
                    rect.p.y = int2fixed(j);
110
9.25M
                    rect.q.x = int2fixed(ei);
111
9.25M
                    rect.q.y = int2fixed(j + 1);
112
9.25M
                }
113
44.5M
                for (k = 0; k < n; k++) {
114
35.2M
                    devc.colors.devn.values[k] = frac312cv(curr[k]);
115
35.2M
                }
116
9.25M
                devc.tag = device_current_tag(dev);
117
9.25M
                code = dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
118
9.25M
                if (code < 0)
119
0
                    return code;
120
9.25M
            }
121
9.51M
            bi = i;
122
45.7M
            for (k = 0; k < n; k++) {
123
36.2M
                curr[k] = c[k];
124
36.2M
            }
125
9.51M
            di = 1;
126
9.51M
        } else if (i == i1) {
127
0
            i++;
128
0
            break;
129
216k
        } else {
130
            /* Compute a color change pixel analytically. */
131
216k
            di = i1 - i;
132
936k
            for (k = 0; k < n; k++) {
133
720k
                int32_t a;
134
720k
                int64_t x;
135
720k
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
136
720k
                frac31 u = c[k] & (v - 1);
137
138
720k
                if (cg_num[k] == 0) {
139
                    /* No change. */
140
720k
                    continue;
141
720k
                } 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
216k
        }
162
9.72M
    }
163
10.0M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
164
10.0M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
165
10.0M
    if (si < ei) {
166
9.56M
        if (fa->swap_axes) {
167
779k
            rect.p.x = int2fixed(j);
168
779k
            rect.p.y = int2fixed(si);
169
779k
            rect.q.x = int2fixed(j + 1);
170
779k
            rect.q.y = int2fixed(ei);
171
8.78M
        } else {
172
8.78M
            rect.p.x = int2fixed(si);
173
8.78M
            rect.p.y = int2fixed(j);
174
8.78M
            rect.q.x = int2fixed(ei);
175
8.78M
            rect.q.y = int2fixed(j + 1);
176
8.78M
        }
177
47.3M
        for (k = 0; k < n; k++) {
178
37.7M
            devc.colors.devn.values[k] = frac312cv(curr[k]);
179
37.7M
        }
180
9.56M
        devc.tag = device_current_tag(dev);
181
9.56M
        return dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
182
9.56M
    }
183
516k
    return 0;
184
10.0M
}
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
51.5M
{
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
51.5M
    bool devn = dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0);
199
51.5M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
200
51.5M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
201
51.5M
    int i, i1 = i0 + w, bi = i0, k;
202
51.5M
    gx_color_index ci0 = 0, ci1;
203
51.5M
    const gx_device_color_info *cinfo = &dev->color_info;
204
51.5M
    int n = cinfo->num_components;
205
51.5M
    int si, ei, di, code;
206
207
    /* Todo: set this up to vector earlier */
208
51.5M
    if (devn)  /* Note, PDF14 could be additive and doing devn */
209
10.0M
        return gx_hl_fill_linear_color_scanline(dev, fa, i0, j, w, c0, c0f,
210
10.0M
                                                cg_num, cg_den);
211
41.4M
    if (j < fixed2int(fa->clip->p.y) ||
212
41.4M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
213
0
        return 0;
214
148M
    for (k = 0; k < n; k++) {
215
107M
        int shift = cinfo->comp_shift[k];
216
107M
        int bits = cinfo->comp_bits[k];
217
218
107M
        c[k] = c0[k];
219
107M
        f[k] = c0f[k];
220
107M
        ci0 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
221
107M
    }
222
1.20G
    for (i = i0 + 1, di = 1; i < i1; i += di) {
223
1.16G
        if (di == 1) {
224
            /* Advance colors by 1 pixel. */
225
1.15G
            ci1 = 0;
226
4.41G
            for (k = 0; k < n; k++) {
227
3.26G
                int shift = cinfo->comp_shift[k];
228
3.26G
                int bits = cinfo->comp_bits[k];
229
230
3.26G
                if (cg_num[k]) {
231
1.70G
                    int32_t m = f[k] + cg_num[k];
232
233
1.70G
                    c[k] += m / cg_den;
234
1.70G
                    m -= m / cg_den * cg_den;
235
1.70G
                    if (m < 0) {
236
1.22G
                        c[k]--;
237
1.22G
                        m += cg_den;
238
1.22G
                    }
239
1.70G
                    f[k] = m;
240
1.70G
                }
241
3.26G
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
242
3.26G
            }
243
1.15G
        } else {
244
            /* Advance colors by di pixels. */
245
11.0M
            ci1 = 0;
246
41.8M
            for (k = 0; k < n; k++) {
247
30.7M
                int shift = cinfo->comp_shift[k];
248
30.7M
                int bits = cinfo->comp_bits[k];
249
250
30.7M
                if (cg_num[k]) {
251
11.1M
                    int64_t M = f[k] + (int64_t)cg_num[k] * di;
252
11.1M
                    int32_t m;
253
254
11.1M
                    c[k] += (frac31)(M / cg_den);
255
11.1M
                    m = (int32_t)(M - M / cg_den * cg_den);
256
11.1M
                    if (m < 0) {
257
0
                        c[k]--;
258
0
                        m += cg_den;
259
0
                    }
260
11.1M
                    f[k] = m;
261
11.1M
                }
262
30.7M
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
263
30.7M
            }
264
11.0M
        }
265
1.16G
        if (ci1 != ci0) {
266
85.3M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
267
85.3M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
268
85.3M
            if (si < ei) {
269
37.8M
                if (fa->swap_axes) {
270
0
                    code = dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
271
37.8M
                } else {
272
37.8M
                    code = dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
273
37.8M
                }
274
37.8M
                if (code < 0)
275
0
                    return code;
276
37.8M
            }
277
85.3M
            bi = i;
278
85.3M
            ci0 = ci1;
279
85.3M
            di = 1;
280
1.07G
        } else if (i == i1) {
281
0
            i++;
282
0
            break;
283
1.07G
        } else {
284
            /* Compute a color change pixel analitically. */
285
1.07G
            di = i1 - i;
286
2.04G
            for (k = 0; k < n; k++) {
287
2.02G
                int32_t a;
288
2.02G
                int64_t x;
289
2.02G
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
290
2.02G
                frac31 u = c[k] & (v - 1);
291
292
2.02G
                if (cg_num[k] == 0) {
293
                    /* No change. */
294
764M
                    continue;
295
1.26G
                } if (cg_num[k] > 0) {
296
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == v - u, x]  */
297
244M
                    a = v - u;
298
1.01G
                } else {
299
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == - u - 1, x]  */
300
1.01G
                    a = -u - 1;
301
1.01G
                }
302
1.26G
                x = ((int64_t)a * cg_den - f[k]) / cg_num[k];
303
1.26G
                if (i + x >= i1)
304
14.1M
                    continue;
305
1.24G
                else if (x < 0)
306
0
                    return_error(gs_error_unregistered); /* Must not happen. */
307
1.24G
                else if (di > (int)x) {
308
1.17G
                    di = (int)x;
309
1.17G
                    if (di <= 1) {
310
1.06G
                        di = 1;
311
1.06G
                        break;
312
1.06G
                    }
313
1.17G
                }
314
1.26G
            }
315
1.07G
        }
316
1.16G
    }
317
41.4M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
318
41.4M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
319
41.4M
    if (si < ei) {
320
33.7M
        if (fa->swap_axes) {
321
12.8M
            return dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
322
20.9M
        } else {
323
20.9M
            return dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
324
20.9M
        }
325
33.7M
    }
326
7.66M
    return 0;
327
41.4M
}