Coverage Report

Created: 2026-04-01 07:17

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
7.19M
{
27
7.19M
    int k;
28
29
8.46M
    for (k = 0; k < num; k++) {
30
8.26M
        if (devn1[k] != devn2[k]) {
31
6.98M
            return true;
32
6.98M
        }
33
8.26M
    }
34
203k
    return false;
35
7.19M
}
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
2.27M
{
42
2.27M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
43
2.27M
    frac31 curr[GX_DEVICE_COLOR_MAX_COMPONENTS];
44
2.27M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
45
2.27M
    int i, i1 = i0 + w, bi = i0, k;
46
2.27M
    const gx_device_color_info *cinfo = &dev->color_info;
47
2.27M
    int n = cinfo->num_components;
48
2.27M
    int si, ei, di, code;
49
2.27M
    gs_fixed_rect rect;
50
2.27M
    gx_device_color devc;
51
52
    /* Note: All the stepping math is done with frac color values */
53
54
2.27M
    devc.type = gx_dc_type_devn;
55
139M
    for (i = n; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
56
136M
         devc.colors.devn.values[i] = 0;
57
58
2.27M
    if (j < fixed2int(fa->clip->p.y) ||
59
2.27M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
60
0
        return 0;
61
10.8M
    for (k = 0; k < n; k++) {
62
8.57M
        curr[k] = c[k] = c0[k];
63
8.57M
        f[k] = c0f[k];
64
8.57M
    }
65
9.46M
    for (i = i0 + 1, di = 1; i < i1; i += di) {
66
7.19M
        if (di == 1) {
67
            /* Advance colors by 1 pixel. */
68
34.0M
            for (k = 0; k < n; k++) {
69
26.8M
                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
9.85M
                        c[k]--;
76
9.85M
                        m += cg_den;
77
9.85M
                    }
78
21.9M
                    f[k] = m;
79
21.9M
                }
80
26.8M
            }
81
7.19M
        } 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
7.19M
        if (gx_devn_diff(c, curr, n)) {
99
6.98M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
100
6.98M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
101
6.98M
            if (si < ei) {
102
6.88M
                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
6.88M
                } else {
108
6.88M
                    rect.p.x = int2fixed(si);
109
6.88M
                    rect.p.y = int2fixed(j);
110
6.88M
                    rect.q.x = int2fixed(ei);
111
6.88M
                    rect.q.y = int2fixed(j + 1);
112
6.88M
                }
113
32.7M
                for (k = 0; k < n; k++) {
114
25.8M
                    devc.colors.devn.values[k] = frac312cv(curr[k]);
115
25.8M
                }
116
6.88M
                devc.tag = device_current_tag(dev);
117
6.88M
                code = dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
118
6.88M
                if (code < 0)
119
0
                    return code;
120
6.88M
            }
121
6.98M
            bi = i;
122
33.2M
            for (k = 0; k < n; k++) {
123
26.2M
                curr[k] = c[k];
124
26.2M
            }
125
6.98M
            di = 1;
126
6.98M
        } else if (i == i1) {
127
0
            i++;
128
0
            break;
129
203k
        } else {
130
            /* Compute a color change pixel analytically. */
131
203k
            di = i1 - i;
132
872k
            for (k = 0; k < n; k++) {
133
669k
                int32_t a;
134
669k
                int64_t x;
135
669k
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
136
669k
                frac31 u = c[k] & (v - 1);
137
138
669k
                if (cg_num[k] == 0) {
139
                    /* No change. */
140
669k
                    continue;
141
669k
                } 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
203k
        }
162
7.19M
    }
163
2.27M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
164
2.27M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
165
2.27M
    if (si < ei) {
166
2.11M
        if (fa->swap_axes) {
167
570k
            rect.p.x = int2fixed(j);
168
570k
            rect.p.y = int2fixed(si);
169
570k
            rect.q.x = int2fixed(j + 1);
170
570k
            rect.q.y = int2fixed(ei);
171
1.54M
        } else {
172
1.54M
            rect.p.x = int2fixed(si);
173
1.54M
            rect.p.y = int2fixed(j);
174
1.54M
            rect.q.x = int2fixed(ei);
175
1.54M
            rect.q.y = int2fixed(j + 1);
176
1.54M
        }
177
10.1M
        for (k = 0; k < n; k++) {
178
8.00M
            devc.colors.devn.values[k] = frac312cv(curr[k]);
179
8.00M
        }
180
2.11M
        devc.tag = device_current_tag(dev);
181
2.11M
        return dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
182
2.11M
    }
183
156k
    return 0;
184
2.27M
}
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
46.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
46.5M
    bool devn = dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0);
199
46.5M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
200
46.5M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
201
46.5M
    int i, i1 = i0 + w, bi = i0, k;
202
46.5M
    gx_color_index ci0 = 0, ci1;
203
46.5M
    const gx_device_color_info *cinfo = &dev->color_info;
204
46.5M
    int n = cinfo->num_components;
