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: gdevm8.c 8250 2007-09-25 13:31:24Z giles $ */
14 /* 8-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 #define mem_gray8_strip_copy_rop mem_gray8_rgb24_strip_copy_rop
22
23 /* ================ Standard (byte-oriented) device ================ */
24
25 #undef chunk
26 #define chunk byte
27
28 /* Procedures */
29 declare_mem_procs(mem_mapped8_copy_mono, mem_mapped8_copy_color, mem_mapped8_fill_rectangle);
30
31 /* The device descriptor. */
32 const gx_device_memory mem_mapped8_device =
33 mem_device("image8", 8, 0,
34 mem_mapped_map_rgb_color, mem_mapped_map_color_rgb,
35 mem_mapped8_copy_mono, mem_mapped8_copy_color, mem_mapped8_fill_rectangle,
36 mem_gray8_strip_copy_rop);
37
38 /* Convert x coordinate to byte offset in scan line. */
39 #undef x_to_byte
40 #define x_to_byte(x) (x)
41
42 /* Fill a rectangle with a color. */
43 static int
mem_mapped8_fill_rectangle(gx_device * dev,int x,int y,int w,int h,gx_color_index color)44 mem_mapped8_fill_rectangle(gx_device * dev,
45 int x, int y, int w, int h, gx_color_index color)
46 {
47 gx_device_memory * const mdev = (gx_device_memory *)dev;
48
49 fit_fill(dev, x, y, w, h);
50 bytes_fill_rectangle(scan_line_base(mdev, y) + x, mdev->raster,
51 (byte) color, w, h);
52 return 0;
53 }
54
55 /* Copy a monochrome bitmap. */
56 /* We split up this procedure because of limitations in the bcc32 compiler. */
57 static void mapped8_copy01(chunk *, const byte *, int, int, uint,
58 int, int, byte, byte);
59 static void mapped8_copyN1(chunk *, const byte *, int, int, uint,
60 int, int, byte);
61 static void mapped8_copy0N(chunk *, const byte *, int, int, uint,
62 int, int, byte);
63 static int
mem_mapped8_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)64 mem_mapped8_copy_mono(gx_device * dev,
65 const byte * base, int sourcex, int sraster, gx_bitmap_id id,
66 int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
67 {
68 gx_device_memory * const mdev = (gx_device_memory *)dev;
69 const byte *line;
70 int first_bit;
71
72 declare_scan_ptr(dest);
73 fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
74 setup_rect(dest);
75 line = base + (sourcex >> 3);
76 first_bit = 0x80 >> (sourcex & 7);
77 #define is_color(c) ((int)(c) != (int)gx_no_color_index)
78 if (is_color(one)) {
79 if (is_color(zero))
80 mapped8_copy01(dest, line, first_bit, sraster, draster,
81 w, h, (byte) zero, (byte) one);
82 else
83 mapped8_copyN1(dest, line, first_bit, sraster, draster,
84 w, h, (byte) one);
85 } else if (is_color(zero))
86 mapped8_copy0N(dest, line, first_bit, sraster, draster,
87 w, h, (byte) zero);
88 #undef is_color
89 return 0;
90 }
91 /* Macros for copy loops */
92 #define COPY_BEGIN\
93 while ( h-- > 0 )\
94 { register byte *pptr = dest;\
95 const byte *sptr = line;\
96 register int sbyte = *sptr;\
97 register uint bit = first_bit;\
98 int count = w;\
99 do\
100 {
101 #define COPY_END\
102 if ( (bit >>= 1) == 0 )\
103 bit = 0x80, sbyte = *++sptr;\
104 pptr++;\
105 }\
106 while ( --count > 0 );\
107 line += sraster;\
108 inc_ptr(dest, draster);\
109 }
110 /* Halftone coloring */
111 static void
mapped8_copy01(chunk * dest,const byte * line,int first_bit,int sraster,uint draster,int w,int h,byte b0,byte b1)112 mapped8_copy01(chunk * dest, const byte * line, int first_bit,
113 int sraster, uint draster, int w, int h, byte b0, byte b1)
114 {
115 COPY_BEGIN
116 * pptr = (sbyte & bit ? b1 : b0);
117 COPY_END
118 }
119 /* Stenciling */
120 static void
mapped8_copyN1(chunk * dest,const byte * line,int first_bit,int sraster,uint draster,int w,int h,byte b1)121 mapped8_copyN1(chunk * dest, const byte * line, int first_bit,
122 int sraster, uint draster, int w, int h, byte b1)
123 {
124 COPY_BEGIN
125 if (sbyte & bit)
126 *pptr = b1;
127 COPY_END
128 }
129 /* Reverse stenciling */
130 static void
mapped8_copy0N(chunk * dest,const byte * line,int first_bit,int sraster,uint draster,int w,int h,byte b0)131 mapped8_copy0N(chunk * dest, const byte * line, int first_bit,
132 int sraster, uint draster, int w, int h, byte b0)
133 {
134 COPY_BEGIN
135 if (!(sbyte & bit))
136 *pptr = b0;
137 COPY_END
138 }
139 #undef COPY_BEGIN
140 #undef COPY_END
141
142 /* Copy a color bitmap. */
143 static int
mem_mapped8_copy_color(gx_device * dev,const byte * base,int sourcex,int sraster,gx_bitmap_id id,int x,int y,int w,int h)144 mem_mapped8_copy_color(gx_device * dev,
145 const byte * base, int sourcex, int sraster, gx_bitmap_id id,
146 int x, int y, int w, int h)
147 {
148 gx_device_memory * const mdev = (gx_device_memory *)dev;
149
150 fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
151 mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h);
152 return 0;
153 }
154
155 /* ================ "Word"-oriented device ================ */
156
157 /* Note that on a big-endian machine, this is the same as the */
158 /* standard byte-oriented-device. */
159
160 #if !arch_is_big_endian
161
162 /* Procedures */
163 declare_mem_procs(mem8_word_copy_mono, mem8_word_copy_color, mem8_word_fill_rectangle);
164
165 /* Here is the device descriptor. */
166 const gx_device_memory mem_mapped8_word_device =
167 mem_full_device("image8w", 8, 0, mem_open,
168 mem_mapped_map_rgb_color, mem_mapped_map_color_rgb,
169 mem8_word_copy_mono, mem8_word_copy_color, mem8_word_fill_rectangle,
170 gx_default_map_cmyk_color, gx_default_strip_tile_rectangle,
171 gx_no_strip_copy_rop, mem_word_get_bits_rectangle);
172
173 /* Fill a rectangle with a color. */
174 static int
mem8_word_fill_rectangle(gx_device * dev,int x,int y,int w,int h,gx_color_index color)175 mem8_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
176 gx_color_index color)
177 {
178 gx_device_memory * const mdev = (gx_device_memory *)dev;
179 byte *base;
180 uint raster;
181
182 fit_fill(dev, x, y, w, h);
183 base = scan_line_base(mdev, y);
184 raster = mdev->raster;
185 mem_swap_byte_rect(base, raster, x << 3, w << 3, h, true);
186 bytes_fill_rectangle(base + x, raster, (byte) color, w, h);
187 mem_swap_byte_rect(base, raster, x << 3, w << 3, h, true);
188 return 0;
189 }
190
191 /* Copy a bitmap. */
192 static int
mem8_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)193 mem8_word_copy_mono(gx_device * dev,
194 const byte * base, int sourcex, int sraster, gx_bitmap_id id,
195 int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
196 {
197 gx_device_memory * const mdev = (gx_device_memory *)dev;
198 byte *row;
199 uint raster;
200 bool store;
201
202 fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
203 row = scan_line_base(mdev, y);
204 raster = mdev->raster;
205 store = (zero != gx_no_color_index && one != gx_no_color_index);
206 mem_swap_byte_rect(row, raster, x << 3, w << 3, h, store);
207 mem_mapped8_copy_mono(dev, base, sourcex, sraster, id,
208 x, y, w, h, zero, one);
209 mem_swap_byte_rect(row, raster, x << 3, w << 3, h, false);
210 return 0;
211 }
212
213 /* Copy a color bitmap. */
214 static int
mem8_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)215 mem8_word_copy_color(gx_device * dev,
216 const byte * base, int sourcex, int sraster, gx_bitmap_id id,
217 int x, int y, int w, int h)
218 {
219 gx_device_memory * const mdev = (gx_device_memory *)dev;
220 byte *row;
221 uint raster;
222
223 fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
224 row = scan_line_base(mdev, y);
225 raster = mdev->raster;
226 mem_swap_byte_rect(row, raster, x << 3, w << 3, h, true);
227 mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h);
228 mem_swap_byte_rect(row, raster, x << 3, w << 3, h, false);
229 return 0;
230 }
231
232 #endif /* !arch_is_big_endian */
233