2
The following code was written by Richard White at STScI and made
3
available for use in CFITSIO in July 1999. These routines were
4
originally contained in 2 source files: rcomp.c and rdecomp.c,
5
and the 'include' file now called ricecomp.h was originally called buffer.h.
8
/*----------------------------------------------------------*/
10
/* START OF SOURCE FILE ORIGINALLY CALLED rcomp.c */
12
/*----------------------------------------------------------*/
13
/* @(#) rcomp.c 1.5 99/03/01 12:40:27 */
14
/* rcomp.c Compress image line using
15
* (1) Difference of adjacent pixels
16
* (2) Rice algorithm coding
18
* Returns number of bytes written to code buffer or
25
#include "ricecomp.h" /* originally included in rcomp.c file (WDP) */
29
static void start_outputing_bits(Buffer *buffer);
30
static int done_outputing_bits(Buffer *buffer);
31
static int output_nbits(Buffer *buffer, int bits, int n);
33
/* this routine used to be called 'rcomp' (WDP) */
35
int fits_rcomp(int a[], /* input array */
36
int nx, /* number of input pixels */
37
unsigned char *c, /* output buffer */
38
int clen, /* max length of output */
39
int nblock) /* coding block size */
41
Buffer bufmem, *buffer = &bufmem;
42
int bsize, i, j, thisblock;
43
int lastpix, nextpix, pdiff;
44
int v, fs, fsmask, top, fsmax, fsbits, bbits;
45
int lbitbuffer, lbits_to_go;
47
double pixelsum, dpsum;
51
* Original size of each pixel (bsize, bytes) and coding block
52
* size (nblock, pixels)
53
* Could make bsize a parameter to allow more efficient
54
* compression of short & byte images.
60
* FSBITS = # bits required to store FS
61
* FSMAX = maximum value for FS
62
* BBITS = bits/pixel for direct coding
78
ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes");
84
* Set up buffer pointers
89
buffer->bits_to_go = 8;
91
* array for differences mapped to non-negative values
93
diff = (unsigned int *) malloc(nblock*sizeof(unsigned int));
94
if (diff == (unsigned int *) NULL) {
95
ffpmsg("fits_rcomp: insufficient memory");
99
* Code in blocks of nblock pixels
101
start_outputing_bits(buffer);
103
/* write out first int value to the first 4 bytes of the buffer */
104
if (output_nbits(buffer, a[0], 32) == EOF) {
105
ffpmsg("rice_encode: end of buffer");
110
lastpix = a[0]; /* the first difference will always be zero */
113
for (i=0; i<nx; i += nblock) {
114
/* last block may be shorter */
115
if (nx-i < nblock) thisblock = nx-i;
117
* Compute differences of adjacent pixels and map them to unsigned values.
118
* Note that this may overflow the integer variables -- that's
119
* OK, because we can recover when decompressing. If we were
120
* compressing shorts or bytes, would want to do this arithmetic
121
* with short/byte working variables (though diff will still be
124
* compute sum of mapped pixel values at same time
125
* use double precision for sum to allow 32-bit integer inputs
128
for (j=0; j<thisblock; j++) {
130
pdiff = nextpix - lastpix;
131
diff[j] = (unsigned int) ((pdiff<0) ? ~(pdiff<<1) : (pdiff<<1));
136
* compute number of bits to split from sum
138
dpsum = (pixelsum - (thisblock/2) - 1)/thisblock;
139
if (dpsum < 0) dpsum = 0.0;
140
psum = ((unsigned int) dpsum ) >> 1;
141
for (fs = 0; psum>0; fs++) psum >>= 1;
144
* fsbits ID bits used to indicate split level
147
/* Special high entropy case when FS >= fsmax
148
* Just write pixel difference values directly, no Rice coding at all.
150
if (output_nbits(buffer, fsmax+1, fsbits) == EOF) {
151
ffpmsg("rice_encode: end of buffer");
155
for (j=0; j<thisblock; j++) {
156
if (output_nbits(buffer, diff[j], bbits) == EOF) {
157
ffpmsg("rice_encode: end of buffer");
162
} else if (fs == 0 && pixelsum == 0) {
164
* special low entropy case when FS = 0 and pixelsum=0 (all
165
* pixels in block are zero.)
166
* Output a 0 and return
168
if (output_nbits(buffer, 0, fsbits) == EOF) {
169
ffpmsg("rice_encode: end of buffer");
174
/* normal case: not either very high or very low entropy */
175
if (output_nbits(buffer, fs+1, fsbits) == EOF) {
176
ffpmsg("rice_encode: end of buffer");
180
fsmask = (1<<fs) - 1;
182
* local copies of bit buffer to improve optimization
184
lbitbuffer = buffer->bitbuffer;
185
lbits_to_go = buffer->bits_to_go;
186
for (j=0; j<thisblock; j++) {
190
* top is coded by top zeros + 1
192
if (lbits_to_go >= top+1) {
193
lbitbuffer <<= top+1;
195
lbits_to_go -= top+1;
197
lbitbuffer <<= lbits_to_go;
198
if (putcbuf(lbitbuffer & 0xff,buffer) == EOF) {
199
ffpmsg("rice_encode: end of buffer");
203
for (top -= lbits_to_go; top>=8; top -= 8) {
204
if (putcbuf(0, buffer) == EOF) {
205
ffpmsg("rice_encode: end of buffer");
214
* bottom FS bits are written without coding
215
* code is output_nbits, moved into this routine to reduce overheads
216
* This code potentially breaks if FS>24, so I am limiting
217
* FS to 24 by choice of FSMAX above.
221
lbitbuffer |= v & fsmask;
223
while (lbits_to_go <= 0) {
224
if (putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer)==EOF) {
225
ffpmsg("rice_encode: end of buffer");
233
buffer->bitbuffer = lbitbuffer;
234
buffer->bits_to_go = lbits_to_go;
237
done_outputing_bits(buffer);
240
* return number of bytes used
242
return(buffer->current - buffer->start);
244
/*---------------------------------------------------------------------------*/
247
* Bit output routines
248
* Procedures return zero on success, EOF on end-of-buffer
250
* Programmer: R. White Date: 20 July 1998
253
/* Initialize for bit output */
255
static void start_outputing_bits(Buffer *buffer)
258
* Buffer is empty to start with
260
buffer->bitbuffer = 0;
261
buffer->bits_to_go = 8;
264
/*---------------------------------------------------------------------------*/
265
/* Output N bits (N must be <= 32) */
267
static int output_nbits(Buffer *buffer, int bits, int n)
274
* insert bits at end of bitbuffer
276
lbitbuffer = buffer->bitbuffer;
277
lbits_to_go = buffer->bits_to_go;
278
if (lbits_to_go+n > 32) {
280
* special case for large n: put out the top lbits_to_go bits first
281
* note that 0 < lbits_to_go <= 8
283
lbitbuffer <<= lbits_to_go;
284
lbitbuffer |= (bits>>(n-lbits_to_go)) & ((1<<lbits_to_go)-1);
285
if (putcbuf(lbitbuffer & 0xff,buffer) == EOF) return(EOF);
290
lbitbuffer |= ( bits & ((1<<n)-1) );
292
while (lbits_to_go <= 0) {
294
* bitbuffer full, put out top 8 bits
296
if (putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer) == EOF)
300
buffer->bitbuffer = lbitbuffer;
301
buffer->bits_to_go = lbits_to_go;
305
/*---------------------------------------------------------------------------*/
306
/* Flush out the last bits */
308
static int done_outputing_bits(Buffer *buffer)
310
if(buffer->bits_to_go < 8) {
311
if (putcbuf(buffer->bitbuffer<<buffer->bits_to_go,buffer) == EOF)
316
/*---------------------------------------------------------------------------*/
317
/*----------------------------------------------------------*/
319
/* START OF SOURCE FILE ORIGINALLY CALLED rdecomp.c */
321
/*----------------------------------------------------------*/
323
/* @(#) rdecomp.c 1.4 99/03/01 12:38:41 */
324
/* rdecomp.c Decompress image line using
325
* (1) Difference of adjacent pixels
326
* (2) Rice algorithm coding
328
* Returns 0 on success or 1 on failure
331
/* moved these 'includes' to the beginning of the file (WDP)
336
/* this routine used to be called 'rdecomp' (WDP) */
338
int fits_rdecomp (unsigned char *c, /* input buffer */
339
int clen, /* length of input */
340
unsigned int array[], /* output array */
341
int nx, /* number of output pixels */
342
int nblock) /* coding block size */
344
int bsize, i, k, imax;
345
int nbits, nzero, fs;
346
unsigned char *cend, bytevalue;
347
unsigned int b, diff, lastpix;
348
int fsmax, fsbits, bbits;
349
static int *nonzero_count = (int *)NULL;
352
* Original size of each pixel (bsize, bytes) and coding block
353
* size (nblock, pixels)
354
* Could make bsize a parameter to allow more efficient
355
* compression of short & byte images.
361
* FSBITS = # bits required to store FS
362
* FSMAX = maximum value for FS
363
* BBITS = bits/pixel for direct coding
379
ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes");
384
if (nonzero_count == (int *) NULL) {
386
* nonzero_count is lookup table giving number of bits
387
* in 8-bit values not including leading zeros
390
/* NOTE!!! This memory never gets freed */
391
nonzero_count = (int *) malloc(256*sizeof(int));
392
if (nonzero_count == (int *) NULL) {
393
ffpmsg("rdecomp: insufficient memory");
398
for (i=255; i>=0; ) {
399
for ( ; i>=k; i--) nonzero_count[i] = nzero;
405
* Decode in blocks of nblock pixels
408
/* first 4 bytes of input buffer contain the value of the first */
409
/* 4 byte integer value, without any encoding */
413
lastpix = lastpix | (bytevalue<<24);
415
lastpix = lastpix | (bytevalue<<16);
417
lastpix = lastpix | (bytevalue<<8);
419
lastpix = lastpix | bytevalue;
424
b = *c++; /* bit buffer */
425
nbits = 8; /* number of bits remaining in b */
426
for (i = 0; i<nx; ) {
427
/* get the FS value from first fsbits */
433
fs = (b >> nbits) - 1;
435
/* loop over the next block */
437
if (imax > nx) imax = nx;
439
/* low-entropy case, all zero differences */
440
for ( ; i<imax; i++) array[i] = lastpix;
441
} else if (fs==fsmax) {
442
/* high-entropy case, directly coded pixel values */
443
for ( ; i<imax; i++) {
446
for (k -= 8; k >= 0; k -= 8) {
458
* undo mapping and differencing
459
* Note that some of these operations will overflow the
460
* unsigned int arithmetic -- that's OK, it all works
461
* out to give the right answers in the output file.
463
if ((diff & 1) == 0) {
468
array[i] = diff+lastpix;
472
/* normal case, Rice coding */
473
for ( ; i<imax; i++) {
474
/* count number of leading zeros */
479
nzero = nbits - nonzero_count[b];
481
/* flip the leading one-bit */
483
/* get the FS trailing bits */
489
diff = (nzero<<fs) | (b>>nbits);
491
/* undo mapping and differencing */
492
if ((diff & 1) == 0) {
497
array[i] = diff+lastpix;
502
ffpmsg("decompression error: hit end of compressed byte stream");
507
ffpmsg("decompression warning: unused bytes at end of compressed buffer");