205
46.5M
    int si, ei, di, code;
206
207
    /* Todo: set this up to vector earlier */
208
46.5M
    if (devn)  /* Note, PDF14 could be additive and doing devn */
209
2.27M
        return gx_hl_fill_linear_color_scanline(dev, fa, i0, j, w, c0, c0f,
210
2.27M
                                                cg_num, cg_den);
211
44.2M
    if (j < fixed2int(fa->clip->p.y) ||
212
44.2M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
213
0
        return 0;
214
156M
    for (k = 0; k < n; k++) {
215
112M
        int shift = cinfo->comp_shift[k];
216
112M
        int bits = cinfo->comp_bits[k];
217
218
112M
        c[k] = c0[k];
219
112M
        f[k] = c0f[k];
220
112M
        ci0 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
221
112M
    }
222
1.33G
    for (i = i0 + 1, di = 1; i < i1; i += di) {
223
1.29G
        if (di == 1) {
224
            /* Advance colors by 1 pixel. */
225
1.27G
            ci1 = 0;
226
4.83G
            for (k = 0; k < n; k++) {
227
3.55G
                int shift = cinfo->comp_shift[k];
228
3.55G
                int bits = cinfo->comp_bits[k];
229
230
3.55G
                if (cg_num[k]) {
231
1.87G
                    int32_t m = f[k] + cg_num[k];
232
233
1.87G
                    c[k] += m / cg_den;
234
1.87G
                    m -= m / cg_den * cg_den;
235
1.87G
                    if (m < 0) {
236
1.35G
                        c[k]--;
237
1.35G
                        m += cg_den;
238
1.35G
                    }
239
1.87G
                    f[k] = m;
240
1.87G
                }
241
3.55G
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
242
3.55G
            }
243
1.27G
        } else {
244
            /* Advance colors by di pixels. */
245
12.8M
            ci1 = 0;
246
48.0M
            for (k = 0; k < n; k++) {
247
35.1M
                int shift = cinfo->comp_shift[k];
248
35.1M
                int bits = cinfo->comp_bits[k];
249
250
35.1M
                if (cg_num[k]) {
251
13.0M
                    int64_t M = f[k] + (int64_t)cg_num[k] * di;
252
13.0M
                    int32_t m;
253
254
13.0M
                    c[k] += (frac31)(M / cg_den);
255
13.0M
                    m = (int32_t)(M - M / cg_den * cg_den);
256
13.0M
                    if (m < 0) {
257
0
                        c[k]--;
258
0
                        m += cg_den;
259
0
                    }
260
13.0M
                    f[k] = m;
261
13.0M
                }
262
35.1M
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
263
35.1M
            }
264
12.8M
        }
265
1.29G
        if (ci1 != ci0) {
266
95.2M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
267
95.2M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
268
95.2M
            if (si < ei) {
269
45.1M
                if (fa->swap_axes) {
270
0
                    code = dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
271
45.1M
                } else {
272
45.1M
                    code = dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
273
45.1M
                }
274
45.1M
                if (code < 0)
275
0
                    return code;
276
45.1M
            }
277
95.2M
            bi = i;
278
95.2M
            ci0 = ci1;
279
95.2M
            di = 1;
280
1.19G
        } else if (i == i1) {
281
0
            i++;
282
0
            break;
283
1.19G
        } else {
284
            /* Compute a color change pixel analitically. */
285
1.19G
            di = i1 - i;
286
2.22G
            for (k = 0; k < n; k++) {
287
2.20G
                int32_t a;
288
2.20G
                int64_t x;
289
2.20G
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
290
2.20G
                frac31 u = c[k] & (v - 1);
291
292
2.20G
                if (cg_num[k] == 0) {
293
                    /* No change. */
294
806M
                    continue;
295
1.39G
                } if (cg_num[k] > 0) {
296
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == v - u, x]  */
297
271M
                    a = v - u;
298
1.12G
                } else {
299
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == - u - 1, x]  */
300
1.12G
                    a = -u - 1;
301
1.12G
                }
302
1.39G
                x = ((int64_t)a * cg_den - f[k]) / cg_num[k];
303
1.39G
                if (i + x >= i1)
304
16.3M
                    continue;
305
1.38G
                else if (x < 0)
306
0
                    return_error(gs_error_unregistered); /* Must not happen. */
307
1.38G
                else if (di > (int)x) {
308
1.30G
                    di = (int)x;
309
1.30G
                    if (di <= 1) {
310
1.17G
                        di = 1;
311
1.17G
                        break;
312
1.17G
                    }
313
1.30G
                }
314
1.39G
            }
315
1.19G
        }
316
1.29G
    }
317
44.2M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
318
44.2M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
319
44.2M
    if (si < ei) {
320
36.0M
        if (fa->swap_axes) {
321
15.3M
            return dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
322
20.7M
        } else {
323
20.7M
            return dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
324
20.7M
        }
325
36.0M
    }
326
8.21M
    return 0;
327
44.2M
}