Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 2000 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: gsbitcom.c,v 1.3 2002/02/21 22:24:52 giles Exp $ */
18
/* Oversampled bitmap compression */
19
#include "std.h"
20
#include "gstypes.h"
21
#include "gdebug.h"
22
#include "gsbitops.h"		/* for prototype */
23
 
24
/*
25
 * Define a compile-time option to reverse nibble order in alpha maps.
26
 * Note that this does not reverse bit order within nibbles.
27
 * This option is here for a very specialized purpose and does not
28
 * interact well with the rest of the code.
29
 */
30
#ifndef ALPHA_LSB_FIRST
31
#  define ALPHA_LSB_FIRST 0
32
#endif
33
 
34
/* Count the number of 1-bits in a half-byte. */
35
static const byte half_byte_1s[16] = {
36
    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
37
};
38
 
39
/* Count the number of trailing 1s in an up-to-5-bit value, -1. */
40
static const byte bits5_trailing_1s[32] = {
41
    0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 3,
42
    0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 4
43
};
44
 
45
/* Count the number of leading 1s in an up-to-5-bit value, -1. */
46
static const byte bits5_leading_1s[32] = {
47
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48
    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4
49
};
50
 
51
/*
52
 * Compress a value between 0 and 2^M to a value between 0 and 2^N-1.
53
 * Possible values of M are 1, 2, 3, or 4; of N are 1, 2, and 4.
54
 * The name of the table is compress_count_M_N.
55
 * As noted below, we require that N <= M.
56
 */
57
static const byte compress_1_1[3] = {
58
    0, 1, 1
59
};
60
static const byte compress_2_1[5] = {
61
    0, 0, 1, 1, 1
62
};
63
static const byte compress_2_2[5] = {
64
    0, 1, 2, 2, 3
65
};
66
static const byte compress_3_1[9] = {
67
    0, 0, 0, 0, 1, 1, 1, 1, 1
68
};
69
static const byte compress_3_2[9] = {
70
    0, 0, 1, 1, 2, 2, 2, 3, 3
71
};
72
static const byte compress_4_1[17] = {
73
    0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
74
};
75
static const byte compress_4_2[17] = {
76
    0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3
77
};
78
static const byte compress_4_4[17] = {
79
    0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15
80
};
81
 
82
/* The table of tables is indexed by log2(N) and then by M-1. */
83
static const byte *const compress_tables[4][4] = {
84
    {compress_1_1, compress_2_1, compress_3_1, compress_4_1},
85
    {0, compress_2_2, compress_3_2, compress_4_2},
86
    {0, 0, 0, compress_4_4}
87
};
88
 
89
/*
90
 * Compress an XxY-oversampled bitmap to Nx1 by counting 1-bits.  The X and
91
 * Y oversampling factors are 1, 2, or 4, but may be different.  N, the
92
 * resulting number of (alpha) bits per pixel, may be 1, 2, or 4; we allow
93
 * compression in place, in which case N must not exceed the X oversampling
94
 * factor.  Width and height are the source dimensions, and hence reflect
95
 * the oversampling; both are multiples of the relevant scale factor.  The
96
 * same is true for srcx.
97
 */
98
void
99
bits_compress_scaled(const byte * src, int srcx, uint width, uint height,
100
		     uint sraster, byte * dest, uint draster,
101
		     const gs_log2_scale_point *plog2_scale, int log2_out_bits)
