Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/gdevdsha.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2021 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.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, 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
8.23M
{
27
8.23M
    int k;
28
29
11.2M
    for (k = 0; k < num; k++) {
30
10.9M
        if (devn1[k] != devn2[k]) {
31
7.92M
            return true;
32
7.92M
        }
33
10.9M
    }
34
313k
    return false;
35
8.23M
}
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.50M
{
42
2.50M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
43
2.50M
    frac31 curr[GX_DEVICE_COLOR_MAX_COMPONENTS];
44
2.50M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
45
2.50M
    int i, i1 = i0 + w, bi = i0, k;
46
2.50M
    const gx_device_color_info *cinfo = &dev->color_info;
47
2.50M
    int n = cinfo->num_components;
48
2.50M
    int si, ei, di, code;
49
2.50M
    gs_fixed_rect rect;
50
2.50M
    gx_device_color devc;
51
52
    /* Note: All the stepping math is done with frac color values */
53
54
2.50M
    devc.type = gx_dc_type_devn;
55
56
2.50M
    if (j < fixed2int(fa->clip->p.y) ||
57
2.50M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
58
0
        return 0;
59
11.1M
    for (k = 0; k < n; k++) {
60
8.62M
        curr[k] = c[k] = c0[k];
61
8.62M
        f[k] = c0f[k];
62
8.62M
    }
63
10.7M
    for (i = i0 + 1, di = 1; i < i1; i += di) {
64
8.23M
        if (di == 1) {
65
            /* Advance colors by 1 pixel. */
66
31.9M
            for (k = 0; k < n; k++) {
67
23.6M
                if (cg_num[k]) {
68
18.3M
                    int32_t m = f[k] + cg_num[k];
69
70
18.3M
                    c[k] += m / cg_den;
71
18.3M
                    m -= m / cg_den * cg_den;
72
18.3M
                    if (m < 0) {
73
8.79M
                        c[k]--;
74
8.79M
                        m += cg_den;
75
8.79M
                    }
76
18.3M
                    f[k] = m;
77
18.3M
                }
78
23.6M
            }
79
8.23M
        } 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
8.23M
        if (gx_devn_diff(c, curr, n)) {
97
7.92M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
98
7.92M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
99
7.92M
            if (si < ei) {
100
7.65M
                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
7.65M
                } else {
106
7.65M
                    rect.p.x = int2fixed(si);
107
7.65M
                    rect.p.y = int2fixed(j);
108
7.65M
                    rect.q.x = int2fixed(ei);
109
7.65M
                    rect.q.y = int2fixed(j + 1);
110
7.65M
                }
111
29.3M
                for (k = 0; k < n; k++) {
112
21.7M
                    devc.colors.devn.values[k] = frac312cv(curr[k]);
113
21.7M
                }
114
7.65M
                if (device_encodes_tags(dev)) {
115
0
                    devc.tag = (dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS);
116
7.65M
                } else {
117
7.65M
                    devc.tag = 0;
118
7.65M
                }
119
7.65M
                code = dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
120
7.65M
                if (code < 0)
121
0
                    return code;
122
7.65M
            }
123
7.92M
            bi = i;
124
30.6M
            for (k = 0; k < n; k++) {
125
22.6M
                curr[k] = c[k];
126
22.6M
            }
127
7.92M
            di = 1;
128
7.92M
        } else if (i == i1) {
129
0
            i++;
130
0
            break;
131
313k
        } else {
132
            /* Compute a color change pixel analytically. */
133
313k
            di = i1 - i;
134
1.30M
            for (k = 0; k < n; k++) {
135
991k
                int32_t a;
136
991k
                int64_t x;
137
991k
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
138
991k
                frac31 u = c[k] & (v - 1);
139
140
991k
                if (cg_num[k] == 0) {
141
                    /* No change. */
142
991k
                    continue;
143
991k
                } if (cg_num[k] > 0) {
144
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == v - u, x]  */
145
0
                    a = v - u;
146
0
                } else {
147
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == - u - 1, x]  */
148
0
                    a = -u - 1;
149
0
                }
150
0
                x = ((int64_t)a * cg_den - f[k]) / cg_num[k];
151
0
                if (i + x >= i1)
152
0
                    continue;
153
0
                else if (x < 0)
154
0
                    return_error(gs_error_unregistered); /* Must not happen. */
155
0
                else if (di > (int)x) {
156
0
                    di = (int)x;
157
0
                    if (di <= 1) {
158
0
                        di = 1;
159
0
                        break;
160
0
                    }
161
0
                }
162
0
            }
163
313k
        }
