static void _t2(rev_fwd_xform, Int, DIMS)(Int* p); /* private functions ------------------------------------------------------- */ /* reversible forward lifting transform of 4-vector */ static void _t1(rev_fwd_lift, Int)(Int* p, uint s) { Int x, y, z, w; x = *p; p += s; y = *p; p += s; z = *p; p += s; w = *p; p += s; /* ** high-order Lorenzo transform ** ( 1 0 0 0) (x) ** (-1 1 0 0) (y) ** ( 1 -2 1 0) (z) ** (-1 3 -3 1) (w) */ w -= z; z -= y; y -= x; w -= z; z -= y; w -= z; p -= s; *p = w; p -= s; *p = z; p -= s; *p = y; p -= s; *p = x; } /* return precision required to encode block reversibly */ static uint _t1(rev_precision, UInt)(const UInt* block, uint n) { uint p = 0; uint s; /* compute bitwise OR of all values */ UInt m = 0; while (n--) m |= *block++; /* count trailing zeros via binary search */ for (s = CHAR_BIT * (uint)sizeof(UInt); m; s /= 2) if ((UInt)(m << (s - 1))) { m <<= s - 1; m <<= 1; p += s; } return p; } /* encode block of integers using reversible algorithm */ static uint _t2(rev_encode_block, Int, DIMS)(bitstream* stream, int minbits, int maxbits, int maxprec, Int* iblock) { int bits = PBITS; int prec; cache_align_(UInt ublock[BLOCK_SIZE]); /* perform decorrelating transform */ _t2(rev_fwd_xform, Int, DIMS)(iblock); /* reorder signed coefficients and convert to unsigned integer */ _t1(fwd_order, Int)(ublock, iblock, PERM, BLOCK_SIZE); /* determine and encode number of significant bits */ prec = _t1(rev_precision, UInt)(ublock, BLOCK_SIZE); prec = MIN(prec, maxprec); prec = MAX(prec, 1); stream_write_bits(stream, prec - 1, PBITS); /* encode integer coefficients */ if (BLOCK_SIZE <= 64) bits += _t1(encode_ints, UInt)(stream, maxbits - bits, prec, ublock, BLOCK_SIZE); else bits += _t1(encode_many_ints, UInt)(stream, maxbits - bits, prec, ublock, BLOCK_SIZE); /* write at least minbits bits by padding with zeros */ if (bits < minbits) { stream_pad(stream, minbits - bits); bits = minbits; } return bits; }