MythTV  master
freesat_huffman.cpp
Go to the documentation of this file.
1 #include "freesat_huffman.h"
2 
3 #define START '\0'
4 #define STOP '\0'
5 #define ESCAPE '\1'
6 
7 QString 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 QString("");
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.count())
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 bit++;
90  }
91  }
92  else
93  {
94  // Entry missing in table.
95  QString result = QString::fromUtf8(uncompressed, p);
96  result.append("...");
97  return result;
98  }
99  } while (lastch != STOP && byte < size+4);
100 
101  return QString::fromUtf8(uncompressed, p);
102 }
const std::vector< fsattab > fsat_table_2
#define START
QString freesat_huffman_to_string(const unsigned char *compressed, uint size)
#define STOP
#define ESCAPE
const std::vector< uint16_t > fsat_index_1
unsigned int uint
Definition: compat.h:140
const std::vector< fsattab > fsat_table_1
unsigned short uint16_t
Definition: iso6937tables.h:1
const std::vector< uint16_t > fsat_index_2