164
8.23M
    }
165
2.50M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
166
2.50M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
167
2.50M
    if (si < ei) {
168
2.27M
        if (fa->swap_axes) {
169
712k
            rect.p.x = int2fixed(j);
170
712k
            rect.p.y = int2fixed(si);
171
712k
            rect.q.x = int2fixed(j + 1);
172
712k
            rect.q.y = int2fixed(ei);
173
1.56M
        } else {
174
1.56M
            rect.p.x = int2fixed(si);
175
1.56M
            rect.p.y = int2fixed(j);
176
1.56M
            rect.q.x = int2fixed(ei);
177
1.56M
            rect.q.y = int2fixed(j + 1);
178
1.56M
        }
179
10.1M
        for (k = 0; k < n; k++) {
180
7.82M
            devc.colors.devn.values[k] = frac312cv(curr[k]);
181
7.82M
        }
182
2.27M
        if (device_encodes_tags(dev)) {
183
0
            devc.tag = (dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS);
184
2.27M
        } else {
185
2.27M
            devc.tag = 0;
186
2.27M
        }
187
2.27M
        return dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL);
188
2.27M
    }
189
226k
    return 0;
190
2.50M
}
191
192
int
193
gx_default_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa,
194
        int i0, int j, int w,
195
        const frac31 *c0, const int32_t *c0f, const int32_t *cg_num, int32_t cg_den)
196
11.9M
{
197
    /* This default implementation decomposes the area into constant color rectangles.
198
       Devices may supply optimized implementations with
199
       the inversed nesting of the i,k cicles,
200
       i.e. with enumerating planes first, with a direct writing to the raster,
201
       and with a fixed bits per component.
202
     */
203
    /* First determine if we are doing high level style colors or pure colors */
204
11.9M
    bool devn = dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0);
205
11.9M
    frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS];
206
11.9M
    ulong f[GX_DEVICE_COLOR_MAX_COMPONENTS];
207
11.9M
    int i, i1 = i0 + w, bi = i0, k;
208
11.9M
    gx_color_index ci0 = 0, ci1;
209
11.9M
    const gx_device_color_info *cinfo = &dev->color_info;
210
11.9M
    int n = cinfo->num_components;
211
11.9M
    int si, ei, di, code;
212
    /* If the device encodes tags, we expect the comp_shift[num_components] to be valid */
213
    /* for the tag part of the color (usually the high order bits of the color_index).  */
214
11.9M
    gx_color_index tag = device_encodes_tags(dev) ?
215
0
                         (gx_color_index)(dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS) << cinfo->comp_shift[n]
216
11.9M
                         : 0;
217
218
    /* Todo: set this up to vector earlier */
219
11.9M
    if (devn)  /* Note, PDF14 could be additive and doing devn */
220
2.50M
        return gx_hl_fill_linear_color_scanline(dev, fa, i0, j, w, c0, c0f,
221
2.50M
                                                cg_num, cg_den);
