/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 | } |