MythTV master
freesat_huffman.cpp
Go to the documentation of this file.
1#include "freesat_huffman.h"
2
3static constexpr uint8_t START { 255 };
4static constexpr uint8_t STOP { 0 };
5static constexpr uint8_t ESCAPE { 1 };
6
7QString freesat_huffman_to_string(const unsigned char *compressed, uint size)
8{
9 const unsigned char *src = compressed;
10
11 if ((src[1] != 1) && (src[1] != 2))
12 return {""};
13
14 const std::vector<fsattab> &fsat_table = (src[1] == 1) ? fsat_table_1 : fsat_table_2;
15 const std::vector<uint16_t> &fsat_index = (src[1] == 1) ? fsat_index_1 : fsat_index_2;
16
17 QByteArray uncompressed;
18 uncompressed.reserve(size * 3);
19 unsigned value = 0;
20 unsigned byte = 2;
21 unsigned bit = 0;
22 while (byte < 6 && byte < size)
23 {
24 value |= src[byte] << ((5-byte) * 8);
25 byte++;
26 }
27 uchar lastch = START;
28
29 while (lastch != STOP && byte < size+4)
30 {
31 if (lastch == START)
32 lastch = STOP;
33 bool found = false;
34 unsigned bitShift = 0;
35 uchar nextCh = STOP;
36 if (lastch == ESCAPE)
37 {
38 found = true;
39 // Encoded in the next 8 bits.
40 // Terminated by the first ASCII character.
41 nextCh = (value >> 24) & 0xff;
42 bitShift = 8;
43 if ((nextCh & 0x80) == 0)
44 {
45 if (nextCh < ' ')
46 nextCh = STOP;
47 lastch = nextCh;
48 }
49 }
50 else
51 {
52 auto indx = (unsigned)lastch;
53 for (unsigned j = fsat_index[indx]; j < fsat_index[indx+1]; j++)
54 {
55 unsigned mask = 0;
56 unsigned maskbit = 0x80000000;
57 for (uint16_t kk = 0; kk < fsat_table[j].m_bits; kk++)
58 {
59 mask |= maskbit;
60 maskbit >>= 1;
61 }
62 if ((value & mask) == fsat_table[j].m_value)
63 {
64 nextCh = fsat_table[j].m_next;
65 bitShift = fsat_table[j].m_bits;
66 found = true;
67 lastch = nextCh;
68 break;
69 }
70 }
71 }
72 if (found)
73 {
74 if (nextCh != STOP && nextCh != ESCAPE)
75 uncompressed.append(nextCh);
76 // Shift up by the number of bits.
77 for (unsigned b = 0; b < bitShift; b++)
78 {
79 value = (value << 1) & 0xfffffffe;
80 if (byte < size)
81 value |= (src[byte] >> (7-bit)) & 1;
82 if (bit == 7)
83 {
84 bit = 0;
85 byte++;
86 }
87 else
88 {
89 bit++;
90 }
91 }
92 }
93 else
94 {
95 // Entry missing in table.
96 QString result = QString::fromUtf8(uncompressed);
97 result.append("...");
98 return result;
99 }
100 }
101
102 return QString::fromUtf8(uncompressed);
103}
unsigned int uint
Definition: compat.h:60
static constexpr uint8_t ESCAPE
QString freesat_huffman_to_string(const unsigned char *compressed, uint size)
static constexpr uint8_t STOP
static constexpr uint8_t START
const std::vector< fsattab > fsat_table_1
const std::vector< fsattab > fsat_table_2
const std::vector< uint16_t > fsat_index_1
const std::vector< uint16_t > fsat_index_2
unsigned short uint16_t
Definition: iso6937tables.h:3