1 /* Copyright (C) 2001-2019 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,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* Structure and procedures for memory devices */
18 /* Requires gxdevice.h */
19 
20 #ifndef gxdevmem_INCLUDED
21 #  define gxdevmem_INCLUDED
22 
23 #include "gxdevcli.h"
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 
78 struct gx_device_memory_s {
79     gx_device_forward_common;	/* (see gxdevice.h) */
80     /*
81      * The following may be set by the client before or just after
82      * opening the device.  See above.
83      */
84     uint raster;		/* bytes per scan line */
85     byte *base;
86 #define scan_line_base(dev,y) ((dev)->line_ptrs[y])
87     gs_memory_t *bitmap_memory;	/* allocator for bits + line pointers */
88     bool foreign_bits;		/* if true, bits are not in GC-able space */
89     gs_memory_t *line_pointer_memory;  /* allocate for line pointers */
90     bool foreign_line_pointers;  /* if true, line_ptrs are not in GC-able space */
91     /*
92      * The following are only used for planar devices.  num_planes == 0
93      * means this is a chunky device.  Note that for planar devices, we
94      * require color_info.depth = the sum of the individual plane depths.
95      */
96     gx_render_plane_t planes[GX_DEVICE_COLOR_MAX_COMPONENTS];
97     /*
98      * End of client-initializable fields.
99      */
100     gs_matrix initial_matrix;	/* the initial transformation */
101     byte **line_ptrs;		/* scan line pointers */
102     /* Following is used for mapped color, */
103     /* including 1-bit devices (to specify polarity). */
104     gs_const_string palette;	/* RGB triples */
105     /* Following is only used for 24-bit color. */
106     struct _c24 {
107         gx_color_index rgb;	/* cache key */
108         bits32 rgbr, gbrg, brgb;	/* cache value */
109     } color24;
110     /* Following is only used for 40-bit color. */
111     struct _c40 {
112         gx_color_index abcde;	/* cache key */
113         bits32 abcd, bcde, cdea, deab, eabc;	/* cache value */
114     } color40;
115     /* Following is only used for 48-bit color. */
116     struct _c48 {
117         gx_color_index abcdef;	/* cache key */
118         bits32 abcd, cdef, efab;	/* cache value */
119     } color48;
120     /* Following is only used for 56-bit color. */
121     struct _c56 {
122         gx_color_index abcdefg;	/* cache key */
123         bits32 abcd, bcde, cdef, defg, efga, fgab, gabc;	/* cache value */
124     } color56;
125     /* Following is only used for 64-bit color. */
126     struct _c64 {
127         gx_color_index abcdefgh;	/* cache key */
128         bits32 abcd, efgh;	/* cache value */
129     } color64;
130     /* Following are only used for alpha buffers. */
131     /* The client initializes those marked with $; */
132     /* they don't change after initialization. */
133     gs_log2_scale_point log2_scale;	/* $ oversampling scale factors */
134     int log2_alpha_bits;	/* $ log2 of # of alpha bits being produced */
135     int mapped_x;		/* $ X value mapped to buffer X=0 */
136     int mapped_y;		/* lowest Y value mapped to buffer */
137     int mapped_height;		/* # of Y values mapped to buffer */
138     int mapped_start;		/* local Y value corresponding to mapped_y */
139     gx_color_index save_color;	/* last (only) color displayed */
140     const gx_drawing_color *save_hl_color;
141                                 /* last (only) hl color displayed */
142     /* Following are used only for planar devices. */
143     int plane_depth;		/* if non-zero, depth of all planes */
144     int band_y; /* Debug purpose only. */
145 };
146 
147 extern_st(st_device_memory);
148 #define public_st_device_memory() /* in gdevmem.c */\
149   gs_public_st_composite_use_final(st_device_memory, gx_device_memory,\
150     "gx_device_memory", device_memory_enum_ptrs, device_memory_reloc_ptrs,\
151     gx_device_finalize)
152 #define st_device_memory_max_ptrs (st_device_forward_max_ptrs + 2)
153 #define mem_device_init_private\
154         0,			/* raster */\
155         (byte *)0,		/* base */\
156         0,			/* bitmap_memory */\
157         true,			/* foreign_bits (default) */\
158         0,			/* line_pointer_memory */\
159         true,			/* foreign_line_pointers (default) */\
160         { { 0 } },		/* planes (only used for planar) */\
161         { identity_matrix_body },	/* initial matrix (filled in) */\
162         (byte **)0,		/* line_ptrs (filled in by mem_open) */\
163         { (byte *)0, 0 },	/* palette (filled in for color) */\
164         { gx_no_color_index },	/* color24 */\
165         { gx_no_color_index },	/* color40 */\
166         { gx_no_color_index },	/* color48 */\
167         { gx_no_color_index },	/* color56 */\
168         { gx_no_color_index },	/* color64 */\
169         { 0, 0 }, 0,		/* scale, log2_alpha_bits */\
170         0, 0, 0, 0,		/* mapped_* */\
171         gx_no_color_index	/* save_color */
172 
173 /*
174  * Memory devices may have special setup requirements.  In particular, it
175  * may not be obvious how much space to allocate for the bitmap.  Here is
176  * the routine that computes this from the width and height.  Note that this
177  * size includes both the bitmap and the line pointers.
178  */
179 /* bits only */
180 int gdev_mem_bits_size(const gx_device_memory *mdev, int width,
181                          int height, ulong *size);
182 /* line pointers only */
183 ulong gdev_mem_line_ptrs_size(const gx_device_memory *mdev, int width,
184                               int height);
185 /* bits + line pointers */
186 int gdev_mem_data_size(const gx_device_memory *mdev, int width,
187                          int height, ulong *size);
188 
189 #define gdev_mem_bitmap_size(mdev, size)\
190   gdev_mem_data_size(mdev, (mdev)->width, (mdev)->height, size)
191 
192 /*
193  * Do the inverse computation: given the device width and a buffer size,
194  * compute the maximum height.
195  */
196 int gdev_mem_max_height(const gx_device_memory * dev, int width, ulong size,
197                 bool page_uses_transparency);
198 
199 /*
200  * Compute the standard raster (data bytes per line) similarly.
201  */
202 #define gdev_mem_raster(mdev)\
203   gx_device_raster((const gx_device *)(mdev), true)
204 
205 /* Determine the appropriate memory device for a given */
206 /* number of bits per pixel (0 if none suitable). */
207 const gx_device_memory *gdev_mem_device_for_bits(int);
208 
209 /* Determine the word-oriented memory device for a given depth. */
210 const gx_device_memory *gdev_mem_word_device_for_bits(int);
211 
212 /*
213  * Make a memory device.  The following 4 procedures will be
214  * deprecated, use gs_make_mem_*_copydevice() below, for future
215  * changes.
216  */
217 
218 /* mem is 0 if the device is temporary and local, */
219 /* or the allocator that was used to allocate it if it is a real object. */
220 /* page_device is 1 if the device should be a page device, */
221 /* 0 if it should propagate this property from its target, or */
222 /* -1 if it should not be a page device. */
223 void gs_make_mem_mono_device(gx_device_memory * mdev, gs_memory_t * mem,
224                              gx_device * target);
225 void gs_make_mem_device(gx_device_memory * mdev,
226                         const gx_device_memory * mdproto,
227                         gs_memory_t * mem, int page_device,
228                         gx_device * target);
229 void gs_make_mem_abuf_device(gx_device_memory * adev, gs_memory_t * mem,
230                              gx_device * target,
231                              const gs_log2_scale_point * pscale,
232                              int alpha_bits, int mapped_x, bool devn);
233 void gs_make_mem_alpha_device(gx_device_memory * adev, gs_memory_t * mem,
234                               gx_device * target, int alpha_bits);
235 
236 /*
237  * Create memory devices with copydevice.  For now the destructor is
238  * simply: gx_device_retain(mdev, false).
239  */
240 
241 int gs_make_mem_mono_device_with_copydevice(gx_device_memory ** mdev,
242                                             gs_memory_t * mem,
243                                             gx_device * target);
244 
245 int gs_make_mem_device_with_copydevice(gx_device_memory ** mdev,
246                                        const gx_device_memory * mdproto,
247                                        gs_memory_t * mem,
248                                        int page_device,
249                                        gx_device * target);
250 
251 /*
252  * TODO replace gs_make_mem_abuf_device, gs_make_mem_alpha_device with
253  * procedures that use copydevice.
254  */
255 
256 /*
257  * Open a memory device, only setting line pointers to a subset of its
258  * scan lines.  Banding devices use this (see gxclread.c).
259  */
260 int gdev_mem_open_scan_lines(gx_device_memory *mdev, int setup_height);
261 
262 /*
263  * Initialize the line pointers of a memory device.  base and/or line_ptrs
264  * may be NULL, in which case the value already stored in the device is
265  * used; if base is NULL, raster is also ignored and the existing value is
266  * used.  Note that this takes raster and setup_height arguments.
267  * If the base is not NULL and the device is planar, all planes must have
268  * the same depth, since otherwise a single raster value is not sufficient.
269  *
270  * Note that setup_height may be less than height.  In this case, for
271  * planar devices, only setup_height * num_planes line pointers are set,
272  * in the expectation that the device's height will be reset to
273  * setup_height.
274  */
275 int gdev_mem_set_line_ptrs(gx_device_memory *mdev,
276                            byte *base, int raster, byte **line_ptrs,
277                            int setup_height);
278 
279 /* Define whether a monobit memory device is inverted (black=1). */
280 void gdev_mem_mono_set_inverted(gx_device_memory * mdev, bool black_is_1);
281 
282 /* Test whether a device is a memory device. */
283 bool gs_device_is_memory(const gx_device *);
284 
285 /* Test whether a device is an alpha-buffering device. */
286 bool gs_device_is_abuf(const gx_device *);
287 
288 /* Check for getting the antialiasing bit depth */
289 int alpha_buffer_bits(gs_gstate * pgs);
290 
291 #endif /* gxdevmem_INCLUDED */
292