Coverage Report

Created: 2025-06-10 06:56

/src/ghostpdl/base/gdevm32.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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
/* 32-bit-per-pixel "memory" (stored bitmap) device */
17
#include "memory_.h"
18
#include "gx.h"
19
#include "gxdevice.h"
20
#include "gxdevmem.h"   /* semi-public definitions */
21
#include "gdevmem.h"    /* private definitions */
22
23
/* ================ Standard (byte-oriented) device ================ */
24
25
#undef chunk
26
#define chunk byte
27
28
/* Procedures */
29
declare_mem_procs(mem_true32_copy_mono, mem_true32_copy_color, mem_true32_fill_rectangle);
30
31
/* The device descriptor. */
32
const gx_device_memory mem_true32_device =
33
    mem_device("image32", 24, 8, mem_dev_initialize_device_procs);
34
35
const gdev_mem_functions gdev_mem_fns_32 =
36
{
37
    gx_default_map_rgb_color,
38
    gx_default_map_color_rgb,
39
    mem_true32_fill_rectangle,
40
    mem_true32_copy_mono,
41
    mem_true32_copy_color,
42
    gx_default_copy_alpha,
43
    gx_default_strip_tile_rectangle,
44
    mem_default_strip_copy_rop2,
45
    mem_get_bits_rectangle
46
};
47
48
/* Convert x coordinate to byte offset in scan line. */
49
#undef x_to_byte
50
0
#define x_to_byte(x) ((x) << 2)
51
52
/* Swap the bytes of a color if needed. */
53
#define color_swap_bytes(color)\
54
0
  ((((color) >> 24) & 0xff) + (((color) >> 8) & 0xff00) +\
55
0
   (((color) & 0xff00) << 8) + ((color) << 24))
56
#if ARCH_IS_BIG_ENDIAN
57
#  define arrange_bytes(color) (color)
58
#else
59
0
#  define arrange_bytes(color) color_swap_bytes(color)
60
#endif
61
62
/* Fill a rectangle with a color. */
63
static int
64
mem_true32_fill_rectangle(gx_device * dev,
65
                          int x, int y, int w, int h, gx_color_index color)
