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