1 static void _t2(rev_fwd_xform, Int, DIMS)(Int* p);
2
3 /* private functions ------------------------------------------------------- */
4
5 /* reversible forward lifting transform of 4-vector */
6 static void
_t1(rev_fwd_lift,Int)7 _t1(rev_fwd_lift, Int)(Int* p, uint s)
8 {
9 Int x, y, z, w;
10 x = *p; p += s;
11 y = *p; p += s;
12 z = *p; p += s;
13 w = *p; p += s;
14
15 /*
16 ** high-order Lorenzo transform
17 ** ( 1 0 0 0) (x)
18 ** (-1 1 0 0) (y)
19 ** ( 1 -2 1 0) (z)
20 ** (-1 3 -3 1) (w)
21 */
22 w -= z; z -= y; y -= x;
23 w -= z; z -= y;
24 w -= z;
25
26 p -= s; *p = w;
27 p -= s; *p = z;
28 p -= s; *p = y;
29 p -= s; *p = x;
30 }
31
32 /* return precision required to encode block reversibly */
33 static uint
_t1(rev_precision,UInt)34 _t1(rev_precision, UInt)(const UInt* block, uint n)
35 {
36 uint p = 0;
37 uint s;
38 /* compute bitwise OR of all values */
39 UInt m = 0;
40 while (n--)
41 m |= *block++;
42 /* count trailing zeros via binary search */
43 for (s = CHAR_BIT * (uint)sizeof(UInt); m; s /= 2)
44 if ((UInt)(m << (s - 1))) {
45 m <<= s - 1;
46 m <<= 1;
47 p += s;
48 }
49 return p;
50 }
51
52 /* encode block of integers using reversible algorithm */
53 static uint
_t2(rev_encode_block,Int,DIMS)54 _t2(rev_encode_block, Int, DIMS)(bitstream* stream, int minbits, int maxbits, int maxprec, Int* iblock)
55 {
56 int bits = PBITS;
57 int prec;
58 cache_align_(UInt ublock[BLOCK_SIZE]);
59 /* perform decorrelating transform */
60 _t2(rev_fwd_xform, Int, DIMS)(iblock);
61 /* reorder signed coefficients and convert to unsigned integer */
62 _t1(fwd_order, Int)(ublock, iblock, PERM, BLOCK_SIZE);
63 /* determine and encode number of significant bits */
64 prec = _t1(rev_precision, UInt)(ublock, BLOCK_SIZE);
65 prec = MIN(prec, maxprec);
66 prec = MAX(prec, 1);
67 stream_write_bits(stream, prec - 1, PBITS);
68 /* encode integer coefficients */
69 if (BLOCK_SIZE <= 64)
70 bits += _t1(encode_ints, UInt)(stream, maxbits - bits, prec, ublock, BLOCK_SIZE);
71 else
72 bits += _t1(encode_many_ints, UInt)(stream, maxbits - bits, prec, ublock, BLOCK_SIZE);
73 /* write at least minbits bits by padding with zeros */
74 if (bits < minbits) {
75 stream_pad(stream, minbits - bits);
76 bits = minbits;
77 }
78 return bits;
79 }
80