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