xref: /plan9/sys/src/cmd/gs/src/gxdevmem.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1989, 1995, 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: gxdevmem.h,v 1.7 2005/03/14 18:08:36 dan Exp $ */
18 /* Structure and procedures for memory devices */
19 /* Requires gxdevice.h */
20 
21 #ifndef gxdevmem_INCLUDED
22 #  define gxdevmem_INCLUDED
23 
24 #include "gxrplane.h"
25 
26 /*
27  * A 'memory' device is essentially a stored bitmap.
28  * There are several different kinds: 1-bit black and white,
29  * 2-, 4-, and 8-bit mapped color, 16- and 24-bit RGB color,
30  * and 32-bit CMYK color.  (16-bit uses 5/6/5 bits per color.)
31  * All use the same structure, since it's so awkward to get the effect of
32  * subclasses in C.
33  *
34  * Memory devices come in two flavors: standard, which always stores bytes
35  * big-endian, and word-oriented, which stores bytes in the machine order
36  * within 32-bit "words".  The source data for copy_mono and
37  * copy_color must be in big-endian order, and since memory devices
38  * also are guaranteed to allocate the bitmap consecutively,
39  * the bitmap of a standard memory device can serve directly as input
40  * to copy_mono or copy_color operations.  This is not true of word-oriented
41  * memory devices, which are provided only in response to a request by
42  * a customer with their own image processing library that uses this format.
43  *
44  * In addition to the device structure itself, memory devices require two
45  * other pieces of storage: the bitmap, and a table of pointers to the scan
46  * lines of the bitmap.  Clients have several options for allocating these:
47  *
48  *	1) Set bitmap_memory to an allocator before opening the device.
49  *	With this option, opening the device allocates the bitmap and the
50  *	line pointer table (contiguously), and closing the device frees
51  *	them.
52  *
53  *	2) Set line_pointer_memory to an allocator, base to the base address
54  *	of the bitmap, and raster to the length of each scan line (distance
55  *	from one scan line to the next) before opening the device.  With
56  *	this option, opening the device allocates the line table, but not
57  *	the bitmap; closing the device frees the table.
58  *
59  *	3) Set line_pointer_memory but not base or raster.  Opening /
60  *	closing the device will allocate / free the line pointer table, but
61  *	the client must set the pointers with a subsequent call of
62  *	gdev_mem_set_line_ptrs.
63  *
64  *	4) Set neither _memory field.  In this case, it's up to the client
65  *	to call gdev_mem_set_line_ptrs and to manage storage for the
66  *	line pointers and the bitmap.
67  *
68  * In cases (2) through (4), it is the client's responsibility to set
69  * foreign_bits (and foreign_line_pointers, if the line pointers are not
70  * contiguous with the bits) to tell the GC whether to trace the pointers.
71  * By default, anything allocated by bitmap_memory or line_pointer_memory is
72  * assumed GC'able (i.e., case (1) assumes that the bits + line pointers are
73  * GC'able, and cases (2) and (3) assume that the line pointers are GC'able,
74  * but not the bits), but the client can change the foreign_* flag(s) after
75  * opening the device if this is not the case.
76  */
77 #ifndef gx_device_memory_DEFINED
78 #  define gx_device_memory_DEFINED
79 typedef struct gx_device_memory_s gx_device_memory;
80 #endif
81 
82 struct gx_device_memory_s {
83     gx_device_forward_common;	/* (see gxdevice.h) */
84     /*
85      * The following may be set by the client before or just after
86      * opening the device.  See above.
87      */
88     uint raster;		/* bytes per scan line */
89     byte *base;
90 #define scan_line_base(dev,y) ((dev)->line_ptrs[y])
91     gs_memory_t *bitmap_memory;	/* allocator for bits + line pointers */
92     bool foreign_bits;		/* if true, bits are not in GC-able space */
93     gs_memory_t *line_pointer_memory;  /* allocate for line pointers */
94     bool foreign_line_pointers;  /* if true, line_ptrs are not in GC-able space */
95     /*
96      * The following are only used for planar devices.  num_planes == 0
97      * means this is a chunky device.  Note that for planar devices, we
98      * require color_info.depth = the sum of the individual plane depths.
99      */
100     int num_planes;
101     gx_render_plane_t planes[GX_DEVICE_COLOR_MAX_COMPONENTS];
102     /*
103      * End of client-initializable fields.
104      */
105     gs_matrix initial_matrix;	/* the initial transformation */
106     byte **line_ptrs;		/* scan line pointers */
107     /* Following is used for mapped color, */
108     /* including 1-bit devices (to specify polarity). */
109     gs_const_string palette;	/* RGB triples */
110     /* Following is only used for 24-bit color. */
111     struct _c24 {
112 	gx_color_index rgb;	/* cache key */
113 	bits32 rgbr, gbrg, brgb;	/* cache value */
114     } color24;
115     /* Following is only used for 40-bit color. */
116     struct _c40 {
117 	gx_color_index abcde;	/* cache key */
118 	bits32 abcd, bcde, cdea, deab, eabc;	/* cache value */
119     } color40;
120     /* Following is only used for 48-bit color. */
121     struct _c48 {
122 	gx_color_index abcdef;	/* cache key */
123 	bits32 abcd, cdef, efab;	/* cache value */
124     } color48;
125     /* Following is only used for 56-bit color. */
126     struct _c56 {
127 	gx_color_index abcdefg;	/* cache key */
128 	bits32 abcd, bcde, cdef, defg, efga, fgab, gabc;	/* cache value */
129     } color56;
130     /* Following is only used for 64-bit color. */
131     struct _c64 {
132 	gx_color_index abcdefgh;	/* cache key */
133 	bits32 abcd, efgh;	/* cache value */
134     } color64;
135     /* Following are only used for alpha buffers. */
136     /* The client initializes those marked with $; */
137     /* they don't change after initialization. */
138     gs_log2_scale_point log2_scale;	/* $ oversampling scale factors */
139     int log2_alpha_bits;	/* $ log2 of # of alpha bits being produced */
140     int mapped_x;		/* $ X value mapped to buffer X=0 */
141     int mapped_y;		/* lowest Y value mapped to buffer */
142     int mapped_height;		/* # of Y values mapped to buffer */
143     int mapped_start;		/* local Y value corresponding to mapped_y */
144     gx_color_index save_color;	/* last (only) color displayed */
145     /* Following are used only for planar devices. */
146     int plane_depth;		/* if non-zero, depth of all planes */
147 };
148 
149 extern_st(st_device_memory);
150 #define public_st_device_memory() /* in gdevmem.c */\
151   gs_public_st_composite_use_final(st_device_memory, gx_device_memory,\
152     "gx_device_memory", device_memory_enum_ptrs, device_memory_reloc_ptrs,\
153     gx_device_finalize)
154 #define st_device_memory_max_ptrs (st_device_forward_max_ptrs + 2)
155 #define mem_device_init_private\
156 	0,			/* raster */\
157 	(byte *)0,		/* base */\
158 	0,			/* bitmap_memory */\
159 	true,			/* foreign_bits (default) */\
160 	0,			/* line_pointer_memory */\
161 	true,			/* foreign_line_pointers (default) */\
162 	0,			/* num_planes (default) */\
163 	{ { 0 } },		/* planes (only used for planar) */\
164 	{ identity_matrix_body },	/* initial matrix (filled in) */\
165 	(byte **)0,		/* line_ptrs (filled in by mem_open) */\
166 	{ (byte *)0, 0 },	/* palette (filled in for color) */\
167 	{ gx_no_color_index },	/* color24 */\
168 	{ gx_no_color_index },	/* color40 */\
169 	{ gx_no_color_index },	/* color48 */\
170 	{ gx_no_color_index },	/* color56 */\
171 	{ gx_no_color_index },	/* color64 */\
172 	{ 0, 0 }, 0,		/* scale, log2_alpha_bits */\
173 	0, 0, 0, 0,		/* mapped_* */\
174 	gx_no_color_index	/* save_color */
175 
176 /*
177  * Memory devices may have special setup requirements.  In particular, it
178  * may not be obvious how much space to allocate for the bitmap.  Here is
179  * the routine that computes this from the width and height.  Note that this
180  * size includes both the bitmap and the line pointers.
181  */
182 /* bits only */
183 ulong gdev_mem_bits_size(const gx_device_memory *mdev, int width,
184 			 int height);
185 /* line pointers only */
186 ulong gdev_mem_line_ptrs_size(const gx_device_memory *mdev, int width,
187 			      int height);
188 /* bits + line pointers */
189 ulong gdev_mem_data_size(const gx_device_memory *mdev, int width,
190 			 int height);
191 
192 #define gdev_mem_bitmap_size(mdev)\
193   gdev_mem_data_size(mdev, (mdev)->width, (mdev)->height)
194 
195 /*
196  * Do the inverse computation: given the device width and a buffer size,
197  * compute the maximum height.
198  */
199 int gdev_mem_max_height(const gx_device_memory * dev, int width, ulong size,
200 		bool page_uses_transparency);
201 
202 /*
203  * Compute the standard raster (data bytes per line) similarly.
204  */
205 #define gdev_mem_raster(mdev)\
206   gx_device_raster((const gx_device *)(mdev), true)
207 
208 /* Determine the appropriate memory device for a given */
209 /* number of bits per pixel (0 if none suitable). */
210 const gx_device_memory *gdev_mem_device_for_bits(int);
211 
212 /* Determine the word-oriented memory device for a given depth. */
213 const gx_device_memory *gdev_mem_word_device_for_bits(int);
214 
215 /* Make a memory device. */
216 /* mem is 0 if the device is temporary and local, */
217 /* or the allocator that was used to allocate it if it is a real object. */
218 /* page_device is 1 if the device should be a page device, */
219 /* 0 if it should propagate this property from its target, or */
220 /* -1 if it should not be a page device. */
221 void gs_make_mem_mono_device(gx_device_memory * mdev, gs_memory_t * mem,
222 			     gx_device * target);
223 void gs_make_mem_device(gx_device_memory * mdev,
224 			const gx_device_memory * mdproto,
225 			gs_memory_t * mem, int page_device,
226 			gx_device * target);
227 void gs_make_mem_abuf_device(gx_device_memory * adev, gs_memory_t * mem,
228 			     gx_device * target,
229 			     const gs_log2_scale_point * pscale,
230 			     int alpha_bits, int mapped_x);
231 void gs_make_mem_alpha_device(gx_device_memory * adev, gs_memory_t * mem,
232 			      gx_device * target, int alpha_bits);
233 
234 /*
235  * Open a memory device, only setting line pointers to a subset of its
236  * scan lines.  Banding devices use this (see gxclread.c).
237  */
238 int gdev_mem_open_scan_lines(gx_device_memory *mdev, int setup_height);
239 
240 /*
241  * Initialize the line pointers of a memory device.  base and/or line_ptrs
242  * may be NULL, in which case the value already stored in the device is
243  * used; if base is NULL, raster is also ignored and the existing value is
244  * used.  Note that this takes raster and setup_height arguments.
245  * If the base is not NULL and the device is planar, all planes must have
246  * the same depth, since otherwise a single raster value is not sufficient.
247  *
248  * Note that setup_height may be less than height.  In this case, for
249  * planar devices, only setup_height * num_planes line pointers are set,
250  * in the expectation that the device's height will be reset to
251  * setup_height.
252  */
253 int gdev_mem_set_line_ptrs(gx_device_memory *mdev,
254 			   byte *base, int raster, byte **line_ptrs,
255 			   int setup_height);
256 
257 /* Define whether a monobit memory device is inverted (black=1). */
258 void gdev_mem_mono_set_inverted(gx_device_memory * mdev, bool black_is_1);
259 
260 /* Test whether a device is a memory device. */
261 bool gs_device_is_memory(const gx_device *);
262 
263 /* Test whether a device is an alpha-buffering device. */
264 bool gs_device_is_abuf(const gx_device *);
265 
266 #endif /* gxdevmem_INCLUDED */
267