102
{
103
    int log2_x = plog2_scale->x, log2_y = plog2_scale->y;
104
    int xscale = 1 << log2_x;
105
    int yscale = 1 << log2_y;
106
    int out_bits = 1 << log2_out_bits;
107
    /*
108
     * The following two initializations are only needed (and the variables
109
     * are only used) if out_bits <= xscale.  We do them in all cases only
110
     * to suppress bogus "possibly uninitialized variable" warnings from
111
     * certain compilers.
112
     */
113
    int input_byte_out_bits = out_bits << (3 - log2_x);
114
    byte input_byte_out_mask = (1 << input_byte_out_bits) - 1;
115
    const byte *table =
116
	compress_tables[log2_out_bits][log2_x + log2_y - 1];
117
    uint sskip = sraster << log2_y;
118
    uint dwidth = (width >> log2_x) << log2_out_bits;
119
    uint dskip = draster - ((dwidth + 7) >> 3);
120
    uint mask = (1 << xscale) - 1;
121
    uint count_max = 1 << (log2_x + log2_y);
122
    /*
123
     * For the moment, we don't attempt to take advantage of the fact
124
     * that the input is aligned.
125
     */
126
    const byte *srow = src + (srcx >> 3);
127
    int in_shift_initial = 8 - xscale - (srcx & 7);
128
    int in_shift_check = (out_bits <= xscale ? 8 - xscale : -1);
129
    byte *d = dest;
130
    uint h;
131
 
132
    for (h = height; h; srow += sskip, h -= yscale) {
133
	const byte *s = srow;
134
 
135
#if ALPHA_LSB_FIRST
136
#  define out_shift_initial 0
137
#  define out_shift_update(out_shift, nbits) ((out_shift += (nbits)) >= 8)
138
#else
139
#  define out_shift_initial (8 - out_bits)
140
#  define out_shift_update(out_shift, nbits) ((out_shift -= (nbits)) < 0)
141
#endif
142
	int out_shift = out_shift_initial;
143
	byte out = 0;
144
	int in_shift = in_shift_initial;
145
	int dw = 8 - (srcx & 7);
146
	int w;
147
 
148
	/* Loop over source bytes. */
149
	for (w = width; w > 0; w -= dw, dw = 8) {
150
	    int index;
151
	    int in_shift_final = (w >= dw ? 0 : dw - w);
152
 
153
	    /*
154
	     * Check quickly for all-0s or all-1s, but only if each
155
	     * input byte generates no more than one output byte,
156
	     * we're at an input byte boundary, and we're processing
157
	     * an entire input byte (i.e., this isn't a final
158
	     * partial byte.)
159
	     */
160
	    if (in_shift == in_shift_check && in_shift_final == 0)
161
		switch (*s) {
162
		    case 0:
163
			for (index = sraster; index != sskip; index += sraster)
164
			    if (s[index] != 0)
165
				goto p;
166
			if (out_shift_update(out_shift, input_byte_out_bits))
167
			    *d++ = out, out_shift &= 7, out = 0;
168
			s++;
169
			continue;
170
#if !ALPHA_LSB_FIRST		/* too messy to make it work */
171
		    case 0xff:
172
			for (index = sraster; index != sskip; index += sraster)
173
			    if (s[index] != 0xff)
174
				goto p;
175
			{
176
			    int shift =
177
				(out_shift -= input_byte_out_bits) + out_bits;
178
 
179
			    if (shift > 0)
180
				out |= input_byte_out_mask << shift;
181
			    else {
182
				out |= input_byte_out_mask >> -shift;
183
				*d++ = out;
184
				out_shift += 8;
185
				out = input_byte_out_mask << (8 + shift);
186
			    }
187
			}
188
			s++;
189
			continue;
190
#endif
191
		    default:
192
			;
193
		}
194
	  p:			/* Loop over source pixels within a byte. */
195
	    do {
196
		uint count;
197
 
198
		for (index = 0, count = 0; index != sskip;
199
		     index += sraster
200
		    )
201
		    count += half_byte_1s[(s[index] >> in_shift) & mask];
202
		if (count != 0 && table[count] == 0) {	/* Look at adjacent cells to help prevent */
203
		    /* dropouts. */
204
		    uint orig_count = count;
205
		    uint shifted_mask = mask << in_shift;
206
		    byte in;
207
 
208
		    if_debug3('B', "[B]count(%d,%d)=%d\n",
209
			      (width - w) / xscale,
210
			      (height - h) / yscale, count);
211
		    if (yscale > 1) {	/* Look at the next "lower" cell. */
212
			if (h < height && (in = s[0] & shifted_mask) != 0) {
213
			    uint lower;
214
 
215
			    for (index = 0, lower = 0;
216
				 -(index -= sraster) <= sskip &&
217
				 (in &= s[index]) != 0;
218
				)
219
				lower += half_byte_1s[in >> in_shift];
220
			    if_debug1('B', "[B]  lower adds %d\n",
221
				      lower);
222
			    if (lower <= orig_count)
223
				count += lower;
224
			}
225
			/* Look at the next "higher" cell. */
226
			if (h > yscale && (in = s[sskip - sraster] & shifted_mask) != 0) {
227
			    uint upper;
228
 
229
			    for (index = sskip, upper = 0;
230
				 index < sskip << 1 &&
231
				 (in &= s[index]) != 0;
232
				 index += sraster
233
				)
234
				upper += half_byte_1s[in >> in_shift];
235
			    if_debug1('B', "[B]  upper adds %d\n",
236
				      upper);
237
			    if (upper < orig_count)
238
				count += upper;
239
			}
240
		    }
241
		    if (xscale > 1) {
242
			uint mask1 = (mask << 1) + 1;
243
 
244
			/* Look at the next cell to the left. */
245
			if (w < width) {
246
			    int lshift = in_shift + xscale - 1;
247
			    uint left;
248
 
249
			    for (index = 0, left = 0;
250
				 index < sskip; index += sraster
251
				) {
252
				uint bits =
253
				((s[index - 1] << 8) +
254
				 s[index]) >> lshift;
255
 
256
				left += bits5_trailing_1s[bits & mask1];
257
			    }
258
			    if_debug1('B', "[B]  left adds %d\n",
259
				      left);
260
			    if (left < orig_count)
261
				count += left;
262
			}
263
			/* Look at the next cell to the right. */
264
			if (w > xscale) {
265
			    int rshift = in_shift - xscale + 8;
266
			    uint right;
267
 
268
			    for (index = 0, right = 0;
269
				 index < sskip; index += sraster
270
				) {
271
				uint bits =
272
				((s[index] << 8) +
273
				 s[index + 1]) >> rshift;
274
 
275
				right += bits5_leading_1s[(bits & mask1) << (4 - xscale)];
276
			    }
277
			    if_debug1('B', "[B]  right adds %d\n",
278
				      right);
279
			    if (right <= orig_count)
280
				count += right;
281
			}
282
		    }
283
		    if (count > count_max)
284
			count = count_max;
285
		}
286
		out += table[count] << out_shift;
287
		if (out_shift_update(out_shift, out_bits))
288
		    *d++ = out, out_shift &= 7, out = 0;
289
	    }
290
	    while ((in_shift -= xscale) >= in_shift_final);
291
	    s++, in_shift += 8;
292
	}
293
	if (out_shift != out_shift_initial)
294
	    *d++ = out;
295
	for (w = dskip; w != 0; w--)
296
	    *d++ = 0;
297
#undef out_shift_initial
298
#undef out_shift_update
299
    }
300
}