2 |
- |
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 */
|