Coverage Report

Created: 2025-06-24 07:01

/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
18.6M
{
27
18.6M
    int k;
28
29
30.2M
    for (k = 0; k < num; k++) {
30
29.4M
        if (devn1[k] != devn2[k]) {
31
17.9M
            return true;
32
17.9M
        }
33
29.4M
    }
34
758k
    return false;
35
18.6M
}
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
7.86M
{
42
7.86M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
43
7.86M
    frac31 curr[GX_DEVICE_COLOR_MAX_COMPONENTS];
44
7.86M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
45
7.86M
    int i, i1 = i0 + w, bi = i0, k;
46
7.86M
    const gx_device_color_info *cinfo = &dev->color_info;
47
7.86M
    int n = cinfo->num_components;
48
7.86M
    int si, ei, di, code;
49
7.86M
    gs_fixed_rect rect;
50
7.86M
    gx_device_color devc;
51
52
    /* Note: All the stepping math is done with frac color values */
53
54
7.86M
    devc.type = gx_dc_type_devn;
55
56
7.86M
    if (j < fixed2int(fa->clip->p.y) ||
57
7.86M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
58
0
        return 0;
59
36.5M
    for (k = 0; k < n; k++) {
60
28.6M
        curr[k] = c[k] = c0[k];
61
28.6M
        f[k] = c0f[k];
62
28.6M
    }
63
26.5M
    for (i = i0 + 1, di = 1; i < i1; i += di) {
64
18.6M
        if (di == 1) {
65
            /* Advance colors by 1 pixel. */
66
78.4M
            for (k = 0; k < n; k++) {
67
59.7M
                if (cg_num[k]) {
68
41.7M
                    int32_t m = f[k] + cg_num[k];
69
70
41.7M
                    c[k] += m / cg_den;
71
41.7M
                    m -= m / cg_den * cg_den;
72
41.7M
                    if (m < 0) {
73
18.8M
                        c[k]--;
74
18.8M
                        m += cg_den;
75
18.8M
                    }
76
41.7M
                    f[k] = m;
77
41.7M
                }
78
59.7M
            }
79
18.6M
        } 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
18.6M
        if (gx_devn_diff(c, curr, n)) {
97
17.9M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
98
17.9M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
99
17.9M
            if (si < ei) {
100
16.9M
                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
16.9M
                } else {
106
16.9M
                    rect.p.x = int2fixed(si);
107
16.9M
                    rect.p.y = int2fixed(j);
108
16.9M
                    rect.q.x = int2fixed(ei);
109
16.9M
                    rect.q.y = int2fixed(j + 1);
110
16.9M
                }
111
70.9M
                for (k = 0; k < n; k++) {
112
53.9M
                    devc.colors.devn.values[k] = frac312cv(curr[k]);
113
53.9M
                }
114
16.9M
                devc.tag = device_current_tag(dev);
115
16.9M
                code = dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
116
16.9M
                if (code < 0)
117
0
                    return code;
118
16.9M
            }
119
17.9M
            bi = i;
120
75.1M
            for (k = 0; k < n; k++) {
121
57.2M
                curr[k] = c[k];
122
57.2M
            }
123
17.9M
            di = 1;
124
17.9M
        } else if (i == i1) {
125
0
            i++;
126
0
            break;
127
758k
        } else {
128
            /* Compute a color change pixel analytically. */
129
758k
            di = i1 - i;
130
3.28M
            for (k = 0; k < n; k++) {
131
2.52M
                int32_t a;
132
2.52M
                int64_t x;
133
2.52M
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
134
2.52M
                frac31 u = c[k] & (v - 1);
135
136
2.52M
                if (cg_num[k] == 0) {
137
                    /* No change. */
138
2.52M
                    continue;
139
2.52M
                } 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
758k
        }
160
18.6M
    }
161
7.86M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
162
7.86M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
163
7.86M
    if (si < ei) {
164
7.10M
        if (fa->swap_axes) {
165
1.86M
            rect.p.x = int2fixed(j);
166
1.86M
            rect.p.y = int2fixed(si);
167
1.86M
            rect.q.x = int2fixed(j + 1);
168
1.86M
            rect.q.y = int2fixed(ei);
169
5.24M
        } else {
170
5.24M
            rect.p.x = int2fixed(si);
171
5.24M
            rect.p.y = int2fixed(j);
172
5.24M
            rect.q.x = int2fixed(ei);
173
5.24M
            rect.q.y = int2fixed(j + 1);
174
5.24M
        }
175
33.0M
        for (k = 0; k < n; k++) {
176
25.9M
            devc.colors.devn.values[k] = frac312cv(curr[k]);
177
25.9M
        }
178
7.10M
        devc.tag = device_current_tag(dev);
179
7.10M
        return dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
180
7.10M
    }
181
754k
    return 0;
182
7.86M
}
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
130M
{
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
130M
    bool devn = dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0);
197
130M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
198
130M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
199
130M
    int i, i1 = i0 + w, bi = i0, k;
200
130M
    gx_color_index ci0 = 0, ci1;
201
130M
    const gx_device_color_info *cinfo = &dev->color_info;
202
130M
    int n = cinfo->num_components;
203
130M
    int si, ei, di, code;
204
205
    /* Todo: set this up to vector earlier */
206
130M
    if (devn)  /* Note, PDF14 could be additive and doing devn */
207
7.86M
        return gx_hl_fill_linear_color_scanline(dev, fa, i0, j, w, c0, c0f,
208
7.86M
                                                cg_num, cg_den);
209
123M
    if (j < fixed2int(fa->clip->p.y) ||
210
123M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
211
0
        return 0;
212
467M
    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
2.78G
    for (i = i0 + 1, di = 1; i < i1; i += di) {
221
2.65G
        if (di == 1) {
222
            /* Advance colors by 1 pixel. */
223
2.63G
            ci1 = 0;
224
8.59G
            for (k = 0; k < n; k++) {
225
5.96G
                int shift = cinfo->comp_shift[k];
226
5.96G
                int bits = cinfo->comp_bits[k];
227
228
5.96G
                if (cg_num[k]) {
229
3.62G
                    int32_t m = f[k] + cg_num[k];
230
231
3.62G
                    c[k] += m / cg_den;
232
3.62G
                    m -= m / cg_den * cg_den;
233
3.62G
                    if (m < 0) {
234
2.75G
                        c[k]--;
235
2.75G
                        m += cg_den;
236
2.75G
                    }
237
3.62G
                    f[k] = m;
238
3.62G
                }
239
5.96G
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
240
5.96G
            }
241
2.63G
        } else {
242
            /* Advance colors by di pixels. */
243
25.5M
            ci1 = 0;
244
81.5M
            for (k = 0; k < n; k++) {
245
55.9M
                int shift = cinfo->comp_shift[k];
246
55.9M
                int bits = cinfo->comp_bits[k];
247
248
55.9M
                if (cg_num[k]) {
249
26.0M
                    int64_t M = f[k] + (int64_t)cg_num[k] * di;
250
26.0M
                    int32_t m;
251
252
26.0M
                    c[k] += (frac31)(M / cg_den);
253
26.0M
                    m = (int32_t)(M - M / cg_den * cg_den);
254
26.0M
                    if (m < 0) {
255
0
                        c[k]--;
256
0
                        m += cg_den;
257
0
                    }
258
26.0M
                    f[k] = m;
259
26.0M
                }
260
55.9M
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
261
55.9M
            }
262
25.5M
        }
263
2.65G
        if (ci1 != ci0) {
264
184M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
265
184M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
266
184M
            if (si < ei) {
267
108M
                if (fa->swap_axes) {
268
0
                    code = dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
269
108M
                } else {
270
108M
                    code = dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
271
108M
                }
272
108M
                if (code < 0)
273
0
                    return code;
274
108M
            }
275
184M
            bi = i;
276
184M
            ci0 = ci1;
277
184M
            di = 1;
278
2.47G
        } else if (i == i1) {
279
0
            i++;
280
0
            break;
281
2.47G
        } else {
282
            /* Compute a color change pixel analitically. */
283
2.47G
            di = i1 - i;
284
3.94G
            for (k = 0; k < n; k++) {
285
3.90G
                int32_t a;
286
3.90G
                int64_t x;
287
3.90G
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
288
3.90G
                frac31 u = c[k] & (v - 1);
289
290
3.90G
                if (cg_num[k] == 0) {
291
                    /* No change. */
292
1.12G
                    continue;
293
2.77G
                } if (cg_num[k] > 0) {
294
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == v - u, x]  */
295
424M
                    a = v - u;
296
2.35G
                } else {
297
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == - u - 1, x]  */
298
2.35G
                    a = -u - 1;
299
2.35G
                }
300
2.77G
                x = ((int64_t)a * cg_den - f[k]) / cg_num[k];
301
2.77G
                if (i + x >= i1)
302
39.0M
                    continue;
303
2.74G
                else if (x < 0)
304
0
                    return_error(gs_error_unregistered); /* Must not happen. */
305
2.74G
                else if (di > (int)x) {
306
2.62G
                    di = (int)x;
307
2.62G
                    if (di <= 1) {
308
2.43G
                        di = 1;
309
2.43G
                        break;
310
2.43G
                    }
311
2.62G
                }
312
2.77G
            }
313
2.47G
        }
314
2.65G
    }
315
123M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
316
123M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
317
123M
    if (si < ei) {
318
99.0M
        if (fa->swap_axes) {
319
31.3M
            return dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
320
67.7M
        } else {
321
67.7M
            return dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
322
67.7M
        }
323
99.0M
    }
324
24.0M
    return 0;
325
123M
}