1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
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 = (uint)(CHAR_BIT * 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 */
bits += _t1(encode_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;
}
|