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