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