static void _t2(rev_fwd_xform, Int, DIMS)(Int* p);
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;
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;
}
static uint
_t1(rev_precision, UInt)(const UInt* block, uint n)
{
uint p = 0;
uint s;
UInt m = 0;
while (n--)
m |= *block++;
for (s = (uint)(CHAR_BIT * sizeof(UInt)); m; s /= 2)
if ((UInt)(m << (s - 1))) {
m <<= s - 1;
m <<= 1;
p += s;
}
return p;
}
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]);
_t2(rev_fwd_xform, Int, DIMS)(iblock);
_t1(fwd_order, Int)(ublock, iblock, PERM, BLOCK_SIZE);
prec = _t1(rev_precision, UInt)(ublock, BLOCK_SIZE);
prec = MIN(prec, maxprec);
prec = MAX(prec, 1);
stream_write_bits(stream, prec - 1, PBITS);
bits += _t1(encode_ints, UInt)(stream, maxbits - bits, prec, ublock, BLOCK_SIZE);
if (bits < minbits) {
stream_pad(stream, minbits - bits);
bits = minbits;
}
return bits;
}