37 lines
1.8 KiB
C
37 lines
1.8 KiB
C
// optimized version from: http://jinruhe.com/
|
|
static int s16_cnum[16] = {28, 21, 21, 21, 14, 9, 8, 7, 6, 6, 5, 5, 4, 3, 2, 1};
|
|
static int s16_cbits[16][28] = {
|
|
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
|
|
{2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0},
|
|
{1,1,1,1,1,1,1,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,0,0,0,0,0,0},
|
|
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,0,0,0,0,0,0,0},
|
|
{2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
|
{4,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
|
{3,4,4,4,4,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
|
{4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
|
{5,5,5,5,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
|
{4,4,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
|
{6,6,6,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
|
{5,5,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
|
{7,7,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
|
{10,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
|
{14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
|
{28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} };
|
|
|
|
#define S16ENC(__w, __p, m) { unsigned *_p = __p, *_w = __w; \
|
|
unsigned int _k, _j, _m, _o; \
|
|
for (_k = 0; _k < 16; _k++) { \
|
|
*_w = _k<<28; \
|
|
_m = (s16_cnum[_k] < m)? s16_cnum[_k]:m; \
|
|
for (_j = 0, _o = 0; (_j < _m) && (*(_p+_j) < (1<<s16_cbits[_k][_j])); ) { \
|
|
*_w += ((*(_p+_j))<<_o); \
|
|
_o += s16_cbits[_k][_j]; \
|
|
_j++; \
|
|
} \
|
|
if(_j == _m) { _p += _m; _w++; break; } \
|
|
} __p = _p; __w = _w; \
|
|
} \
|
|
|
|
static inline unsigned char *vs16enc(unsigned *__restrict in, int n, unsigned *__restrict out) { unsigned *in_ = in +n; while(in < in_) S16ENC(out, in, in_ - in); return (unsigned char *)out; }
|
|
|