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