66
0
{
67
0
    gx_device_memory * const mdev = (gx_device_memory *)dev;
68
0
    bits32 a_color;
69
70
0
    declare_scan_ptr(dest);
71
72
0
    fit_fill(dev, x, y, w, h);
73
0
    a_color = arrange_bytes(color);
74
0
    setup_rect(dest);
75
0
    if (w <= 4)
76
0
        switch (w) {
77
                /*case 0: *//* not possible */
78
0
#define dest32 ((bits32 *)dest)
79
0
            case 1:
80
0
                do {
81
0
                    dest32[0] = a_color;
82
0
                    inc_ptr(dest, draster);
83
0
                }
84
0
                while (--h > 0);
85
0
                break;
86
0
            case 2:
87
0
                do {
88
0
                    dest32[1] = dest32[0] = a_color;
89
0
                    inc_ptr(dest, draster);
90
0
                }
91
0
                while (--h > 0);
92
0
                break;
93
0
            case 3:
94
0
                do {
95
0
                    dest32[2] = dest32[1] = dest32[0] = a_color;
96
0
                    inc_ptr(dest, draster);
97
0
                }
98
0
                while (--h > 0);
99
0
                break;
100
0
            case 4:
101
0
                do {
102
0
                    dest32[3] = dest32[2] = dest32[1] = dest32[0] = a_color;
103
0
                    inc_ptr(dest, draster);
104
0
                }
105
0
                while (--h > 0);
106
0
                break;
107
0
            default:    /* not possible */
108
0
                ;
109
0
    } else if (a_color == 0)
110
0
        do {
111
0
            memset(dest, 0, w << 2);
112
0
            inc_ptr(dest, draster);
113
0
        }
114
0
        while (--h > 0);
115
0
    else
116
0
        do {
117
0
            bits32 *pptr = dest32;
118
0
            int cnt = w;
119
120
0
            do {
121
0
                pptr[3] = pptr[2] = pptr[1] = pptr[0] = a_color;
122
0
                pptr += 4;
123
0
            }
124
0
            while ((cnt -= 4) > 4);
125
0
            do {
126
0
                *pptr++ = a_color;
127
0
            } while (--cnt > 0);
128
0
            inc_ptr(dest, draster);
129
0
        }
130
0
        while (--h > 0);
131
0
#undef dest32
132
0
    return 0;
133
0
}
134
135
/* Copy a monochrome bitmap. */
136
static int
137
mem_true32_copy_mono(gx_device * dev,
138
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
139
        int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
140
0
{
141
0
    gx_device_memory * const mdev = (gx_device_memory *)dev;
142
0
    bits32 a_zero = arrange_bytes(zero);
143
0
    bits32 a_one = arrange_bytes(one);
144
0
    const byte *line;
145
146
0
    declare_scan_ptr(dest);
147
0
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
148
0
    setup_rect(dest);
149
0
    line = base + (sourcex >> 3);
150
0
    if (zero == gx_no_color_index) {
151
0
        int first_bit = sourcex & 7;
152
0
        int w_first = min(w, 8 - first_bit);
153
0
        int w_rest = w - w_first;
154
155
0
        if (one == gx_no_color_index)
156
0
            return 0;
157
        /*
158
         * There are no halftones, so this case -- characters --
159
         * is the only common one.
160
         */
161
0
        while (h-- > 0) {
162
0
            bits32 *pptr = (bits32 *) dest;
163
0
            const byte *sptr = line;
164
0
            int sbyte = (*sptr++ << first_bit) & 0xff;
165
0
            int count = w_first;
166
167
0
#ifdef PACIFY_VALGRIND
168
0
      sbyte &= 0x100-(0x100>>w_first);
169
0
#endif
170
171
0
            if (sbyte)
172
0
                do {
173
0
                    if (sbyte & 0x80)
174
0
                        *pptr = a_one;
175
0
                    sbyte <<= 1;
176
0
                    pptr++;
177
0
                }
178
0
                while (--count > 0);
179
0
            else
180
0
                pptr += count;
181
0
            for (count = w_rest; count >= 8; count -= 8, pptr += 8) {
182
0
                sbyte = *sptr++;
183
0
                if (sbyte) {
184
0
                    if (sbyte & 0x80) pptr[0] = a_one;
185
0
                    if (sbyte & 0x40) pptr[1] = a_one;
186
0
                    if (sbyte & 0x20) pptr[2] = a_one;
187
0
                    if (sbyte & 0x10) pptr[3] = a_one;
188
0
                    if (sbyte & 0x08) pptr[4] = a_one;
189
0
                    if (sbyte & 0x04) pptr[5] = a_one;
190
0
                    if (sbyte & 0x02) pptr[6] = a_one;
191
0
                    if (sbyte & 0x01) pptr[7] = a_one;
192
0
                }
193
0
            }
194
0
            if (count) {
195
0
                sbyte = *sptr;
196
0
                do {
197
0
                    if (sbyte & 0x80)
198
0
                        *pptr = a_one;
199
0
                    sbyte <<= 1;
200
0
                    pptr++;
201
0
                }
202
0
                while (--count > 0);
203
0
            }
204
0
            line += sraster;
205
0
            inc_ptr(dest, draster);
206
0
        }
207
0
    } else {     /* zero != gx_no_color_index */
208
0
        int first_bit = 0x80 >> (sourcex & 7);
209
210
0
        while (h-- > 0) {
211
0
            bits32 *pptr = (bits32 *) dest;
212
0
            const byte *sptr = line;
213
0
            int sbyte = *sptr++;
214
0
            int bit = first_bit;
215
0
            int count = w;
216
217
0
            do {
218
0
                if (sbyte & bit) {
219
0
                    if (one != gx_no_color_index)
220
0
                        *pptr = a_one;
221
0
                } else
222
0
                    *pptr = a_zero;
223
0
                if ((bit >>= 1) == 0)
224
0
                    bit = 0x80, sbyte = *sptr++;
225
0
                pptr++;
226
0
            }
227
0
            while (--count > 0);
228
0
            line += sraster;
229
0
            inc_ptr(dest, draster);
230
0
        }
231
0
    }
232
0
    return 0;
233
0
}
234
235
/* Copy a color bitmap. */
236
static int
237
mem_true32_copy_color(gx_device * dev,
238
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
239
                      int x, int y, int w, int h)
240
0
{
241
0
    gx_device_memory * const mdev = (gx_device_memory *)dev;
242
243
0
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
244
0
    mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h);
245
0
    return 0;
246
0
}
247
248
/* ================ "Word"-oriented device ================ */
249
250
/* Note that on a big-endian machine, this is the same as the */
251
/* standard byte-oriented-device. */
252
253
#if !ARCH_IS_BIG_ENDIAN
254
255
/* Procedures */
256
declare_mem_procs(mem32_word_copy_mono, mem32_word_copy_color, mem32_word_fill_rectangle);
257
258
/* Here is the device descriptor. */
259
const gx_device_memory mem_true32_word_device =
260
    mem_device("image32w", 24, 8, mem_word_dev_initialize_device_procs);
261
262
const gdev_mem_functions gdev_mem_fns_32w =
263
{
264
    gx_default_map_rgb_color,
265
    gx_default_map_color_rgb,
266
    mem32_word_fill_rectangle,
267
    mem32_word_copy_mono,
268
    mem32_word_copy_color,
269
    gx_default_copy_alpha,
270
    gx_default_strip_tile_rectangle,
271
    gx_no_strip_copy_rop2,
272
    mem_word_get_bits_rectangle
273
};
274
275
/* Fill a rectangle with a color. */
276
static int
277
mem32_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
278
                          gx_color_index color)
279
0
{
280
0
    return mem_true32_fill_rectangle(dev, x, y, w, h,
281
0
                                     color_swap_bytes(color));
282
0
}
283
284
/* Copy a bitmap. */
285
static int
286
mem32_word_copy_mono(gx_device * dev,
287
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
288
        int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
289
0
{
290
0
    return mem_true32_copy_mono(dev, base, sourcex, sraster, id,
291
0
                                x, y, w, h, color_swap_bytes(zero),
292
0
                                color_swap_bytes(one));
293
0
}
294
295
/* Copy a color bitmap. */
296
static int
297
mem32_word_copy_color(gx_device * dev,
298
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
299
                      int x, int y, int w, int h)
300
0
{
301
0
    gx_device_memory * const mdev = (gx_device_memory *)dev;
302
0
    byte *row;
303
0
    size_t raster;
304
305
0
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
306
0
    row = scan_line_base(mdev, y);
307
0
    raster = mdev->raster;
308
0
    bytes_copy_rectangle(row + (x << 2), raster, base + (sourcex << 2),
309
0
                         sraster, w << 2, h);
310
0
    mem_swap_byte_rect(row, raster, x << 5, w << 5, h, false);
311
0
    return 0;
312
0
}
313
314
#endif /* !ARCH_IS_BIG_ENDIAN */