1 /* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved. 2 3 This file is part of Aladdin Ghostscript. 4 5 Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author 6 or distributor accepts any responsibility for the consequences of using it, 7 or for whether it serves any particular purpose or works at all, unless he 8 or she says so in writing. Refer to the Aladdin Ghostscript Free Public 9 License (the "License") for full details. 10 11 Every copy of Aladdin Ghostscript must include a copy of the License, 12 normally in a plain ASCII text file named PUBLIC. The License grants you 13 the right to copy, modify and redistribute Aladdin Ghostscript, but only 14 under certain conditions described in the License. Among other things, the 15 License requires that the copyright notice and this notice be preserved on 16 all copies. 17 */ 18 19 /*$Id: gdevm32.c,v 1.1 2000/03/09 08:40:41 lpd Exp $ */ 20 /* 32-bit-per-pixel "memory" (stored bitmap) device */ 21 #include "memory_.h" 22 #include "gx.h" 23 #include "gxdevice.h" 24 #include "gxdevmem.h" /* semi-public definitions */ 25 #include "gdevmem.h" /* private definitions */ 26 27 /* ================ Standard (byte-oriented) device ================ */ 28 29 #undef chunk 30 #define chunk byte 31 32 /* Procedures */ 33 declare_mem_procs(mem_true32_copy_mono, mem_true32_copy_color, mem_true32_fill_rectangle); 34 35 /* The device descriptor. */ 36 const gx_device_memory mem_true32_device = 37 mem_full_device("image32", 24, 8, mem_open, 38 gx_default_map_rgb_color, gx_default_map_color_rgb, 39 mem_true32_copy_mono, mem_true32_copy_color, mem_true32_fill_rectangle, 40 gx_default_cmyk_map_cmyk_color, gx_default_strip_tile_rectangle, 41 mem_default_strip_copy_rop, mem_get_bits_rectangle); 42 43 /* Convert x coordinate to byte offset in scan line. */ 44 #undef x_to_byte 45 #define x_to_byte(x) ((x) << 2) 46 47 /* Swap the bytes of a color if needed. */ 48 #define color_swap_bytes(color)\ 49 (((color) >> 24) + (((color) >> 8) & 0xff00) +\ 50 (((color) & 0xff00) << 8) + ((color) << 24)) 51 #if arch_is_big_endian 52 # define arrange_bytes(color) (color) 53 #else 54 # define arrange_bytes(color) color_swap_bytes(color) 55 #endif 56 57 /* Fill a rectangle with a color. */ 58 private int 59 mem_true32_fill_rectangle(gx_device * dev, 60 int x, int y, int w, int h, gx_color_index color) 61 { 62 gx_device_memory * const mdev = (gx_device_memory *)dev; 63 bits32 a_color; 64 65 declare_scan_ptr(dest); 66 67 fit_fill(dev, x, y, w, h); 68 a_color = arrange_bytes(color); 69 setup_rect(dest); 70 if (w <= 4) 71 switch (w) { 72 /*case 0: *//* not possible */ 73 #define dest32 ((bits32 *)dest) 74 case 1: 75 do { 76 dest32[0] = a_color; 77 inc_ptr(dest, draster); 78 } 79 while (--h > 0); 80 break; 81 case 2: 82 do { 83 dest32[1] = dest32[0] = a_color; 84 inc_ptr(dest, draster); 85 } 86 while (--h > 0); 87 break; 88 case 3: 89 do { 90 dest32[2] = dest32[1] = dest32[0] = a_color; 91 inc_ptr(dest, draster); 92 } 93 while (--h > 0); 94 break; 95 case 4: 96 do { 97 dest32[3] = dest32[2] = dest32[1] = dest32[0] = a_color; 98 inc_ptr(dest, draster); 99 } 100 while (--h > 0); 101 break; 102 default: /* not possible */ 103 ; 104 } else if (a_color == 0) 105 do { 106 memset(dest, 0, w << 2); 107 inc_ptr(dest, draster); 108 } 109 while (--h > 0); 110 else 111 do { 112 bits32 *pptr = dest32; 113 int cnt = w; 114 115 do { 116 pptr[3] = pptr[2] = pptr[1] = pptr[0] = a_color; 117 pptr += 4; 118 } 119 while ((cnt -= 4) > 4); 120 do { 121 *pptr++ = a_color; 122 } while (--cnt > 0); 123 inc_ptr(dest, draster); 124 } 125 while (--h > 0); 126 #undef dest32 127 return 0; 128 } 129 130 /* Copy a monochrome bitmap. */ 131 private int 132 mem_true32_copy_mono(gx_device * dev, 133 const byte * base, int sourcex, int sraster, gx_bitmap_id id, 134 int x, int y, int w, int h, gx_color_index zero, gx_color_index one) 135 { 136 gx_device_memory * const mdev = (gx_device_memory *)dev; 137 bits32 a_zero = arrange_bytes(zero); 138 bits32 a_one = arrange_bytes(one); 139 const byte *line; 140 141 declare_scan_ptr(dest); 142 fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); 143 setup_rect(dest); 144 line = base + (sourcex >> 3); 145 if (zero == gx_no_color_index) { 146 int first_bit = sourcex & 7; 147 int w_first = min(w, 8 - first_bit); 148 int w_rest = w - w_first; 149 150 if (one == gx_no_color_index) 151 return 0; 152 /* 153 * There are no halftones, so this case -- characters -- 154 * is the only common one. 155 */ 156 while (h-- > 0) { 157 bits32 *pptr = (bits32 *) dest; 158 const byte *sptr = line; 159 int sbyte = (*sptr++ << first_bit) & 0xff; 160 int count = w_first; 161 162 if (sbyte) 163 do { 164 if (sbyte & 0x80) 165 *pptr = a_one; 166 sbyte <<= 1; 167 pptr++; 168 } 169 while (--count > 0); 170 else 171 pptr += count; 172 for (count = w_rest; count >= 8; count -= 8, pptr += 8) { 173 sbyte = *sptr++; 174 if (sbyte) { 175 if (sbyte & 0x80) pptr[0] = a_one; 176 if (sbyte & 0x40) pptr[1] = a_one; 177 if (sbyte & 0x20) pptr[2] = a_one; 178 if (sbyte & 0x10) pptr[3] = a_one; 179 if (sbyte & 0x08) pptr[4] = a_one; 180 if (sbyte & 0x04) pptr[5] = a_one; 181 if (sbyte & 0x02) pptr[6] = a_one; 182 if (sbyte & 0x01) pptr[7] = a_one; 183 } 184 } 185 if (count) { 186 sbyte = *sptr; 187 do { 188 if (sbyte & 0x80) 189 *pptr = a_one; 190 sbyte <<= 1; 191 pptr++; 192 } 193 while (--count > 0); 194 } 195 line += sraster; 196 inc_ptr(dest, draster); 197 } 198 } else { /* zero != gx_no_color_index */ 199 int first_bit = 0x80 >> (sourcex & 7); 200 201 while (h-- > 0) { 202 bits32 *pptr = (bits32 *) dest; 203 const byte *sptr = line; 204 int sbyte = *sptr++; 205 int bit = first_bit; 206 int count = w; 207 208 do { 209 if (sbyte & bit) { 210 if (one != gx_no_color_index) 211 *pptr = a_one; 212 } else 213 *pptr = a_zero; 214 if ((bit >>= 1) == 0) 215 bit = 0x80, sbyte = *sptr++; 216 pptr++; 217 } 218 while (--count > 0); 219 line += sraster; 220 inc_ptr(dest, draster); 221 } 222 } 223 return 0; 224 } 225 226 /* Copy a color bitmap. */ 227 private int 228 mem_true32_copy_color(gx_device * dev, 229 const byte * base, int sourcex, int sraster, gx_bitmap_id id, 230 int x, int y, int w, int h) 231 { 232 gx_device_memory * const mdev = (gx_device_memory *)dev; 233 234 fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); 235 mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h); 236 return 0; 237 } 238 239 /* ================ "Word"-oriented device ================ */ 240 241 /* Note that on a big-endian machine, this is the same as the */ 242 /* standard byte-oriented-device. */ 243 244 #if !arch_is_big_endian 245 246 /* Procedures */ 247 declare_mem_procs(mem32_word_copy_mono, mem32_word_copy_color, mem32_word_fill_rectangle); 248 249 /* Here is the device descriptor. */ 250 const gx_device_memory mem_true32_word_device = 251 mem_full_device("image32w", 24, 8, mem_open, 252 gx_default_map_rgb_color, gx_default_map_color_rgb, 253 mem32_word_copy_mono, mem32_word_copy_color, mem32_word_fill_rectangle, 254 gx_default_cmyk_map_cmyk_color, gx_default_strip_tile_rectangle, 255 gx_no_strip_copy_rop, mem_word_get_bits_rectangle); 256 257 /* Fill a rectangle with a color. */ 258 private int 259 mem32_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h, 260 gx_color_index color) 261 { 262 return mem_true32_fill_rectangle(dev, x, y, w, h, 263 color_swap_bytes(color)); 264 } 265 266 /* Copy a bitmap. */ 267 private int 268 mem32_word_copy_mono(gx_device * dev, 269 const byte * base, int sourcex, int sraster, gx_bitmap_id id, 270 int x, int y, int w, int h, gx_color_index zero, gx_color_index one) 271 { 272 return mem_true32_copy_mono(dev, base, sourcex, sraster, id, 273 x, y, w, h, color_swap_bytes(zero), 274 color_swap_bytes(one)); 275 } 276 277 /* Copy a color bitmap. */ 278 private int 279 mem32_word_copy_color(gx_device * dev, 280 const byte * base, int sourcex, int sraster, gx_bitmap_id id, 281 int x, int y, int w, int h) 282 { 283 gx_device_memory * const mdev = (gx_device_memory *)dev; 284 byte *row; 285 uint raster; 286 287 fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); 288 row = scan_line_base(mdev, y); 289 raster = mdev->raster; 290 bytes_copy_rectangle(row + (x << 2), raster, base + (sourcex << 2), 291 sraster, w << 2, h); 292 mem_swap_byte_rect(row, raster, x << 5, w << 5, h, false); 293 return 0; 294 } 295 296 #endif /* !arch_is_big_endian */ 297