#include <limits.h>
static void _t2(inv_xform, Int, DIMS)(Int* p);
static void
_t1(inv_lift, Int)(Int* p, ptrdiff_t s)
{
Int x, y, z, w;
x = *p; p += s;
y = *p; p += s;
z = *p; p += s;
w = *p; p += s;
y += w >> 1; w -= y >> 1;
y += w; w <<= 1; w -= y;
z += x; x <<= 1; x -= z;
y += z; z <<= 1; z -= y;
w += x; x <<= 1; x -= w;
p -= s; *p = w;
p -= s; *p = z;
p -= s; *p = y;
p -= s; *p = x;
}
#if ZFP_ROUNDING_MODE == ZFP_ROUND_LAST
static void
_t1(inv_round, UInt)(UInt* ublock, uint n, uint m, uint prec)
{
if (prec < (uint)(CHAR_BIT * sizeof(UInt) - 1)) {
n -= m;
while (m--) *ublock++ += ((NBMASK >> 2) >> prec);
while (n--) *ublock++ += ((NBMASK >> 1) >> prec);
}
}
#endif
static Int
_t1(uint2int, UInt)(UInt x)
{
return (Int)((x ^ NBMASK) - NBMASK);
}
static void
_t1(inv_order, Int)(const UInt* ublock, Int* iblock, const uchar* perm, uint n)
{
do
iblock[*perm++] = _t1(uint2int, UInt)(*ublock++);
while (--n);
}
static uint
_t1(decode_few_ints, UInt)(bitstream* restrict_ stream, uint maxbits, uint maxprec, UInt* restrict_ data, uint size)
{
bitstream s = *stream;
uint intprec = (uint)(CHAR_BIT * sizeof(UInt));
uint kmin = intprec > maxprec ? intprec - maxprec : 0;
uint bits = maxbits;
uint i, k, m, n;
uint64 x;
for (i = 0; i < size; i++)
data[i] = 0;
for (k = intprec, m = n = 0; bits && (m = 0, k-- > kmin);) {
m = MIN(n, bits);
bits -= m;
x = stream_read_bits(&s, m);
for (; bits && n < size; n++, m = n) {
bits--;
if (stream_read_bit(&s)) {
for (; bits && n < size - 1; n++) {
bits--;
if (stream_read_bit(&s))
break;
}
x += (uint64)1 << n;
}
else {
m = size;
break;
}
}
for (i = 0; x; i++, x >>= 1)
data[i] += (UInt)(x & 1u) << k;
}
#if ZFP_ROUNDING_MODE == ZFP_ROUND_LAST
_t1(inv_round, UInt)(data, size, m, intprec - k);
#endif
*stream = s;
return maxbits - bits;
}
static uint
_t1(decode_many_ints, UInt)(bitstream* restrict_ stream, uint maxbits, uint maxprec, UInt* restrict_ data, uint size)
{
bitstream s = *stream;
uint intprec = (uint)(CHAR_BIT * sizeof(UInt));
uint kmin = intprec > maxprec ? intprec - maxprec : 0;
uint bits = maxbits;
uint i, k, m, n;
for (i = 0; i < size; i++)
data[i] = 0;
for (k = intprec, m = n = 0; bits && (m = 0, k-- > kmin);) {
m = MIN(n, bits);
bits -= m;
for (i = 0; i < m; i++)
if (stream_read_bit(&s))
data[i] += (UInt)1 << k;
for (; bits && n < size; n++, m = n) {
bits--;
if (stream_read_bit(&s)) {
for (; bits && n < size - 1; n++) {
bits--;
if (stream_read_bit(&s))
break;
}
data[n] += (UInt)1 << k;
}
else {
m = size;
break;
}
}
}
#if ZFP_ROUNDING_MODE == ZFP_ROUND_LAST
_t1(inv_round, UInt)(data, size, m, intprec - k);
#endif
*stream = s;
return maxbits - bits;
}
static uint
_t1(decode_few_ints_prec, UInt)(bitstream* restrict_ stream, uint maxprec, UInt* restrict_ data, uint size)
{
bitstream s = *stream;
size_t offset = stream_rtell(&s);
uint intprec = (uint)(CHAR_BIT * sizeof(UInt));
uint kmin = intprec > maxprec ? intprec - maxprec : 0;
uint i, k, n;
for (i = 0; i < size; i++)
data[i] = 0;
for (k = intprec, n = 0; k-- > kmin;) {
uint64 x = stream_read_bits(&s, n);
for (; n < size && stream_read_bit(&s); x += (uint64)1 << n, n++)
for (; n < size - 1 && !stream_read_bit(&s); n++)
;
for (i = 0; x; i++, x >>= 1)
data[i] += (UInt)(x & 1u) << k;
}
#if ZFP_ROUNDING_MODE == ZFP_ROUND_LAST
_t1(inv_round, UInt)(data, size, 0, intprec - k);
#endif
*stream = s;
return (uint)(stream_rtell(&s) - offset);
}
static uint
_t1(decode_many_ints_prec, UInt)(bitstream* restrict_ stream, uint maxprec, UInt* restrict_ data, uint size)
{
bitstream s = *stream;
size_t offset = stream_rtell(&s);
uint intprec = (uint)(CHAR_BIT * sizeof(UInt));
uint kmin = intprec > maxprec ? intprec - maxprec : 0;
uint i, k, n;
for (i = 0; i < size; i++)
data[i] = 0;
for (k = intprec, n = 0; k-- > kmin;) {
for (i = 0; i < n; i++)
if (stream_read_bit(&s))
data[i] += (UInt)1 << k;
for (; n < size && stream_read_bit(&s); data[n] += (UInt)1 << k, n++)
for (; n < size - 1 && !stream_read_bit(&s); n++)
;
}
#if ZFP_ROUNDING_MODE == ZFP_ROUND_LAST
_t1(inv_round, UInt)(data, size, 0, intprec - k);
#endif
*stream = s;
return (uint)(stream_rtell(&s) - offset);
}
static uint
_t1(decode_ints, UInt)(bitstream* restrict_ stream, uint maxbits, uint maxprec, UInt* restrict_ data, uint size)
{
if (with_maxbits(maxbits, maxprec, size)) {
if (size <= 64)
return _t1(decode_few_ints, UInt)(stream, maxbits, maxprec, data, size);
else
return _t1(decode_many_ints, UInt)(stream, maxbits, maxprec, data, size);
}
else {
if (size <= 64)
return _t1(decode_few_ints_prec, UInt)(stream, maxprec, data, size);
else
return _t1(decode_many_ints_prec, UInt)(stream, maxprec, data, size);
}
}
static uint
_t2(decode_block, Int, DIMS)(bitstream* stream, int minbits, int maxbits, int maxprec, Int* iblock)
{
int bits;
cache_align_(UInt ublock[BLOCK_SIZE]);
bits = _t1(decode_ints, UInt)(stream, maxbits, maxprec, ublock, BLOCK_SIZE);
if (bits < minbits) {
stream_skip(stream, minbits - bits);
bits = minbits;
}
_t1(inv_order, Int)(ublock, iblock, PERM, BLOCK_SIZE);
_t2(inv_xform, Int, DIMS)(iblock);
return bits;
}