Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/base/gdevm16.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
/* 16-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
#undef chunk
24
#define chunk byte
25
26
/* The 16 bits are divided 5 for red, 6 for green, and 5 for blue. */
27
/* Note that the bits must always be kept in big-endian order. */
28
29
/* Procedures */
30
declare_mem_map_procs(mem_true16_map_rgb_color, mem_true16_map_color_rgb);
31
declare_mem_procs(mem_true16_copy_mono, mem_true16_copy_color, mem_true16_fill_rectangle);
32
33
/* The device descriptor. */
34
const gx_device_memory mem_true16_device =
35
    mem_device("image16", 16, 0, mem_dev_initialize_device_procs);
36
37
const gdev_mem_functions gdev_mem_fns_16 =
38
{
39
    mem_true16_map_rgb_color,
40
    mem_true16_map_color_rgb,
41
    mem_true16_fill_rectangle,
42
    mem_true16_copy_mono,
43
    mem_true16_copy_color,
44
    gx_default_copy_alpha,
45
    gx_default_strip_tile_rectangle,
46
    mem_default_strip_copy_rop2,
47
    mem_get_bits_rectangle
48
};
49
50
/* Map a r-g-b color to a color index. */
51
static gx_color_index
52
mem_true16_map_rgb_color(gx_device * dev, const gx_color_value cv[])
53
0
{
54
0
    return ((cv[0] >> (gx_color_value_bits - 5)) << 11) +
55
0
        ((cv[1] >> (gx_color_value_bits - 6)) << 5) +
56
0
        (cv[2] >> (gx_color_value_bits - 5));
57
0
}
58
59
/* Map a color index to a r-g-b color. */
60
static int
61
mem_true16_map_color_rgb(gx_device * dev, gx_color_index color,
62
                         gx_color_value prgb[3])
63
0
{
64
0
    ushort value = color >> 11;
65
66
0
    prgb[0] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4))
67
0
                      >> (16 - gx_color_value_bits);
68
0
    value = (color >> 5) & 0x3f;
69
0
    prgb[1] = ((value << 10) + (value << 4) + (value >> 2))
70
0
                      >> (16 - gx_color_value_bits);
71
0
    value = color & 0x1f;
72
0
    prgb[2] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4))
73
0
                      >> (16 - gx_color_value_bits);
74
0
    return 0;
75
0
}
76
77
/* Convert x coordinate to byte offset in scan line. */
78
#undef x_to_byte
79
0
#define x_to_byte(x) ((x) << 1)
80
81
/* Fill a rectangle with a color. */
82
static int
83
mem_true16_fill_rectangle(gx_device * dev,
84
                          int x, int y, int w, int h, gx_color_index color)
85
0
{
86
0
    gx_device_memory * const mdev = (gx_device_memory *)dev;
87
#if ARCH_IS_BIG_ENDIAN
88
    const ushort color16 = (ushort)color;
89
#else
90
0
    const ushort color16 = (ushort)((color << 8) | (color >> 8));
91
0
#endif
92
0
    declare_scan_ptr(dest);
93
94
0
    fit_fill(dev, x, y, w, h);
95
0
    setup_rect(dest);
96
0
    if (w == 1) {
97
0
        while (h-- > 0) {
98
0
            *(ushort *)dest = color16;
99
0
            inc_ptr(dest, draster);
100
0
        }
101
0
    } else if ((color16 >> 8) == (color16 & 0xff)) {
102
0
        bytes_fill_rectangle(scan_line_base(mdev, y) + (x << 1), draster,
103
0
                             (byte)color, w << 1, h);
104
0
    } else {
105
0
        while (h-- > 0) {
106
0
            ushort *pptr = (ushort *) dest;
107
0
            int cnt = w;
108
109
0
            for (; cnt >= 4; pptr += 4, cnt -= 4)
110
0
                pptr[3] = pptr[2] = pptr[1] = pptr[0] = color16;
111
0
            switch (cnt) {
112
0
            case 3: pptr[2] = color16;
113
0
            case 2: pptr[1] = color16;
114
0
            case 1: pptr[0] = color16;
115
0
            case 0: DO_NOTHING;
116
0
            }
117
0
            inc_ptr(dest, draster);
118
0
        }
119
0
    }
120
0
    return 0;
121
0
}
122
123
/* Copy a monochrome bitmap. */
124
static int
125
mem_true16_copy_mono(gx_device * dev,
126
                     const byte * base, int sourcex, int sraster,
127
                     gx_bitmap_id id, int x, int y, int w, int h,
128
                     gx_color_index zero, gx_color_index one)
129
0
{
130
0
    gx_device_memory * const mdev = (gx_device_memory *)dev;
131
#if ARCH_IS_BIG_ENDIAN
132
    const ushort zero16 = (ushort)zero;
133
    const ushort one16 = (ushort)one;
134
#else
135
0
    ushort zero16 = ((uint) (byte) zero << 8) + ((ushort) zero >> 8);
136
0
    ushort one16 = ((uint) (byte) one << 8) + ((ushort) one >> 8);
137
0
#endif
138
0
    const byte *line;
139
0
    int first_bit;
140
141
0
    declare_scan_ptr(dest);
142
0
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
143
0
    setup_rect(dest);
144
0
    line = base + (sourcex >> 3);
145
0
    first_bit = 0x80 >> (sourcex & 7);
146
0
    while (h-- > 0) {
147
0
        register ushort *pptr = (ushort *) dest;
148
0
        const byte *sptr = line;
149
0
        register int sbyte = *sptr++;
150
0
        register int bit = first_bit;
151
0
        int count = w;
152
153
0
        do {
154
0
            if (sbyte & bit) {
155
0
                if (one != gx_no_color_index)
156
0
                    *pptr = one16;
157
0
            } else {
158
0
                if (zero != gx_no_color_index)
159
0
                    *pptr = zero16;
160
0
            }
161
0
            if ((bit >>= 1) == 0)
162
0
                bit = 0x80, sbyte = *sptr++;
163
0
            pptr++;
164
0
        }
165
0
        while (--count > 0);
166
0
        line += sraster;
167
0
        inc_ptr(dest, draster);
168
0
    }
169
0
    return 0;
170
0
}
171
172
/* Copy a color bitmap. */
173
static int
174
mem_true16_copy_color(gx_device * dev,
175
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
176
                      int x, int y, int w, int h)
177
0
{
178
0
    gx_device_memory * const mdev = (gx_device_memory *)dev;
179
180
0
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
181
0
    mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h);
182
0
    return 0;
183
0
}