-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcodec4.c
183 lines (166 loc) · 8.58 KB
/
codec4.c
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include <stdlib.h>
#include <stdint.h>
#include "codec.h"
/* Encoding of centered Gaussian with standard deviation about 165.74 using rANS */
#define TAILCUT 750
static const uint32_t cdt[751] = {
40384, 121149, 201911, 282665, 363408, 444139, 524853, 605548,
686222, 766870, 847490, 928080, 1008636, 1089155, 1169634, 1250072,
1330463, 1410807, 1491099, 1571337, 1651519, 1731640, 1811699, 1891692,
1971617, 2051471, 2131250, 2210953, 2290576, 2370116, 2449571, 2528938,
2608214, 2687396, 2766481, 2845467, 2924352, 3003131, 3081803, 3160365,
3238814, 3317147, 3395363, 3473457, 3551427, 3629272, 3706988, 3784572,
3862022, 3939335, 4016510, 4093542, 4170431, 4247172, 4323764, 4400205,
4476491, 4552620, 4628590, 4704399, 4780043, 4855521, 4930830, 5005969,
5080933, 5155722, 5230333, 5304763, 5379011, 5453073, 5526949, 5600635,
5674130, 5747431, 5820536, 5893443, 5966150, 6038655, 6110955, 6183050,
6254935, 6326611, 6398074, 6469323, 6540356, 6611170, 6681764, 6752137,
6822286, 6892209, 6961904, 7031370, 7100606, 7169608, 7238376, 7306908,
7375202, 7443257, 7511070, 7578641, 7645968, 7713048, 7779881, 7846466,
7912799, 7978881, 8044710, 8110284, 8175602, 8240662, 8305464, 8370005,
8434285, 8498302, 8562055, 8625544, 8688765, 8751719, 8814405, 8876820,
8938965, 9000838, 9062437, 9123763, 9184813, 9245588, 9306085, 9366304,
9426245, 9485905, 9545286, 9604384, 9663201, 9721734, 9779984, 9837949,
9895629, 9953023,10010131,10066951,10123484,10179728,10235683,10291348,
10346724,10401809,10456603,10511105,10565316,10619235,10672860,10726193,
10779233,10831978,10884430,10936588,10988451,11040020,11091294,11142273,
11192956,11243345,11293438,11343235,11392737,11441944,11490855,11539470,
11587790,11635815,11683543,11730977,11778115,11824959,11871507,11917761,
11963720,12009385,12054755,12099832,12144615,12189105,12233302,12277206,
12320818,12364138,12407166,12449903,12492350,12534506,12576373,12617950,
12659238,12700238,12740950,12781375,12821513,12861366,12900932,12940214,
12979211,13017925,13056356,13094505,13132372,13169958,13207265,13244291,
13281039,13317510,13353703,13389620,13425261,13460628,13495721,13530541,
13565089,13599365,13633372,13667109,13700577,13733778,13766712,13799381,
13831784,13863924,13895802,13927417,13958772,13989867,14020703,14051282,
14081604,14111671,14141483,14171041,14200347,14229403,14258207,14286763,
14315071,14343133,14370948,14398519,14425847,14452933,14479778,14506383,
14532749,14558878,14584770,14610428,14635852,14661043,14686002,14710732,
14735232,14759505,14783552,14807373,14830970,14854344,14877497,14900430,
14923144,14945640,14967920,14989985,15011836,15033474,15054901,15076118,
15097127,15117928,15138523,15158913,15179100,15199085,15218868,15238452,
15257838,15277027,15296021,15314820,15333426,15351840,15370064,15388099,
15405946,15423606,15441082,15458373,15475482,15492410,15509158,15525728,
15542120,15558336,15574377,15590245,15605941,15621467,15636822,15652010,
15667031,15681886,15696577,15711104,15725470,15739676,15753723,15767611,
15781343,15794920,15808343,15821613,15834731,15847699,15860518,15873189,
15885714,15898093,15910329,15922421,15934372,15946183,15957854,15969388,
15980785,15992046,16003173,16014168,16025030,16035761,16046363,16056837,
16067184,16077404,16087500,16097472,16107322,16117050,16126658,16136148,
16145519,16154773,16163912,16172936,16181847,16190645,16199332,16207909,
16216377,16224737,16232990,16241138,16249180,16257119,16264955,16272690,
16280324,16287858,16295294,16302633,16309875,16317021,16324073,16331032,
16337898,16344673,16351357,16357952,16364458,16370876,16377208,16383454,
16389615,16395692,16401686,16407599,16413430,16419181,16424853,16430446,
16435962,16441401,16446764,16452052,16457267,16462408,16467476,16472473,
16477400,16482256,16487044,16491763,16496414,16500999,16505519,16509973,
16514362,16518689,16522952,16527154,16531294,16535373,16539393,16543354,
16547257,16551102,16554890,16558621,16562298,16565919,16569487,16573001,
16576462,16579871,16583229,16586536,16589793,16593000,16596159,16599269,
16602332,16605348,16608317,16611241,16614119,16616953,16619743,16622490,
16625194,16627855,16630475,16633054,16635592,16638091,16640549,16642969,
16645351,16647694,16650000,16652270,16654503,16656700,16658862,16660988,
16663081,16665140,16667165,16669157,16671117,16673045,16674941,16676806,
16678641,16680445,16682219,16683964,16685681,16687368,16689028,16690659,
16692264,16693841,16695392,16696917,16698417,16699890,16701339,16702764,
16704164,16705540,16706892,16708222,16709529,16710813,16712075,16713315,
16714534,16715732,16716908,16718065,16719201,16720317,16721414,16722492,
16723550,16724590,16725612,16726615,16727601,16728569,16729520,16730454,
16731371,16732272,16733156,16734025,16734878,16735716,16736538,16737346,
16738139,16738918,16739682,16740432,16741169,16741892,16742602,16743299,
16743983,16744654,16745313,16745959,16746594,16747217,16747828,16748427,
16749016,16749593,16750160,16750716,16751261,16751796,16752321,16752836,
16753341,16753837,16754323,16754800,16755268,16755726,16756176,16756617,
16757050,16757474,16757891,16758299,16758699,16759091,16759476,16759853,
16760222,16760585,16760940,16761289,16761630,16761965,16762293,16762614,
16762930,16763238,16763541,16763838,16764129,16764414,16764693,16764966,
16765234,16765497,16765754,16766006,16766253,16766495,16766733,16766965,
16767192,16767415,16767633,16767847,16768056,16768261,16768462,16768659,
16768851,16769040,16769225,16769405,16769582,16769756,16769925,16770091,
16770254,16770413,16770569,16770722,16770871,16771017,16771160,16771300,
16771437,16771571,16771703,16771831,16771957,16772080,16772200,16772318,
16772433,16772546,16772656,16772764,16772869,16772973,16773074,16773172,
16773269,16773363,16773456,16773546,16773635,16773721,16773806,16773888,
16773969,16774048,16774126,16774201,16774275,16774347,16774418,16774487,
16774554,16774620,16774685,16774748,16774810,16774870,16774929,16774986,
16775042,16775097,16775151,16775203,16775255,16775305,16775354,16775401,
16775448,16775494,16775538,16775582,16775624,16775666,16775707,16775746,
16775785,16775823,16775860,16775896,16775931,16775965,16775999,16776032,
16776064,16776095,16776126,16776155,16776184,16776213,16776241,16776268,
16776294,16776320,16776345,16776370,16776394,16776417,16776440,16776462,
16776484,16776505,16776526,16776546,16776566,16776585,16776604,16776622,
16776640,16776657,16776674,16776691,16776707,16776723,16776738,16776753,
16776768,16776782,16776796,16776810,16776823,16776836,16776848,16776861,
16776873,16776884,16776896,16776907,16776918,16776928,16776938,16776948,
16776958,16776968,16776977,16776986,16776995,16777003,16777012,16777020,
16777028,16777036,16777043,16777050,16777058,16777065,16777071,16777078,
16777084,16777091,16777097,16777103,16777109,16777114,16777120,16777125,
16777130,16777135,16777140,16777145,16777150,16777154,16777159,16777163,
16777167,16777172,16777176,16777179,16777183,16777187,16777191,16777194,
16777197,16777201,16777204,16777207,16777210,16777213,16777216,
};
size_t enc(uint8_t *r, int64_t *v, size_t len) {
uint8_t *r1;
uint32_t a,s,f;
uint64_t state,high,low;
size_t i;
state = 0;
r1 = r;
for(i=0;i<len;i++) {
s = (uint64_t)v[i] >> 63; // sign
a = (v[i] ^ -(int64_t)s) + s; // absolute value
if(a > TAILCUT) return 0;
f = (a==0) ? cdt[0] : (cdt[a]-cdt[a-1])/2; // frequency
while(state >= ((uint64_t)f << (64-24))) {
*(r1++) = (uint8_t)state;
state >>= 8;
}
high = state/f; // Precompute inverses?
low = state - high*f;
if(a==0)
state = (high << 24) + low;
else
state = (high << 24) + (cdt[a-1] + 2*low + s);
}
for(i=0;i<8;i++) {
*(r1++) = (uint8_t)state;
state >>= 8;
}
i = r1-r;
while(r<r1) {
uint8_t tmp = *r;
*(r++) = *(--r1);
*r1 = tmp;
}
return i;
}
void dec(int64_t *r, size_t rlen, uint8_t *in, size_t inlen) {
size_t i;
uint8_t *in1;
uint64_t state = 0;
uint64_t high,low;
uint32_t a,s,f;
in1 = in;
for(i=0;i<8;i++) {
state <<= 8;
state |= *(in1++);
}
for(i=rlen;i;--i) {
low = state & 0xFFFFFF;
high = state >> 24;
a = 0;
while(low >= cdt[a]) a++; //TODO: binary search? Other faster search?
f = (a==0) ? cdt[0] : (cdt[a]-cdt[a-1])/2;
low -= cdt[a-1];
s = low & 1;
if(a==0)
state = high*f + low;
else
state = high*f + low/2;
while(state < (1ULL << 56) && in1 < in+inlen) {
state <<= 8;
state |= *(in1++);
}
r[i-1] = (int64_t)(int32_t)((-s ^ a) + s);
}
}