Advertisement
Guest User

bANS with support for variable L

a guest
Nov 23rd, 2014
361
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.35 KB | None | 0 0
  1. #define L 48  // between 16 and 48
  2. // The I/O is still 16b-based.
  3.  
  4. size_t bANSEncode(const uint8_t* in, size_t in_size,
  5.                   uint8_t* const buf_start, uint8_t* const buf_end,
  6.                   uint16_t p0) {
  7.   const uint16_t q0 = 0x10000u - p0;
  8.   const uint64_t threshold0 = (uint64_t)p0 << L;
  9.   const uint64_t threshold1 = (uint64_t)q0 << L;
  10.   uint16_t* buf = (uint16_t*)buf_end;
  11.   uint64_t x = 1ull << L;
  12.   int i;
  13.   for (i = in_size - 1; i >= 0; --i) {
  14.     if (x >= (in[i] ? threshold1 : threshold0)) {
  15.       *--buf = x & 0xffff;
  16.       x >>= 16;
  17.     }
  18.     if (in[i]) {
  19.       x = ((x / q0) << 16) + (x % q0) + p0;
  20.     } else {
  21.       x = ((x / p0) << 16) + (x % p0) +  0;
  22.     }
  23.   }
  24.   *--buf = (x >>  0) & 0xffff;
  25.   *--buf = (x >> 16) & 0xffff;
  26.   *--buf = (x >> 32) & 0xffff;
  27.   *--buf = (x >> 48) & 0xffff;
  28.   return buf_end - (uint8_t*)buf;
  29. }
  30.  
  31. void bANSDecode(const uint16_t* ptr, uint8_t* out, size_t in_size, uint16_t p0) {
  32.   int i;
  33.   uint64_t x = 0;
  34.   for (i = 0; i < 4; ++i) x = (x << 16) | *ptr++;
  35.   for (i = 0; i < in_size; ++i) {
  36.     if (x < (1ull << L)) {
  37.       x = (x << 16) | *ptr++;   // decode forward
  38.     }
  39.     const uint16_t xfrac = x & 0xffff;
  40.     const uint64_t x_new = p0 * (x >> 16);
  41.     out[i] = (xfrac >= p0);
  42.     if (xfrac < p0) {
  43.       x = x_new + xfrac;
  44.     } else {
  45.       x -= x_new + p0;
  46.     }
  47.   }
  48. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement