blob: bf3592741396d5b9074b0b4f93190bfc7120c4ae [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 *
235 * Return length of RLE according to modified ITU-T T.4 from TS 44.060 Table 9.1.10.2
236 * or -1 if no applicable RLE found
237 * N. B: we need explicit bit length to make decoding unambiguous
238*/
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 *
259 * Return proper make-up code word for an uninterrupted sequence of b bits
260 * of length len according to modified ITU-T T.4 from TS 44.060 Table 9.1.10.2 */
261static inline int t4_rle(struct bitvec *bv, unsigned len, bool b)
262{
263 if (len >= 960) {
264 bitvec_set_uint(bv, t4_make_up[b][14], t4_make_up_length[b][14]);
265 return bitvec_set_uint(bv, t4_term[b][len - 960], t4_term_length[b][len - 960]);
266 }
267
268 if (len >= 896) {
269 bitvec_set_uint(bv, t4_make_up[b][13], t4_make_up_length[b][13]);
270 return bitvec_set_uint(bv, t4_term[b][len - 896], t4_term_length[b][len - 896]);
271 }
272
273 if (len >= 832) {
274 bitvec_set_uint(bv, t4_make_up[b][12], t4_make_up_length[b][12]);
275 return bitvec_set_uint(bv, t4_term[b][len - 832], t4_term_length[b][len - 832]);
276 }
277
278 if (len >= 768) {
279 bitvec_set_uint(bv, t4_make_up[b][11], t4_make_up_length[b][11]);
280 return bitvec_set_uint(bv, t4_term[b][len - 768], t4_term_length[b][len - 768]);
281 }
282
283 if (len >= 704) {
284 bitvec_set_uint(bv, t4_make_up[b][10], t4_make_up_length[b][10]);
285 return bitvec_set_uint(bv, t4_term[b][len - 704], t4_term_length[b][len - 704]);
286 }
287
288 if (len >= 640) {
289 bitvec_set_uint(bv, t4_make_up[b][9], t4_make_up_length[b][9]);
290 return bitvec_set_uint(bv, t4_term[b][len - 640], t4_term_length[b][len - 640]);
291 }
292
293 if (len >= 576) {
294 bitvec_set_uint(bv, t4_make_up[b][8], t4_make_up_length[b][8]);
295 return bitvec_set_uint(bv, t4_term[b][len - 576], t4_term_length[b][len - 576]);
296 }
297
298 if (len >= 512) {
299 bitvec_set_uint(bv, t4_make_up[b][7], t4_make_up_length[b][7]);
300 return bitvec_set_uint(bv, t4_term[b][len - 512], t4_term_length[b][len - 512]);
301 }
302
303 if (len >= 448) {
304 bitvec_set_uint(bv, t4_make_up[b][6], t4_make_up_length[b][6]);
305 return bitvec_set_uint(bv, t4_term[b][len - 448], t4_term_length[b][len - 448]);
306 }
307
308 if (len >= 384) {
309 bitvec_set_uint(bv, t4_make_up[b][5], t4_make_up_length[b][5]);
310 return bitvec_set_uint(bv, t4_term[b][len - 384], t4_term_length[b][len - 384]);
311 }
312
313 if (len >= 320) {
314 bitvec_set_uint(bv, t4_make_up[b][4], t4_make_up_length[b][4]);
315 return bitvec_set_uint(bv, t4_term[b][len - 320], t4_term_length[b][len - 320]);
316 }
317
318 if (len >= 256) {
319 bitvec_set_uint(bv, t4_make_up[b][3], t4_make_up_length[b][3]);
320 return bitvec_set_uint(bv, t4_term[b][len - 256], t4_term_length[b][len - 256]);
321 }
322
323 if (len >= 192) {
324 bitvec_set_uint(bv, t4_make_up[b][2], t4_make_up_length[b][2]);
325 return bitvec_set_uint(bv, t4_term[b][len - 192], t4_term_length[b][len - 192]);
326 }
327
328 if (len >= 128) {
329 bitvec_set_uint(bv, t4_make_up[b][1], t4_make_up_length[b][1]);
330 return bitvec_set_uint(bv, t4_term[b][len - 128], t4_term_length[b][len - 128]);
331 }
332
333 if (len >= 64) {
334 bitvec_set_uint(bv, t4_make_up[b][0], t4_make_up_length[b][0]);
335 return bitvec_set_uint(bv, t4_term[b][len - 64], t4_term_length[b][len - 64]);
336 }
337
338 return bitvec_set_uint(bv, t4_term[b][len], t4_term_length[b][len]);
339}
340
341enum dec_state {
342 EXPECT_TERM,
343 TOO_LONG,
344 NEED_MORE_BITS,
345 CORRUPT,
346 OK
347};
348
349static inline enum dec_state _t4_step(struct bitvec *v, uint16_t w, bool b, unsigned bits, bool term_only)
350{
351 if (bits > t4_max_make_up_length[b])
352 return TOO_LONG;
353 if (bits < t4_min_term_length[b])
354 return NEED_MORE_BITS;
355
356 if (term_only) {
357 if (bits > t4_max_term_length[b])
358 return CORRUPT;
359 int t = t4_rle_term(w, b, bits);
360 if (-1 != t) {
361 bitvec_fill(v, t, b ? ONE : ZERO);
362 return OK;
363 }
364 return NEED_MORE_BITS;
365 }
366
367 int m = t4_rle_makeup(w, b, bits);
368 if (-1 != m) {
369 bitvec_fill(v, m, b ? ONE : ZERO);
370 return EXPECT_TERM;
371 }
372
373 m = t4_rle_term(w, b, bits);
374 if (-1 != m) {
375 bitvec_fill(v, m, b ? ONE : ZERO);
376 return OK;
377 }
378
379 return NEED_MORE_BITS;
380}
381
382/*! \brief decode T4-encoded bit vector
383 * Assumes MSB first encoding.
384 * \param[in] in bit vector with encoded data
385 * \param[in] cc color code (whether decoding should start with 1 or 0)
386 * \param[out] out the bit vector to store result into
387 * returns 0 on success, negative value otherwise
388 */
389int osmo_t4_decode(const struct bitvec *in, bool cc, struct bitvec *out)
390{
391 uint8_t orig[in->data_len];
392 struct bitvec vec;
393 vec.data = orig;
394 vec.data_len = in->data_len;
395 bitvec_zero(&vec);
396 memcpy(vec.data, in->data, in->data_len);
397 vec.cur_bit = in->cur_bit;
398
399 /* init decoder using known color code: */
400 unsigned bits = t4_min_term_length[cc];
401 enum dec_state d;
402 int16_t w = bitvec_get_int16_msb(&vec, bits);
403 bool b = cc;
404 bool term_only = false;
405
406 while (vec.cur_bit > 0) {
407 d = _t4_step(out, w, b, bits, term_only);
408
409 switch (d) {
410 case EXPECT_TERM:
411 bitvec_shiftl(&vec, bits);
412 bits = t4_min_term_length[b];
413 w = bitvec_get_int16_msb(&vec, bits);
414 term_only = true;
415 break;
416 case OK:
417 bitvec_shiftl(&vec, bits);
418 bits = t4_min_term_length[!b];
419 w = bitvec_get_int16_msb(&vec, bits);
420 b = !b;
421 term_only = false;
422 break;
423 case NEED_MORE_BITS:
424 bits++;
425 w = bitvec_get_int16_msb(&vec, bits);
426 break;
427 case TOO_LONG:
428 return -E2BIG;
429 case CORRUPT:
430 return -EINVAL;
431 }
432 }
433
434 return 0;
435}
436
437/*! \brief encode bit vector in-place using T4 encoding
438 * Assumes MSB first encoding.
439 * \param[in] bv bit vector to be encoded
440 * returns color code (if the encoding started with 0 or 1) or -1 on failure (encoded is bigger than original)
441 */
442int osmo_t4_encode(struct bitvec *bv)
443{
444 unsigned rl0 = bitvec_rl(bv, false), rl1 = bitvec_rl(bv, true);
445 int r = (rl0 > rl1) ? 0 : 1;
446 uint8_t orig[bv->data_len], tmp[bv->data_len * 2]; /* FIXME: better estimate max possible encoding overhead */
447 struct bitvec comp, vec;
448 comp.data = tmp;
449 comp.data_len = bv->data_len * 2;
450 bitvec_zero(&comp);
451 vec.data = orig;
452 vec.data_len = bv->data_len;
453 bitvec_zero(&vec);
454 memcpy(vec.data, bv->data, bv->data_len);
455 vec.cur_bit = bv->cur_bit;
456
457 while (vec.cur_bit > 0) {
458 if (rl0 > rl1) {
459 bitvec_shiftl(&vec, rl0);
460 t4_rle(&comp, rl0, false);
461 } else {
462 bitvec_shiftl(&vec, rl1);
463 t4_rle(&comp, rl1, true);
464 }
465 /*
466 TODO: implement backtracking for optimal encoding
467 printf(" -> [%d/%d]", comp.cur_bit + vec.cur_bit, bv->cur_bit);
468 */
469 rl0 = bitvec_rl(&vec, false);
470 rl1 = bitvec_rl(&vec, true);
471 }
472 if (comp.cur_bit < bv->cur_bit) {
473 memcpy(bv->data, tmp, bv->data_len);
474 bv->cur_bit = comp.cur_bit;
475 return r;
476 }
477 return -1;
478}
479
480