1 /* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gdevm32.c,v 1.5 2003/05/24 17:19:58 dan Exp $ */
18 /* 32-bit-per-pixel "memory" (stored bitmap) device */
19 #include "memory_.h"
20 #include "gx.h"
21 #include "gxdevice.h"
22 #include "gxdevmem.h" /* semi-public definitions */
23 #include "gdevmem.h" /* private definitions */
24
25 /* ================ Standard (byte-oriented) device ================ */
26
27 #undef chunk
28 #define chunk byte
29
30 /* Procedures */
31 declare_mem_procs(mem_true32_copy_mono, mem_true32_copy_color, mem_true32_fill_rectangle);
32
33 /* The device descriptor. */
34 const gx_device_memory mem_true32_device =
35 mem_full_device("image32", 24, 8, mem_open,
36 gx_default_map_rgb_color, gx_default_map_color_rgb,
37 mem_true32_copy_mono, mem_true32_copy_color, mem_true32_fill_rectangle,
38 gx_default_cmyk_map_cmyk_color, gx_default_strip_tile_rectangle,
39 mem_default_strip_copy_rop, mem_get_bits_rectangle);
40
41 /* Convert x coordinate to byte offset in scan line. */
42 #undef x_to_byte
43 #define x_to_byte(x) ((x) << 2)
44
45 /* Swap the bytes of a color if needed. */
46 #define color_swap_bytes(color)\
47 ((((color) >> 24) & 0xff) + (((color) >> 8) & 0xff00) +\
48 (((color) & 0xff00) << 8) + ((color) << 24))
49 #if arch_is_big_endian
50 # define arrange_bytes(color) (color)
51 #else
52 # define arrange_bytes(color) color_swap_bytes(color)
53 #endif
54
55 /* Fill a rectangle with a color. */
56 private int
mem_true32_fill_rectangle(gx_device * dev,int x,int y,int w,int h,gx_color_index color)57 mem_true32_fill_rectangle(gx_device * dev,
58 int x, int y, int w, int h, gx_color_index color)
59 {
60 gx_device_memory * const mdev = (gx_device_memory *)dev;
61 bits32 a_color;
62
63 declare_scan_ptr(dest);
64
65 fit_fill(dev, x, y, w, h);
66 a_color = arrange_bytes(color);
67 setup_rect(dest);
68 if (w <= 4)
69 switch (w) {
70 /*case 0: *//* not possible */
71 #define dest32 ((bits32 *)dest)
72 case 1:
73 do {
74 dest32[0] = a_color;
75 inc_ptr(dest, draster);
76 }
77 while (--h > 0);
78 break;
79 case 2:
80 do {
81 dest32[1] = dest32[0] = a_color;
82 inc_ptr(dest, draster);
83 }
84 while (--h > 0);
85 break;
86 case 3:
87 do {
88 dest32[2] = dest32[1] = dest32[0] = a_color;
89 inc_ptr(dest, draster);
90 }
91 while (--h > 0);
92 break;
93 case 4:
94 do {
95 dest32[3] = dest32[2] = dest32[1] = dest32[0] = a_color;
96 inc_ptr(dest, draster);
97 }
98 while (--h > 0);
99 break;
100 default: /* not possible */
101 ;
102 } else if (a_color == 0)
103 do {
104 memset(dest, 0, w << 2);
105 inc_ptr(dest, draster);
106 }
107 while (--h > 0);
108 else
109 do {
110 bits32 *pptr = dest32;
111 int cnt = w;
112
113 do {
114 pptr[3] = pptr[2] = pptr[1] = pptr[0] = a_color;
115 pptr += 4;
116 }
117 while ((cnt -= 4) > 4);
118 do {
119 *pptr++ = a_color;
120 } while (--cnt > 0);
121 inc_ptr(dest, draster);
122 }
123 while (--h > 0);
124 #undef dest32
125 return 0;
126 }
127
128 /* Copy a monochrome bitmap. */
129 private int
mem_true32_copy_mono(gx_device * dev,const byte * base,int sourcex,int sraster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one)130 mem_true32_copy_mono(gx_device * dev,
131 const byte * base, int sourcex, int sraster, gx_bitmap_id id,
132 int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
133 {
134 gx_device_memory * const mdev = (gx_device_memory *)dev;
135 bits32 a_zero = arrange_bytes(zero);
136 bits32 a_one = arrange_bytes(one);
137 const byte *line;
138
139 declare_scan_ptr(dest);
140 fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
141 setup_rect(dest);
142 line = base + (sourcex >> 3);
143 if (zero == gx_no_color_index) {
144 int first_bit = sourcex & 7;
145 int w_first = min(w, 8 - first_bit);
146 int w_rest = w - w_first;
147
148 if (one == gx_no_color_index)
149 return 0;
150 /*
151 * There are no halftones, so this case -- characters --
152 * is the only common one.
153 */
154 while (h-- > 0) {
155 bits32 *pptr = (bits32 *) dest;
156 const byte *sptr = line;
157 int sbyte = (*sptr++ << first_bit) & 0xff;
158 int count = w_first;
159
160 if (sbyte)
161 do {
162 if (sbyte & 0x80)
163 *pptr = a_one;
164 sbyte <<= 1;
165 pptr++;
166 }
167 while (--count > 0);
168 else
169 pptr += count;
170 for (count = w_rest; count >= 8; count -= 8, pptr += 8) {
171 sbyte = *sptr++;
172 if (sbyte) {
173 if (sbyte & 0x80) pptr[0] = a_one;
174 if (sbyte & 0x40) pptr[1] = a_one;
175 if (sbyte & 0x20) pptr[2] = a_one;
176 if (sbyte & 0x10) pptr[3] = a_one;
177 if (sbyte & 0x08) pptr[4] = a_one;
178 if (sbyte & 0x04) pptr[5] = a_one;
179 if (sbyte & 0x02) pptr[6] = a_one;
180 if (sbyte & 0x01) pptr[7] = a_one;
181 }
182 }
183 if (count) {
184 sbyte = *sptr;
185 do {
186 if (sbyte & 0x80)
187 *pptr = a_one;
188 sbyte <<= 1;
189 pptr++;
190 }
191 while (--count > 0);
192 }
193 line += sraster;
194 inc_ptr(dest, draster);
195 }
196 } else { /* zero != gx_no_color_index */
197 int first_bit = 0x80 >> (sourcex & 7);
198
199 while (h-- > 0) {
200 bits32 *pptr = (bits32 *) dest;
201 const byte *sptr = line;
202 int sbyte = *sptr++;
203 int bit = first_bit;
204 int count = w;
205
206 do {
207 if (sbyte & bit) {
208 if (one != gx_no_color_index)
209 *pptr = a_one;
210 } else
211 *pptr = a_zero;
212 if ((bit >>= 1) == 0)
213 bit = 0x80, sbyte = *sptr++;
214 pptr++;
215 }
216 while (--count > 0);
217 line += sraster;
218 inc_ptr(dest, draster);
219 }
220 }
221 return 0;
222 }
223
224 /* Copy a color bitmap. */
225 private int
mem_true32_copy_color(gx_device * dev,const byte * base,int sourcex,int sraster,gx_bitmap_id id,int x,int y,int w,int h)226 mem_true32_copy_color(gx_device * dev,
227 const byte * base, int sourcex, int sraster, gx_bitmap_id id,
228 int x, int y, int w, int h)
229 {
230 gx_device_memory * const mdev = (gx_device_memory *)dev;
231
232 fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
233 mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h);
234 return 0;
235 }
236
237 /* ================ "Word"-oriented device ================ */
238
239 /* Note that on a big-endian machine, this is the same as the */
240 /* standard byte-oriented-device. */
241
242 #if !arch_is_big_endian
243
244 /* Procedures */
245 declare_mem_procs(mem32_word_copy_mono, mem32_word_copy_color, mem32_word_fill_rectangle);
246
247 /* Here is the device descriptor. */
248 const gx_device_memory mem_true32_word_device =
249 mem_full_device("image32w", 24, 8, mem_open,
250 gx_default_map_rgb_color, gx_default_map_color_rgb,
251 mem32_word_copy_mono, mem32_word_copy_color, mem32_word_fill_rectangle,
252 gx_default_cmyk_map_cmyk_color, gx_default_strip_tile_rectangle,
253 gx_no_strip_copy_rop, mem_word_get_bits_rectangle);
254
255 /* Fill a rectangle with a color. */
256 private int
mem32_word_fill_rectangle(gx_device * dev,int x,int y,int w,int h,gx_color_index color)257 mem32_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
258 gx_color_index color)
259 {
260 return mem_true32_fill_rectangle(dev, x, y, w, h,
261 color_swap_bytes(color));
262 }
263
264 /* Copy a bitmap. */
265 private int
mem32_word_copy_mono(gx_device * dev,const byte * base,int sourcex,int sraster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one)266 mem32_word_copy_mono(gx_device * dev,
267 const byte * base, int sourcex, int sraster, gx_bitmap_id id,
268 int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
269 {
270 return mem_true32_copy_mono(dev, base, sourcex, sraster, id,
271 x, y, w, h, color_swap_bytes(zero),
272 color_swap_bytes(one));
273 }
274
275 /* Copy a color bitmap. */
276 private int
mem32_word_copy_color(gx_device * dev,const byte * base,int sourcex,int sraster,gx_bitmap_id id,int x,int y,int w,int h)277 mem32_word_copy_color(gx_device * dev,
278 const byte * base, int sourcex, int sraster, gx_bitmap_id id,
279 int x, int y, int w, int h)
280 {
281 gx_device_memory * const mdev = (gx_device_memory *)dev;
282 byte *row;
283 uint raster;
284
285 fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
286 row = scan_line_base(mdev, y);
287 raster = mdev->raster;
288 bytes_copy_rectangle(row + (x << 2), raster, base + (sourcex << 2),
289 sraster, w << 2, h);
290 mem_swap_byte_rect(row, raster, x << 5, w << 5, h, false);
291 return 0;
292 }
293
294 #endif /* !arch_is_big_endian */
295