blob: 8b3090e622a7c6274b1c81b09168e5227368a4b3 [file] [log] [blame]
Max5c18e262016-02-05 13:55:38 +01001/* bit compression routines */
2
3/* (C) 2016 sysmocom s.f.m.c. GmbH by Max Suraev <msuraev@sysmocom.de>
4 *
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
23/*! \defgroup bitcomp Bit compression
24 * @{
25 */
26
27/*! \file bitcomp.c
28 * \brief Osmocom bit compression routines
29 */
30
31#include <stdint.h>
32#include <stdbool.h>
33#include <errno.h>
34#include <string.h>
35
36#include <osmocom/core/bitvec.h>
37#include <osmocom/core/bitcomp.h>
38
39/*
40 * Terminating codes for uninterrupted sequences of 0 and 1 up to 64 bit length
41 * according to TS 44.060 9.1.10
42 */
43static const unsigned t4_term[2][64] = {
44 {
45 0b0000110111,
46 0b10,
47 0b11,
48 0b010,
49 0b011,
50 0b0011,
51 0b0010,
52 0b00011,
53 0b000101,
54 0b000100,
55 0b0000100,
56 0b0000101,
57 0b0000111,
58 0b00000100,
59 0b00000111,
60 0b000011000,
61 0b0000010111,
62 0b0000011000,
63 0b0000001000,
64 0b00001100111,
65 0b00001101000,
66 0b00001101100,
67 0b00000110111,
68 0b00000101000,
69 0b00000010111,
70 0b00000011000,
71 0b000011001010,
72 0b000011001011,
73 0b000011001100,
74 0b000011001101,
75 0b000001101000,
76 0b000001101001,
77 0b000001101010,
78 0b000001101011,
79 0b000011010010,
80 0b000011010011,
81 0b000011010100,
82 0b000011010101,
83 0b000011010110,
84 0b000011010111,
85 0b000001101100,
86 0b000001101101,
87 0b000011011010,
88 0b000011011011,
89 0b000001010100,
90 0b000001010101,
91 0b000001010110,
92 0b000001010111,
93 0b000001100100,
94 0b000001100101,
95 0b000001010010,
96 0b000001010011,
97 0b000000100100,
98 0b000000110111,
99 0b000000111000,
100 0b000000100111,
101 0b000000101000,
102 0b000001011000,
103 0b000001011001,
104 0b000000101011,
105 0b000000101100,
106 0b000001011010,
107 0b000001100110,
108 0b000001100111
109 },
110 {
111 0b00110101,
112 0b000111,
113 0b0111,
114 0b1000,
115 0b1011,
116 0b1100,
117 0b1110,
118 0b1111,
119 0b10011,
120 0b10100,
121 0b00111,
122 0b01000,
123 0b001000,
124 0b000011,
125 0b110100,
126 0b110101,
127 0b101010,
128 0b101011,
129 0b0100111,
130 0b0001100,
131 0b0001000,
132 0b0010111,
133 0b0000011,
134 0b0000100,
135 0b0101000,
136 0b0101011,
137 0b0010011,
138 0b0100100,
139 0b0011000,
140 0b00000010,
141 0b00000011,
142 0b00011010,
143 0b00011011,
144 0b00010010,
145 0b00010011,
146 0b00010100,
147 0b00010101,
148 0b00010110,
149 0b00010111,
150 0b00101000,
151 0b00101001,
152 0b00101010,
153 0b00101011,
154 0b00101100,
155 0b00101101,
156 0b00000100,
157 0b00000101,
158 0b00001010,
159 0b00001011,
160 0b01010010,
161 0b01010011,
162 0b01010100,
163 0b01010101,
164 0b00100100,
165 0b00100101,
166 0b01011000,
167 0b01011001,
168 0b01011010,
169 0b01011011,
170 0b01001010,
171 0b01001011,
172 0b00110010,
173 0b00110011,
174 0b00110100
175 }
176};
177
178static const unsigned t4_term_length[2][64] = {
179 {10, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12},
180 {8, 6, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}
181};
182
183static const unsigned t4_min_term_length[] = {2, 4};
184static const unsigned t4_min_make_up_length[] = {10, 5};
185
186static const unsigned t4_max_term_length[] = {12, 8};
187static const unsigned t4_max_make_up_length[] = {13, 9};
188
189static const unsigned t4_make_up_length[2][15] = {
190 {10, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13},
191 {5, 5, 6, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9}
192};
193
194static const unsigned t4_make_up_ind[15] = {64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960};
195
196static const unsigned t4_make_up[2][15] = {
197 {
198 0b0000001111,
199 0b000011001000,
200 0b000011001001,
201 0b000001011011,
202 0b000000110011,
203 0b000000110100,
204 0b000000110101,
205 0b0000001101100,
206 0b0000001101101,
207 0b0000001001010,
208 0b0000001001011,
209 0b0000001001100,
210 0b0000001001101,
211 0b0000001110010,
212 0b0000001110011
213 },
214 {
215 0b11011,
216 0b10010,
217 0b010111,
218 0b0110111,
219 0b00110110,
220 0b00110111,
221 0b01100100,
222 0b01100101,
223 0b01101000,
224 0b01100111,
225 0b011001100,
226 0b011001101,
227 0b011010010,
228 0b011010011,
229 0b011010100
230 }
231};
232
233/*! \brief Attempt to decode compressed bit vector
234 *
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200235 * \return length of RLE according to modified ITU-T T.4 from TS 44.060
236 * Table 9.1.10.2 or -1 if no applicable RLE found N. B: we need
237 * explicit bit length to make decoding unambiguous
Max5c18e262016-02-05 13:55:38 +0100238*/
239static inline int t4_rle_term(unsigned w, bool b, unsigned bits)
240{
241 unsigned i;
242 for (i = 0; i < 64; i++)
243 if (w == t4_term[b][i] && bits == t4_term_length[b][i])
244 return i;
245 return -1;
246}
247
248static inline int t4_rle_makeup(unsigned w, bool b, unsigned bits)
249{
250 unsigned i;
251 for (i = 0; i < 15; i++)
252 if (w == t4_make_up[b][i] && bits == t4_make_up_length[b][i])
253 return t4_make_up_ind[i];
254 return -1;
255}
256
257/*! \brief Make-up codes for a given length
258 *
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200259 * \return Return proper make-up code word for an uninterrupted
260 * sequence of b bits of length len according to modified ITU-T T.4
261 * from TS 44.060 Table 9.1.10.2 */
Max5c18e262016-02-05 13:55:38 +0100262static inline int t4_rle(struct bitvec *bv, unsigned len, bool b)
263{
264 if (len >= 960) {
265 bitvec_set_uint(bv, t4_make_up[b][14], t4_make_up_length[b][14]);
266 return bitvec_set_uint(bv, t4_term[b][len - 960], t4_term_length[b][len - 960]);
267 }
268
269 if (len >= 896) {
270 bitvec_set_uint(bv, t4_make_up[b][13], t4_make_up_length[b][13]);
271 return bitvec_set_uint(bv, t4_term[b][len - 896], t4_term_length[b][len - 896]);
272 }
273
274 if (len >= 832) {
275 bitvec_set_uint(bv, t4_make_up[b][12], t4_make_up_length[b][12]);
276 return bitvec_set_uint(bv, t4_term[b][len - 832], t4_term_length[b][len - 832]);
277 }
278
279 if (len >= 768) {
280 bitvec_set_uint(bv, t4_make_up[b][11], t4_make_up_length[b][11]);
281 return bitvec_set_uint(bv, t4_term[b][len - 768], t4_term_length[b][len - 768]);
282 }
283
284 if (len >= 704) {
285 bitvec_set_uint(bv, t4_make_up[b][10], t4_make_up_length[b][10]);
286 return bitvec_set_uint(bv, t4_term[b][len - 704], t4_term_length[b][len - 704]);
287 }
288
289 if (len >= 640) {
290 bitvec_set_uint(bv, t4_make_up[b][9], t4_make_up_length[b][9]);
291 return bitvec_set_uint(bv, t4_term[b][len - 640], t4_term_length[b][len - 640]);
292 }
293
294 if (len >= 576) {
295 bitvec_set_uint(bv, t4_make_up[b][8], t4_make_up_length[b][8]);
296 return bitvec_set_uint(bv, t4_term[b][len - 576], t4_term_length[b][len - 576]);
297 }
298
299 if (len >= 512) {
300 bitvec_set_uint(bv, t4_make_up[b][7], t4_make_up_length[b][7]);
301 return bitvec_set_uint(bv, t4_term[b][len - 512], t4_term_length[b][len - 512]);
302 }
303
304 if (len >= 448) {
305 bitvec_set_uint(bv, t4_make_up[b][6], t4_make_up_length[b][6]);
306 return bitvec_set_uint(bv, t4_term[b][len - 448], t4_term_length[b][len - 448]);
307 }
308
309 if (len >= 384) {
310 bitvec_set_uint(bv, t4_make_up[b][5], t4_make_up_length[b][5]);
311 return bitvec_set_uint(bv, t4_term[b][len - 384], t4_term_length[b][len - 384]);
312 }
313
314 if (len >= 320) {
315 bitvec_set_uint(bv, t4_make_up[b][4], t4_make_up_length[b][4]);
316 return bitvec_set_uint(bv, t4_term[b][len - 320], t4_term_length[b][len - 320]);
317 }
318
319 if (len >= 256) {
320 bitvec_set_uint(bv, t4_make_up[b][3], t4_make_up_length[b][3]);
321 return bitvec_set_uint(bv, t4_term[b][len - 256], t4_term_length[b][len - 256]);
322 }
323
324 if (len >= 192) {
325 bitvec_set_uint(bv, t4_make_up[b][2], t4_make_up_length[b][2]);
326 return bitvec_set_uint(bv, t4_term[b][len - 192], t4_term_length[b][len - 192]);
327 }
328
329 if (len >= 128) {
330 bitvec_set_uint(bv, t4_make_up[b][1], t4_make_up_length[b][1]);
331 return bitvec_set_uint(bv, t4_term[b][len - 128], t4_term_length[b][len - 128]);
332 }
333
334 if (len >= 64) {
335 bitvec_set_uint(bv, t4_make_up[b][0], t4_make_up_length[b][0]);
336 return bitvec_set_uint(bv, t4_term[b][len - 64], t4_term_length[b][len - 64]);
337 }
338
339 return bitvec_set_uint(bv, t4_term[b][len], t4_term_length[b][len]);
340}
341
342enum dec_state {
343 EXPECT_TERM,
344 TOO_LONG,
345 NEED_MORE_BITS,
346 CORRUPT,
347 OK
348};
349
350static inline enum dec_state _t4_step(struct bitvec *v, uint16_t w, bool b, unsigned bits, bool term_only)
351{
352 if (bits > t4_max_make_up_length[b])
353 return TOO_LONG;
354 if (bits < t4_min_term_length[b])
355 return NEED_MORE_BITS;
356
357 if (term_only) {
358 if (bits > t4_max_term_length[b])
359 return CORRUPT;
360 int t = t4_rle_term(w, b, bits);
361 if (-1 != t) {
362 bitvec_fill(v, t, b ? ONE : ZERO);
363 return OK;
364 }
365 return NEED_MORE_BITS;
366 }
367
368 int m = t4_rle_makeup(w, b, bits);
369 if (-1 != m) {
370 bitvec_fill(v, m, b ? ONE : ZERO);
371 return EXPECT_TERM;
372 }
373
374 m = t4_rle_term(w, b, bits);
375 if (-1 != m) {
376 bitvec_fill(v, m, b ? ONE : ZERO);
377 return OK;
378 }
379
380 return NEED_MORE_BITS;
381}
382
383/*! \brief decode T4-encoded bit vector
384 * Assumes MSB first encoding.
385 * \param[in] in bit vector with encoded data
386 * \param[in] cc color code (whether decoding should start with 1 or 0)
387 * \param[out] out the bit vector to store result into
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200388 * \return 0 on success, negative value otherwise
Max5c18e262016-02-05 13:55:38 +0100389 */
390int osmo_t4_decode(const struct bitvec *in, bool cc, struct bitvec *out)
391{
392 uint8_t orig[in->data_len];
393 struct bitvec vec;
394 vec.data = orig;
395 vec.data_len = in->data_len;
396 bitvec_zero(&vec);
397 memcpy(vec.data, in->data, in->data_len);
398 vec.cur_bit = in->cur_bit;
399
400 /* init decoder using known color code: */
401 unsigned bits = t4_min_term_length[cc];
402 enum dec_state d;
403 int16_t w = bitvec_get_int16_msb(&vec, bits);
404 bool b = cc;
405 bool term_only = false;
406
407 while (vec.cur_bit > 0) {
408 d = _t4_step(out, w, b, bits, term_only);
409
410 switch (d) {
411 case EXPECT_TERM:
412 bitvec_shiftl(&vec, bits);
413 bits = t4_min_term_length[b];
414 w = bitvec_get_int16_msb(&vec, bits);
415 term_only = true;
416 break;
417 case OK:
418 bitvec_shiftl(&vec, bits);
419 bits = t4_min_term_length[!b];
420 w = bitvec_get_int16_msb(&vec, bits);
421 b = !b;
422 term_only = false;
423 break;
424 case NEED_MORE_BITS:
425 bits++;
426 w = bitvec_get_int16_msb(&vec, bits);
427 break;
428 case TOO_LONG:
429 return -E2BIG;
430 case CORRUPT:
431 return -EINVAL;
432 }
433 }
434
435 return 0;
436}
437
438/*! \brief encode bit vector in-place using T4 encoding
439 * Assumes MSB first encoding.
440 * \param[in] bv bit vector to be encoded
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200441 * \return color code (if the encoding started with 0 or 1) or -1 on
442 * failure (encoded is bigger than original)
Max5c18e262016-02-05 13:55:38 +0100443 */
444int osmo_t4_encode(struct bitvec *bv)
445{
446 unsigned rl0 = bitvec_rl(bv, false), rl1 = bitvec_rl(bv, true);
447 int r = (rl0 > rl1) ? 0 : 1;
448 uint8_t orig[bv->data_len], tmp[bv->data_len * 2]; /* FIXME: better estimate max possible encoding overhead */
449 struct bitvec comp, vec;
450 comp.data = tmp;
451 comp.data_len = bv->data_len * 2;
452 bitvec_zero(&comp);
453 vec.data = orig;
454 vec.data_len = bv->data_len;
455 bitvec_zero(&vec);
456 memcpy(vec.data, bv->data, bv->data_len);
457 vec.cur_bit = bv->cur_bit;
458
459 while (vec.cur_bit > 0) {
460 if (rl0 > rl1) {
461 bitvec_shiftl(&vec, rl0);
462 t4_rle(&comp, rl0, false);
463 } else {
464 bitvec_shiftl(&vec, rl1);
465 t4_rle(&comp, rl1, true);
466 }
467 /*
468 TODO: implement backtracking for optimal encoding
469 printf(" -> [%d/%d]", comp.cur_bit + vec.cur_bit, bv->cur_bit);
470 */
471 rl0 = bitvec_rl(&vec, false);
472 rl1 = bitvec_rl(&vec, true);
473 }
474 if (comp.cur_bit < bv->cur_bit) {
475 memcpy(bv->data, tmp, bv->data_len);
476 bv->cur_bit = comp.cur_bit;
477 return r;
478 }
479 return -1;
480}
481
482