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