File: revencode.c

package info (click to toggle)
c-blosc2 2.23.0%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 14,060 kB
  • sloc: ansic: 46,362; python: 332; lisp: 82; makefile: 36; sh: 3
file content (76 lines) | stat: -rw-r--r-- 1,985 bytes parent folder | download | duplicates (6)
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;
}