1 /* Copyright (C) 1991, 1995, 1997, 1998, 1999 artofcode LLC. All rights reserved. 2 3 This program is free software; you can redistribute it and/or modify it 4 under the terms of the GNU General Public License as published by the 5 Free Software Foundation; either version 2 of the License, or (at your 6 option) any later version. 7 8 This program is distributed in the hope that it will be useful, but 9 WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along 14 with this program; if not, write to the Free Software Foundation, Inc., 15 59 Temple Place, Suite 330, Boston, MA, 02111-1307. 16 17 */ 18 19 /*$Id: gsbitops.h,v 1.2.6.1.2.1 2003/01/17 00:49:02 giles Exp $ */ 20 /* Interface for bitmap operations */ 21 22 #ifndef gsbitops_INCLUDED 23 # define gsbitops_INCLUDED 24 25 /* ---------------- Pixel processing macros ---------------- */ 26 27 /* 28 * These macros support code that processes data pixel-by-pixel (or, to be 29 * more accurate, packed arrays of values -- they may be complete pixels 30 * or individual components of pixels). 31 * 32 * Supported #s of bits per value (bpv) are 1, 2, 4, 8, 12, 16, 24, 32. 33 * The suffix 8, 12, 16, or 32 on a macro name indicates the maximum value 34 * of bpv that the macro is prepared to handle. 35 * 36 * The setup macros number bits within a byte in big-endian order, i.e., 37 * 0x80 is bit 0, 0x01 is bit 7. However, sbit/dbit may use a different 38 * representation for better performance. ****** NYI ****** 39 */ 40 41 #define sample_end_\ 42 default: return_error(gs_error_rangecheck);\ 43 } END 44 45 /* Declare variables for loading. */ 46 #define sample_load_declare(sptr, sbit)\ 47 const byte *sptr;\ 48 int sbit 49 #define sample_load_declare_setup(sptr, sbit, ptr, bitno, sbpv)\ 50 const byte *sptr = (ptr);\ 51 int sample_load_setup(sbit, bitno, sbpv) 52 53 /* Set up to load starting at a given bit number. */ 54 #define sample_load_setup(sbit, bitno, sbpv)\ 55 sbit = (bitno) 56 57 /* Load a value from memory, without incrementing. */ 58 #define sample_load8_(value, sptr, sbit, sbpv)\ 59 BEGIN\ 60 switch ( (sbpv) >> 2 ) {\ 61 case 0: value = (*(sptr) >> (8 - (sbit) - (sbpv))) & ((sbpv) | 1); break;\ 62 case 1: value = (*(sptr) >> (4 - (sbit))) & 0xf; break;\ 63 case 2: value = *(sptr); break; 64 #define sample_load8(value, sptr, sbit, sbpv)\ 65 sample_load8_(value, sptr, sbit, sbpv)\ 66 sample_end_ 67 #define sample_load_next8(value, sptr, sbit, sbpv)\ 68 sample_load8(value, sptr, sbit, sbpv);\ 69 sample_next(sptr, sbit, sbpv) 70 #define sample_load12_(value, sptr, sbit, sbpv)\ 71 sample_load8_(value, sptr, sbit, sbpv)\ 72 case 3:\ 73 value = ((sbit) ? ((*(sptr) & 0xf) << 8) | (sptr)[1] :\ 74 (*(sptr) << 4) | ((sptr)[1] >> 4));\ 75 break; 76 #define sample_load12(value, sptr, sbit, sbpv)\ 77 sample_load12_(value, sptr, sbit, sbpv)\ 78 sample_end_ 79 #define sample_load_next12(value, sptr, sbit, sbpv)\ 80 sample_load12(value, sptr, sbit, sbpv);\ 81 sample_next(sptr, sbit, sbpv) 82 #define sample_load16_(value, sptr, sbit, sbpv)\ 83 sample_load12_(value, sptr, sbit, sbpv)\ 84 case 4: value = (*(sptr) << 8) | (sptr)[1]; break; 85 #define sample_load16(value, sptr, sbit, sbpv)\ 86 sample_load16_(value, sptr, sbit, sbpv)\ 87 sample_end_ 88 #define sample_load_next16(value, sptr, sbit, sbpv)\ 89 sample_load16(value, sptr, sbit, sbpv);\ 90 sample_next(sptr, sbit, sbpv) 91 #define sample_load32(value, sptr, sbit, sbpv)\ 92 sample_load16_(value, sptr, sbit, sbpv)\ 93 case 6: value = (*(sptr) << 16) | ((sptr)[1] << 8) | (sptr)[2]; break;\ 94 case 8:\ 95 value = (*(sptr) << 24) | ((sptr)[1] << 16) | ((sptr)[2] << 8) | sptr[3];\ 96 break;\ 97 sample_end_ 98 #define sample_load_next32(value, sptr, sbit, sbpv)\ 99 sample_load32(value, sptr, sbit, sbpv);\ 100 sample_next(sptr, sbit, sbpv) 101 102 /* Declare variables for storing. */ 103 #define sample_store_declare(dptr, dbit, dbbyte)\ 104 byte *dptr;\ 105 int dbit;\ 106 byte dbbyte /* maybe should be uint? */ 107 #define sample_store_declare_setup(dptr, dbit, dbbyte, ptr, bitno, dbpv)\ 108 byte *dptr = (ptr);\ 109 int sample_store_setup(dbit, bitno, dbpv);\ 110 byte /* maybe should be uint? */\ 111 sample_store_preload(dbbyte, dptr, dbit, dbpv) 112 113 /* Set up to store starting at a given bit number. */ 114 #define sample_store_setup(dbit, bitno, dbpv)\ 115 dbit = (bitno) 116 117 /* Prepare for storing by preloading any partial byte. */ 118 #define sample_store_preload(dbbyte, dptr, dbit, dbpv)\ 119 dbbyte = ((dbit) ? (byte)(*(dptr) & (0xff00 >> (dbit))) : 0) 120 121 /* Store a value and increment the pointer. */ 122 #define sample_store_next8_(value, dptr, dbit, dbpv, dbbyte)\ 123 BEGIN\ 124 switch ( (dbpv) >> 2 ) {\ 125 case 0:\ 126 if ( (dbit += (dbpv)) == 8 )\ 127 *(dptr)++ = dbbyte | (value), dbbyte = 0, dbit = 0;\ 128 else dbbyte |= (value) << (8 - dbit);\ 129 break;\ 130 case 1:\ 131 if ( dbit ^= 4 ) dbbyte = (byte)((value) << 4);\ 132 else *(dptr)++ = dbbyte | (value);\ 133 break;\ 134 /* case 2 is deliberately omitted */ 135 #define sample_store_next8(value, dptr, dbit, dbpv, dbbyte)\ 136 sample_store_next8_(value, dptr, dbit, dbpv, dbbyte)\ 137 case 2: *(dptr)++ = (byte)(value); break;\ 138 sample_end_ 139 #define sample_store_next_12_(value, dptr, dbit, dbbyte)\ 140 if ( dbit ^= 4 ) *(dptr)++ = (value) >> 4, dbbyte = (byte)((value) << 4);\ 141 else\ 142 *(dptr) = dbbyte | ((value) >> 8), (dptr)[1] = (byte)(value), dptr += 2; 143 #define sample_store_next_12(value, dptr, dbit, dbbyte)\ 144 BEGIN sample_store_next_12_(value, dptr, dbit, dbbyte) END 145 #define sample_store_next12_(value, dptr, dbit, dbpv, dbbyte)\ 146 sample_store_next8_(value, dptr, dbit, dbpv, dbbyte)\ 147 /* case 2 is deliberately omitted */\ 148 case 3: sample_store_next_12_(value, dptr, dbit, dbbyte) break; 149 #define sample_store_next12(value, dptr, dbit, dbpv, dbbyte)\ 150 sample_store_next12_(value, dptr, dbit, dbpv, dbbyte)\ 151 case 2: *(dptr)++ = (byte)(value); break;\ 152 sample_end_ 153 #define sample_store_next16(value, dptr, dbit, dbpv, dbbyte)\ 154 sample_store_next12_(value, dptr, dbit, dbpv, dbbyte)\ 155 case 4: *(dptr)++ = (byte)((value) >> 8);\ 156 case 2: *(dptr)++ = (byte)(value); break;\ 157 sample_end_ 158 #define sample_store_next32(value, dptr, dbit, dbpv, dbbyte)\ 159 sample_store_next12_(value, dptr, dbit, dbpv, dbbyte)\ 160 case 8: *(dptr)++ = (byte)((value) >> 24);\ 161 case 6: *(dptr)++ = (byte)((value) >> 16);\ 162 case 4: *(dptr)++ = (byte)((value) >> 8);\ 163 case 2: *(dptr)++ = (byte)(value); break;\ 164 sample_end_ 165 166 /* Skip over storing one sample. This may or may not store into the */ 167 /* skipped region. */ 168 #define sample_store_skip_next(dptr, dbit, dbpv, dbbyte)\ 169 if ( (dbpv) < 8 ) {\ 170 sample_store_flush(dptr, dbit, dbpv, dbbyte);\ 171 sample_next(dptr, dbit, dbpv);\ 172 } else dptr += ((dbpv) >> 3) 173 174 /* Finish storing by flushing any partial byte. */ 175 #define sample_store_flush(dptr, dbit, dbpv, dbbyte)\ 176 if ( (dbit) != 0 )\ 177 *(dptr) = dbbyte | (*(dptr) & (0xff >> (dbit))); 178 179 /* Increment a pointer to the next sample. */ 180 #define sample_next(ptr, bit, bpv)\ 181 BEGIN bit += (bpv); ptr += bit >> 3; bit &= 7; END 182 183 /* ---------------- Definitions ---------------- */ 184 185 /* 186 * Define the chunk size for monobit filling operations. 187 * This is always uint, regardless of byte order. 188 */ 189 #define mono_fill_chunk uint 190 #define mono_fill_chunk_bytes arch_sizeof_int 191 192 /* ---------------- Procedures ---------------- */ 193 194 /* Fill a rectangle of bits with an 8x1 pattern. */ 195 /* The pattern argument must consist of the pattern in every byte, */ 196 /* e.g., if the desired pattern is 0xaa, the pattern argument must */ 197 /* have the value 0xaaaa (if ints are short) or 0xaaaaaaaa. */ 198 #if mono_fill_chunk_bytes == 2 199 # define mono_fill_make_pattern(byt) (uint)((uint)(byt) * 0x0101) 200 #else 201 # define mono_fill_make_pattern(byt) (uint)((uint)(byt) * 0x01010101) 202 #endif 203 void bits_fill_rectangle(P6(byte * dest, int dest_bit, uint raster, 204 mono_fill_chunk pattern, int width_bits, int height)); 205 206 /* Replicate a bitmap horizontally in place. */ 207 void bits_replicate_horizontally(P6(byte * data, uint width, uint height, 208 uint raster, uint replicated_width, uint replicated_raster)); 209 210 /* Replicate a bitmap vertically in place. */ 211 void bits_replicate_vertically(P4(byte * data, uint height, uint raster, 212 uint replicated_height)); 213 214 /* Find the bounding box of a bitmap. */ 215 void bits_bounding_box(P4(const byte * data, uint height, uint raster, 216 gs_int_rect * pbox)); 217 218 /* Compress an oversampled image, possibly in place. */ 219 /* The width and height must be multiples of the respective scale factors. */ 220 /* The source must be an aligned bitmap, as usual. */ 221 void bits_compress_scaled(P9(const byte * src, int srcx, uint width, 222 uint height, uint sraster, byte * dest, uint draster, 223 const gs_log2_scale_point * plog2_scale, int log2_out_bits)); 224 225 /* Extract a plane from a pixmap. */ 226 typedef struct bits_plane_s { 227 union bpd_ { /* Bit planes must be aligned. */ 228 byte *write; 229 const byte *read; 230 } data; 231 int raster; 232 int depth; 233 int x; /* starting x */ 234 } bits_plane_t; 235 int bits_extract_plane(P5(const bits_plane_t *dest /*write*/, 236 const bits_plane_t *source /*read*/, int shift, int width, int height)); 237 238 /* Expand a plane into a pixmap. */ 239 int bits_expand_plane(P5(const bits_plane_t *dest /*write*/, 240 const bits_plane_t *source /*read*/, int shift, int width, int height)); 241 242 /* Fill a rectangle of bytes. */ 243 void bytes_fill_rectangle(P5(byte * dest, uint raster, 244 byte value, int width_bytes, int height)); 245 246 /* Copy a rectangle of bytes. */ 247 void bytes_copy_rectangle(P6(byte * dest, uint dest_raster, 248 const byte * src, uint src_raster, int width_bytes, int height)); 249 250 #endif /* gsbitops_INCLUDED */ 251