222
9.48M
    if (j < fixed2int(fa->clip->p.y) ||
223
9.48M
            j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
224
0
        return 0;
225
39.4M
    for (k = 0; k < n; k++) {
226
29.9M
        int shift = cinfo->comp_shift[k];
227
29.9M
        int bits = cinfo->comp_bits[k];
228
229
29.9M
        c[k] = c0[k];
230
29.9M
        f[k] = c0f[k];
231
29.9M
        ci0 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
232
29.9M
    }
233
47.0M
    for (i = i0 + 1, di = 1; i < i1; i += di) {
234
37.5M
        if (di == 1) {
235
            /* Advance colors by 1 pixel. */
236
37.2M
            ci1 = 0;
237
132M
            for (k = 0; k < n; k++) {
238
94.8M
                int shift = cinfo->comp_shift[k];
239
94.8M
                int bits = cinfo->comp_bits[k];
240
241
94.8M
                if (cg_num[k]) {
242
74.1M
                    int32_t m = f[k] + cg_num[k];
243
244
74.1M
                    c[k] += m / cg_den;
245
74.1M
                    m -= m / cg_den * cg_den;
246
74.1M
                    if (m < 0) {
247
39.3M
                        c[k]--;
248
39.3M
                        m += cg_den;
249
39.3M
                    }
250
74.1M
                    f[k] = m;
251
74.1M
                }
252
94.8M
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
253
94.8M
            }
254
37.2M
        } else {
255
            /* Advance colors by di pixels. */
256
385k
            ci1 = 0;
257
885k
            for (k = 0; k < n; k++) {
258
499k
                int shift = cinfo->comp_shift[k];
259
499k
                int bits = cinfo->comp_bits[k];
260
261
499k
                if (cg_num[k]) {
262
447k
                    int64_t M = f[k] + (int64_t)cg_num[k] * di;
263
447k
                    int32_t m;
264
265
447k
                    c[k] += (frac31)(M / cg_den);
266
447k
                    m = (int32_t)(M - M / cg_den * cg_den);
267
447k
                    if (m < 0) {
268
0
                        c[k]--;
269
0
                        m += cg_den;
270
0
                    }
271
447k
                    f[k] = m;
272
447k
                }
273
499k
                ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
274
499k
            }
275
385k
        }
276
37.5M
        if (ci1 != ci0) {
277
16.9M
            si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
278
16.9M
            ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
279
16.9M
            if (si < ei) {
280
16.6M
                ci0 |= tag;   /* set tag (may be 0 if the device doesn't use tags) */
281
16.6M
                if (fa->swap_axes) {
282
0
                    code = dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
283
16.6M
                } else {
284
16.6M
                    code = dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
285
16.6M
                }
286
16.6M
                if (code < 0)
287
0
                    return code;
288
16.6M
            }
289
16.9M
            bi = i;
290
16.9M
            ci0 = ci1;
291
16.9M
            di = 1;
292
20.6M
        } else if (i == i1) {
293
0
            i++;
294
0
            break;
295
20.6M
        } else {
296
            /* Compute a color change pixel analitically. */
297
20.6M
            di = i1 - i;
298
33.9M
            for (k = 0; k < n; k++) {
299
32.2M
                int32_t a;
300
32.2M
                int64_t x;
301
32.2M
                frac31 v = 1 << (31 - cinfo->comp_bits[k]); /* Color index precision in frac31. */
302
32.2M
                frac31 u = c[k] & (v - 1);
303
304
32.2M
                if (cg_num[k] == 0) {
305
                    /* No change. */
306
8.47M
                    continue;
307
23.7M
                } if (cg_num[k] > 0) {
308
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == v - u, x]  */
309
8.49M
                    a = v - u;
310
15.2M
                } else {
311
                    /* Solve[(f[k] + cg_num[k]*x)/cg_den == - u - 1, x]  */
312
15.2M
                    a = -u - 1;
313
15.2M
                }
314
23.7M
                x = ((int64_t)a * cg_den - f[k]) / cg_num[k];
315
23.7M
                if (i + x >= i1)
316
869k
                    continue;
317
22.9M
                else if (x < 0)
318
0
                    return_error(gs_error_unregistered); /* Must not happen. */
319
22.9M
                else if (di > (int)x) {
320
22.5M
                    di = (int)x;
321
22.5M
                    if (di <= 1) {
322
18.9M
                        di = 1;
323
18.9M
                        break;
324
18.9M
                    }
325
22.5M
                }
326
23.7M
            }
327
20.6M
        }
328
37.5M
    }
329
9.48M
    si = max(bi, fixed2int(fa->clip->p.x));     /* Must be compatible to the clipping logic. */
330
9.48M
    ei = min(i, fixed2int_ceiling(fa->clip->q.x));  /* Must be compatible to the clipping logic. */
331
9.48M
    if (si < ei) {
332
9.01M
        ci0 |= tag;   /* set tag (may be 0 if the device doesn't use tags) */
333
9.01M
        if (fa->swap_axes) {
334
3.22M
            return dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0);
335
5.79M
        } else {
336
5.79M
            return dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0);
337
5.79M
        }
338
9.01M
    }
339
466k
    return 0;
340
9.48M
}