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