1 /*
2 * dvbsi.cpp
3 *
4 * Copyright (C) 2008-2011 Christoph Pfister <christophpfister@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "../log.h"
22
23 #include <QTextCodec>
24
25 #include "dvbsi.h"
26
initSection(const char * data,int size)27 void DvbSection::initSection(const char *data, int size)
28 {
29 if (size < 3) {
30 initSectionData();
31 return;
32 }
33
34 int sectionLength = ((((quint8(data[1]) & 0xf) << 8) | quint8(data[2])) + 3);
35
36 if (sectionLength > size) {
37 qCInfo(logDvbSi, "Adjusting length");
38 sectionLength = size;
39 }
40
41 initSectionData(data, sectionLength, size);
42 }
43
verifyCrc32(const char * data,int size)44 int DvbStandardSection::verifyCrc32(const char *data, int size)
45 {
46 unsigned int crc32 = 0xffffffff;
47
48 for (int i = 0; i < size; ++i) {
49 crc32 = ((crc32 << 8) ^ crc32Table[(crc32 >> 24) ^ quint8(data[i])]);
50 }
51
52 return crc32;
53 }
54
55 /*
56 * unsigned int crc32TableValue(int index)
57 * {
58 * unsigned int value = 0;
59 *
60 * for (int i = 8; i >= 0; --i) {
61 * if (((value & 0x80000000) != 0) ^ ((index & (1 << i)) != 0)) {
62 * value = (value << 1) ^ 0x04c11db7;
63 * } else {
64 * value <<= 1;
65 * }
66 * }
67 *
68 * return value;
69 * }
70 */
71
72 const unsigned int DvbStandardSection::crc32Table[] =
73 {
74 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
75 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
76 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
77 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
78 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
79 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
80 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
81 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
82 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
83 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
84 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
85 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
86 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
87 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
88 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
89 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
90 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
91 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
92 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
93 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
94 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
95 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
96 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
97 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
98 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
99 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
100 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
101 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
102 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
103 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
104 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
105 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
106 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
107 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
108 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
109 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
110 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
111 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
112 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
113 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
114 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
115 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
116 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
117 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
118 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
119 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
120 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
121 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
122 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
123 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
124 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
125 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
126 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
127 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
128 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
129 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
130 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
131 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
132 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
133 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
134 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
135 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
136 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
137 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
138 };
139
initStandardSection(const char * data,int size)140 void DvbStandardSection::initStandardSection(const char *data, int size)
141 {
142 if (size < 12) {
143 initSectionData();
144 return;
145 }
146
147 initSection(data, size);
148 }
149
150 class Iso6937Codec : public QTextCodec
151 {
152 public:
Iso6937Codec()153 Iso6937Codec() { }
~Iso6937Codec()154 ~Iso6937Codec() { }
155
name() const156 QByteArray name() const
157 {
158 return "ISO 6937"; // actually a superset of ISO 6937
159 }
160
mibEnum() const161 int mibEnum() const
162 {
163 return 14;
164 }
165
convertFromUnicode(const QChar *,int,QTextCodec::ConverterState *) const166 QByteArray convertFromUnicode(const QChar *, int, QTextCodec::ConverterState *) const
167 {
168 return QByteArray();
169 }
170
convertToUnicode(const char * input,int size,QTextCodec::ConverterState *) const171 QString convertToUnicode(const char *input, int size, QTextCodec::ConverterState *) const
172 {
173 QString result;
174 unsigned short diacriticalMark = 0;
175
176 for (; size > 0; ++input, --size) {
177 unsigned short value = table[quint8(*input)];
178
179 if (value == 0xffff) {
180 continue;
181 }
182
183 if ((value & 0xff00) == 0x0300) {
184 // diacritical mark
185 diacriticalMark = value;
186 continue;
187 }
188
189 result.append(value);
190
191 if (diacriticalMark != 0) {
192 result.append(diacriticalMark);
193 diacriticalMark = 0;
194 }
195 }
196
197 return result.normalized(QString::NormalizationForm_C);
198 }
199
200 private:
201 static const unsigned short table[];
202 };
203
204 const unsigned short Iso6937Codec::table[] = {
205 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
206 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
207 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
208 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
209 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
210 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
211 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
212 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
213 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
214 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
215 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
216 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
217 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
218 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
219 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
220 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
221 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
222 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
223 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
224 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
225 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0xffff, 0x00a7,
226 0x00a4, 0x2018, 0x201c, 0x00ab, 0x2190, 0x2191, 0x2192, 0x2193,
227 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00d7, 0x00b5, 0x00b6, 0x00b7,
228 0x00f7, 0x2019, 0x201d, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
229 0xffff, 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0306, 0x0307,
230 0x0308, 0xffff, 0x030a, 0x0327, 0xffff, 0x030b, 0x0328, 0x030c,
231 0x2015, 0x00b9, 0x00ae, 0x00a9, 0x2122, 0x266a, 0x00ac, 0x00a6,
232 0xffff, 0xffff, 0xffff, 0xffff, 0x215b, 0x215c, 0x215d, 0x215e,
233 0x2126, 0x00c6, 0x0110, 0x00aa, 0x0126, 0xffff, 0x0132, 0x013f,
234 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00de, 0x0166, 0x014a, 0x0149,
235 0x0138, 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0140,
236 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x0167, 0x014b, 0x00ad
237 };
238
convertText(const char * data,int size)239 QString DvbSiText::convertText(const char *data, int size)
240 {
241 TextEncoding encoding = Iso6937;
242
243 if (size < 1) {
244 return QString();
245 }
246
247 if (size >2 && data[0] == 0x0e && data[size - 1] == 0x0f ) {
248 // Remove LS0 and LS1 codes found on some ISDB-T streams
249 data++;
250 size -= 2;
251
252 encoding = Iso8859_1;
253 }
254
255 if (override6937)
256 encoding = Iso8859_1;
257
258 if (quint8(data[0]) < 0x20) {
259 switch (data[0]) {
260 case 0x00: encoding = Iso6937; break;
261 case 0x01: encoding = Iso8859_5; break;
262 case 0x02: encoding = Iso8859_6; break;
263 case 0x03: encoding = Iso8859_7; break;
264 case 0x04: encoding = Iso8859_8; break;
265 case 0x05: encoding = Iso8859_9; break;
266 case 0x06: encoding = Iso8859_10; break;
267 case 0x07: encoding = Iso8859_11; break;
268 case 0x09: encoding = Iso8859_13; break;
269 case 0x0a: encoding = Iso8859_14; break;
270 case 0x0b: encoding = Iso8859_15; break;
271 case 0x11: encoding = Iso10646_ucs2; break;
272 case 0x12: encoding = Iso2022_kr; break;
273 case 0x13: encoding = Gb2312; break;
274 case 0x14: encoding = Utf_16be; break;
275 case 0x15: encoding = Utf_8; break;
276 case 0x10: {
277 if (size < 3) {
278 return QString();
279 }
280
281 if (data[1] != 0) {
282 return QString();
283 }
284
285 switch (data[2]) {
286 case 0x01: encoding = Iso8859_1; break;
287 case 0x02: encoding = Iso8859_2; break;
288 case 0x03: encoding = Iso8859_3; break;
289 case 0x04: encoding = Iso8859_4; break;
290 case 0x05: encoding = Iso8859_5; break;
291 case 0x06: encoding = Iso8859_6; break;
292 case 0x07: encoding = Iso8859_7; break;
293 case 0x08: encoding = Iso8859_8; break;
294 case 0x09: encoding = Iso8859_9; break;
295 case 0x0a: encoding = Iso8859_10; break;
296 case 0x0b: encoding = Iso8859_11; break;
297 case 0x0d: encoding = Iso8859_13; break;
298 case 0x0e: encoding = Iso8859_14; break;
299 case 0x0f: encoding = Iso8859_15; break;
300 default:
301 return QString();
302 }
303
304 data += 2;
305 size -= 2;
306 break;
307 }
308 }
309
310 data++;
311 size--;
312 }
313
314 if (codecTable[encoding] == NULL) {
315 QTextCodec *codec = NULL;
316
317 switch (encoding) {
318 case Iso6937: codec = new Iso6937Codec(); break;
319 case Iso8859_1: codec = QTextCodec::codecForName("ISO 8859-1"); break;
320 case Iso8859_2: codec = QTextCodec::codecForName("ISO 8859-2"); break;
321 case Iso8859_3: codec = QTextCodec::codecForName("ISO 8859-3"); break;
322 case Iso8859_4: codec = QTextCodec::codecForName("ISO 8859-4"); break;
323 case Iso8859_5: codec = QTextCodec::codecForName("ISO 8859-5"); break;
324 case Iso8859_6: codec = QTextCodec::codecForName("ISO 8859-6"); break;
325 case Iso8859_7: codec = QTextCodec::codecForName("ISO 8859-7"); break;
326 case Iso8859_8: codec = QTextCodec::codecForName("ISO 8859-8"); break;
327 case Iso8859_9: codec = QTextCodec::codecForName("ISO 8859-9"); break;
328 case Iso8859_10: codec = QTextCodec::codecForName("ISO 8859-10"); break;
329 case Iso8859_11: codec = QTextCodec::codecForName("ISO 8859-11"); break;
330 case Iso8859_13: codec = QTextCodec::codecForName("ISO 8859-13"); break;
331 case Iso8859_14: codec = QTextCodec::codecForName("ISO 8859-14"); break;
332 case Iso8859_15: codec = QTextCodec::codecForName("ISO 8859-15"); break;
333 case Iso10646_ucs2: codec = QTextCodec::codecForName("UTF-16"); break;
334 case Iso2022_kr: codec = QTextCodec::codecForName("ISO 2022-KR"); break;
335 case Gb2312: codec = QTextCodec::codecForName("GB2312"); break;
336 case Utf_16be: codec = QTextCodec::codecForName("UTF-16BE"); break;
337 case Utf_8: codec = QTextCodec::codecForName("UTF-8"); break;
338 }
339
340 Q_ASSERT(codec != NULL);
341 codecTable[encoding] = codec;
342 }
343
344 if (encoding <= Iso8859_15) {
345 // only strip control codes for one-byte character tables
346
347 char *dest = new char[size];
348 char *destIt = dest;
349
350 for (const char *it = data; it != (data + size); ++it) {
351 unsigned char value = *it;
352
353 if ((value < 0x80) || (value > 0x9f)) {
354 *(destIt++) = value;
355 }
356 }
357
358 QString result = codecTable[encoding]->toUnicode(dest, int(destIt - dest));
359 delete[] dest;
360
361 return result;
362 }
363
364 return codecTable[encoding]->toUnicode(data, size);
365 }
366
setOverride6937(bool override)367 void DvbSiText::setOverride6937(bool override)
368 {
369 override6937 = override;
370 }
371
372 QTextCodec *DvbSiText::codecTable[EncodingTypeMax + 1] = { NULL };
373 bool DvbSiText::override6937 = false;
374
initDescriptor(const char * data,int size)375 void DvbDescriptor::initDescriptor(const char *data, int size)
376 {
377 if (size < 2) {
378 if (size != 0) {
379 qCInfo(logDvbSi, "Invalid descriptor");
380 }
381
382 initSectionData();
383 return;
384 }
385
386 int descriptorLength = (quint8(data[1]) + 2);
387
388 if (descriptorLength > size) {
389 qCInfo(logDvbSi, "Adjusting length");
390 descriptorLength = size;
391 }
392
393 initSectionData(data, descriptorLength, size);
394 }
395
interpretTextData(const char * data,unsigned int len,unsigned int mode)396 QString AtscPsipText::interpretTextData(const char *data, unsigned int len,
397 unsigned int mode)
398 {
399 // Based on the "mode" values in A/65C Table 6.41, convert
400 // the data into a string
401 QString result;
402
403 if ((mode <= 0x06) ||
404 (mode >= 0x09 && mode <= 0x10) ||
405 (mode >= 0x20 && mode <= 0x27) ||
406 (mode >= 0x30 && mode <= 0x33)) {
407 // Select UNICODE Code range based on mode as leading octet
408 for (unsigned int i = 0; i < len; i++) {
409 QChar val = (data[i] | (mode << 8));
410 result += val;
411 }
412 } else if (mode == 0x3f) {
413 // UTF-16
414 for (unsigned int i = 0; i < len; i += 2) {
415 QChar val = ((unsigned char)data[i] * 256) + (unsigned char)data[i+1];
416 result += val;
417 }
418 } else {
419 // We currently don't support the following:
420 // 0x3e Standard Compression Scheme for UNICODE (SCSU)
421 // 0x40/0x41 Taiwan
422 // 0x48 South Korea
423 qCInfo(logDvbSi, "Unsupported ATSC Text mode %d", mode);
424 }
425 return result;
426 }
427
convertText(const char * data,int size)428 QString AtscPsipText::convertText(const char *data, int size)
429 {
430 QString result;
431
432 if (size < 1) {
433 return QString();
434 }
435
436 unsigned int num_strings = quint8(data[0]);
437
438 if (num_strings == 0) {
439 return result;
440 }
441
442 // Note that for now we are only supporting the first string sent. If
443 // multiple languages are sent, we only grab the first one provided
444 int offset = 1;
445
446 // First three bytes are the ISO 639 language code
447 offset += 3;
448
449 if (offset > size) {
450 qCInfo(logDvbSi, "Adjusting length");
451 return result;
452 }
453
454 int num_segments = quint8(data[offset++]);
455
456 for (int j = 0; j < num_segments; j++) {
457 if ((offset + 3) > size) {
458 qCInfo(logDvbSi, "Adjusting length");
459 return result;
460 }
461
462 int comp_type = quint8(data[offset++]);
463 int mode = quint8(data[offset++]);
464 int num_bytes = quint8(data[offset++]);
465
466 if ((offset + num_bytes) > size) {
467 qCInfo(logDvbSi, "Adjusting length");
468 return result;
469 }
470
471 const char *comp_string = (data + offset);
472
473 if (comp_type == 0x00) {
474 // Uncompressed
475 result += interpretTextData(comp_string,
476 num_bytes, mode);
477 } else if ((comp_type == 0x01 || comp_type == 0x02) &&
478 mode == 0x00) {
479 // Huffman Compression
480 // As per the spec, only mode 0x00 supports Huffman coding
481 result +=
482 AtscHuffmanString::convertText(comp_string, num_bytes, comp_type);
483 } else {
484 qCInfo(logDvbSi, "Unsupported compression / mode %d %d", comp_type, mode);
485 }
486
487 offset += num_bytes;
488 }
489
490 return result;
491 }
492
convertText(const char * data_,int length,int table)493 QString AtscHuffmanString::convertText(const char *data_, int length, int table)
494 {
495 AtscHuffmanString huffmanstring(data_, length, table);
496 huffmanstring.decompress();
497 return huffmanstring.result;
498 }
499
AtscHuffmanString(const char * data_,int length,int table)500 AtscHuffmanString::AtscHuffmanString(const char *data_, int length, int table) : data(data_),
501 bitsLeft(8 * length)
502 {
503 if (table == 1) {
504 offsets = Huffman1Offsets;
505 tableBase = Huffman1Tables;
506 } else {
507 offsets = Huffman2Offsets;
508 tableBase = Huffman2Tables;
509 }
510 }
511
~AtscHuffmanString()512 AtscHuffmanString::~AtscHuffmanString() { }
513
hasBits()514 bool AtscHuffmanString::hasBits()
515 {
516 return bitsLeft > 0;
517 }
518
getBit()519 unsigned char AtscHuffmanString::getBit()
520 {
521 if (bitsLeft >= 1) {
522 int shift = (--bitsLeft % 8);
523 unsigned char value = (data[0] >> shift) & 0x1;
524
525 if (shift == 0) {
526 data++;
527 }
528 return value;
529 }
530
531 return 0;
532 }
533
getByte()534 unsigned char AtscHuffmanString::getByte()
535 {
536 if (bitsLeft >= 8) {
537 int shift = ((bitsLeft - 1) % 8);
538 // Note this takes advantage of the fact that there is always
539 // at least one byte remaining (to avoid a read-past end
540 // condition)
541 unsigned char value = ((((data[0] << 8) | quint8(data[1])) >> (shift + 1)) & 0xff);
542
543 bitsLeft -= 8;
544 data++;
545 return value;
546 }
547
548 return 0;
549 }
550
decompress()551 void AtscHuffmanString::decompress()
552 {
553 const unsigned char *table = tableBase;
554
555 while (hasBits()) {
556 int index = 0;
557
558 do {
559 index = table[2 * index + getBit()];
560 } while (index < 128);
561
562 index &= 0x7f;
563
564 if (index == 27) {
565 // escape --> uncompressed character(s)
566 while (true) {
567 index = getByte();
568
569 if (index < 128) {
570 break;
571 }
572
573 result += QChar(index);
574 }
575 }
576
577 if (index == 0) {
578 // end
579 break;
580 }
581
582 result += QChar(index);
583 table = tableBase + offsets[index];
584 }
585 }
586
587 const unsigned short AtscHuffmanString::Huffman1Offsets[128] = {
588 0x0000, 0x003a, 0x003c, 0x003e, 0x0040, 0x0042, 0x0044, 0x0046,
589 0x0048, 0x004a, 0x004c, 0x004e, 0x0050, 0x0052, 0x0054, 0x0056,
590 0x0058, 0x005a, 0x005c, 0x005e, 0x0060, 0x0062, 0x0064, 0x0066,
591 0x0068, 0x006a, 0x006c, 0x006e, 0x0070, 0x0072, 0x0074, 0x0076,
592 0x0078, 0x00ce, 0x00d2, 0x00d4, 0x00d6, 0x00d8, 0x00da, 0x00dc,
593 0x00e6, 0x00e8, 0x00ea, 0x00f0, 0x00f2, 0x00f4, 0x0106, 0x0112,
594 0x0114, 0x011c, 0x0128, 0x0130, 0x0134, 0x0136, 0x0138, 0x013a,
595 0x013c, 0x013e, 0x0146, 0x0148, 0x014a, 0x014c, 0x014e, 0x0150,
596 0x0152, 0x0154, 0x017e, 0x0192, 0x01ac, 0x01ba, 0x01d2, 0x01e4,
597 0x01fa, 0x0206, 0x021e, 0x0226, 0x0232, 0x023e, 0x0252, 0x0264,
598 0x027a, 0x0294, 0x0298, 0x02a4, 0x02c8, 0x02de, 0x02e6, 0x02f4,
599 0x0304, 0x0306, 0x030c, 0x0310, 0x0312, 0x0314, 0x0316, 0x0318,
600 0x031a, 0x031c, 0x0352, 0x036a, 0x038e, 0x03ae, 0x03ee, 0x0406,
601 0x0428, 0x0444, 0x0472, 0x0476, 0x0490, 0x04be, 0x04d6, 0x050a,
602 0x0544, 0x0564, 0x0566, 0x059a, 0x05d0, 0x05fc, 0x0622, 0x062c,
603 0x0646, 0x0654, 0x067c, 0x068a, 0x068c, 0x068e, 0x0690, 0x0692 };
604
605 const unsigned char AtscHuffmanString::Huffman1Tables[] = {
606 0x1b, 0x1c, 0xb4, 0xa4, 0xb2, 0xb7, 0xda, 0x01,
607 0xd1, 0x02, 0x03, 0x9b, 0x04, 0xd5, 0xd9, 0x05,
608 0xcb, 0xd6, 0x06, 0xcf, 0x07, 0x08, 0xca, 0x09,
609 0xc9, 0xc5, 0xc6, 0x0a, 0xd2, 0xc4, 0xc7, 0xcc,
610 0xd0, 0xc8, 0xd7, 0xce, 0x0b, 0xc1, 0x0c, 0xc2,
611 0xcd, 0xc3, 0x0d, 0x0e, 0x0f, 0x10, 0xd3, 0x11,
612 0xd4, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
613 0x19, 0x1a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
614 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
615 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
616 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
617 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
618 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
619 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
620 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
621 0x29, 0x2a, 0xd8, 0xe5, 0xb9, 0x01, 0xa7, 0xb1,
622 0xec, 0xd1, 0x02, 0xad, 0xb2, 0xda, 0xe3, 0xb3,
623 0x03, 0xe4, 0xe6, 0x04, 0x9b, 0xe2, 0x05, 0x06,
624 0x07, 0x08, 0x09, 0xd5, 0x0a, 0xd6, 0x0b, 0xd9,
625 0x0c, 0xa6, 0xe9, 0xcb, 0xc5, 0xcf, 0x0d, 0x0e,
626 0xca, 0xc9, 0x0f, 0xc7, 0x10, 0x11, 0xe1, 0x12,
627 0x13, 0xc6, 0xd2, 0xc8, 0xce, 0xc1, 0xc4, 0xd0,
628 0xcc, 0x14, 0x15, 0xef, 0xc2, 0xd7, 0x16, 0xcd,
629 0x17, 0xf4, 0xd4, 0x18, 0x19, 0x1a, 0xc3, 0xd3,
630 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
631 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x01, 0x80,
632 0xa0, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0xb1, 0x9b,
633 0x9b, 0x9b, 0x9b, 0xa0, 0x04, 0xf3, 0xe4, 0xb9,
634 0x01, 0xf4, 0xa0, 0x9b, 0x02, 0x03, 0x9b, 0x9b,
635 0x9b, 0x9b, 0x01, 0x02, 0x9b, 0xc1, 0xc8, 0xd3,
636 0x9b, 0x9b, 0x9b, 0xa0, 0x07, 0x08, 0xb1, 0xd2,
637 0xd3, 0xd4, 0xd5, 0xad, 0xcd, 0xc1, 0x01, 0x02,
638 0x03, 0xa0, 0x04, 0x9b, 0x05, 0x06, 0xa0, 0x05,
639 0xc9, 0xd7, 0xd3, 0x01, 0x02, 0x9b, 0xae, 0x80,
640 0x03, 0x04, 0x9b, 0x9b, 0x02, 0x03, 0xad, 0x9b,
641 0x01, 0x80, 0xa0, 0xb0, 0x04, 0x05, 0x80, 0x9b,
642 0xb1, 0xb2, 0xa0, 0xb0, 0xb9, 0x01, 0x02, 0x03,
643 0x02, 0x03, 0xb1, 0xba, 0x01, 0xb0, 0x9b, 0x80,
644 0x80, 0x01, 0xb0, 0x9b, 0x9b, 0xb8, 0x9b, 0x9b,
645 0x9b, 0x9b, 0x9b, 0xb0, 0x9b, 0xa0, 0x02, 0x03,
646 0xb1, 0xb3, 0xb9, 0xb0, 0x01, 0x9b, 0x9b, 0xa0,
647 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
648 0x9b, 0x80, 0x9b, 0x9b, 0x13, 0x14, 0xaa, 0xad,
649 0xae, 0xf6, 0xe7, 0xf4, 0xe2, 0xe9, 0x01, 0x02,
650 0xc2, 0xf0, 0x9b, 0xf3, 0xe3, 0xe6, 0xf7, 0x03,
651 0xf5, 0x04, 0x05, 0x06, 0xf2, 0x07, 0x08, 0x09,
652 0x0a, 0x0b, 0x0c, 0xe4, 0xa0, 0x0d, 0xec, 0xee,
653 0x0e, 0xed, 0x0f, 0x10, 0x11, 0x12, 0x08, 0x09,
654 0xc1, 0xd3, 0x9b, 0x01, 0xc3, 0x02, 0xe9, 0xec,
655 0x03, 0xf2, 0xf5, 0x04, 0xef, 0xe1, 0x05, 0xe5,
656 0x06, 0x07, 0x0b, 0x0c, 0xc1, 0xf9, 0x01, 0xc2,
657 0xcf, 0xe5, 0xf5, 0x9b, 0xe9, 0x02, 0xa0, 0x03,
658 0x04, 0x05, 0xf2, 0x06, 0xec, 0x07, 0xe1, 0x08,
659 0x09, 0xe8, 0x0a, 0xef, 0x05, 0x06, 0xf9, 0x9b,
660 0x01, 0xf5, 0x02, 0xf2, 0xe9, 0xe5, 0xef, 0x03,
661 0xe1, 0x04, 0x0a, 0x0b, 0xf1, 0xf5, 0xf3, 0x01,
662 0xed, 0xf9, 0xc3, 0x02, 0xec, 0xee, 0xe4, 0xf8,
663 0x03, 0x9b, 0xf6, 0x04, 0x05, 0xe1, 0x06, 0x07,
664 0x08, 0x09, 0x07, 0x08, 0xa0, 0x9b, 0xcc, 0x01,
665 0xe5, 0x02, 0xec, 0xf5, 0xef, 0x03, 0xe9, 0xf2,
666 0x04, 0x05, 0xe1, 0x06, 0x09, 0x0a, 0xae, 0xec,
667 0xf9, 0xc1, 0xe8, 0x01, 0x9b, 0x02, 0x03, 0x04,
668 0xe1, 0xf5, 0xe9, 0x05, 0xe5, 0x06, 0xf2, 0xef,
669 0x07, 0x08, 0xef, 0x05, 0x80, 0x9b, 0xf5, 0x01,
670 0x02, 0xe9, 0xe1, 0x03, 0xe5, 0x04, 0xee, 0x0b,
671 0xba, 0xd4, 0xae, 0xf2, 0xe3, 0x01, 0xa0, 0x02,
672 0x80, 0x9b, 0xed, 0x03, 0xc9, 0xf3, 0xf4, 0x04,
673 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x02, 0x03,
674 0x9b, 0xf5, 0x01, 0xe1, 0xef, 0xe5, 0x05, 0xe9,
675 0xe1, 0xef, 0xf5, 0xee, 0x9b, 0xe5, 0x01, 0x02,
676 0x03, 0x04, 0x04, 0x05, 0xa0, 0x9b, 0x01, 0xf5,
677 0x02, 0xe5, 0xef, 0x03, 0xe1, 0xe9, 0x08, 0x09,
678 0xaa, 0xd4, 0x01, 0x9b, 0xe3, 0x02, 0xf2, 0x03,
679 0xe5, 0x04, 0xf5, 0xf9, 0xe9, 0x05, 0xef, 0x06,
680 0x07, 0xe1, 0xe5, 0x08, 0xce, 0xa0, 0xc6, 0xf5,
681 0x01, 0x02, 0x9b, 0xc2, 0x03, 0xe1, 0x04, 0xef,
682 0x05, 0xe9, 0x06, 0x07, 0x09, 0x0a, 0xe4, 0xf3,
683 0xe6, 0xf6, 0xf7, 0xf0, 0xf2, 0x01, 0xec, 0x02,
684 0x03, 0xa0, 0x9b, 0x04, 0x05, 0xf5, 0x06, 0x07,
685 0xee, 0x08, 0x0b, 0x0c, 0xa0, 0xf3, 0xf9, 0xae,
686 0xd2, 0xc7, 0x01, 0x9b, 0x02, 0xf5, 0x03, 0x04,
687 0x05, 0xe9, 0xec, 0x06, 0xe5, 0x07, 0xef, 0x08,
688 0xe1, 0x09, 0xf2, 0x0a, 0x01, 0xf5, 0x9b, 0xd6,
689 0x04, 0x05, 0xe8, 0x9b, 0x01, 0xf5, 0x02, 0xe1,
690 0xe9, 0xef, 0x03, 0xe5, 0x10, 0x11, 0xaa, 0xec,
691 0xf1, 0xae, 0xa0, 0xf7, 0xed, 0xee, 0x01, 0x02,
692 0x9b, 0xeb, 0x03, 0x04, 0x05, 0x06, 0xe3, 0x07,
693 0xef, 0x08, 0xe9, 0xf5, 0x09, 0xe1, 0xe5, 0xf0,
694 0xe8, 0x0a, 0x0b, 0x0c, 0x0d, 0xf4, 0x0e, 0x0f,
695 0xe8, 0x0a, 0xad, 0xce, 0x9b, 0x01, 0xd6, 0x02,
696 0xf5, 0xf7, 0x03, 0x04, 0xe1, 0xe5, 0xe9, 0x05,
697 0xf2, 0x06, 0xef, 0x07, 0x08, 0x09, 0xee, 0x03,
698 0xec, 0xae, 0x01, 0x9b, 0x02, 0xf0, 0x06, 0xe9,
699 0xa0, 0xc3, 0xef, 0x9b, 0xe5, 0x01, 0x80, 0x02,
700 0x03, 0xe1, 0x04, 0x05, 0x06, 0x07, 0xc6, 0xd7,
701 0x01, 0x9b, 0xf2, 0x02, 0x03, 0xe8, 0xe5, 0xe1,
702 0x04, 0xe9, 0xef, 0x05, 0x9b, 0x9b, 0x02, 0xef,
703 0xe1, 0x9b, 0x01, 0xe5, 0x01, 0xef, 0x9b, 0xe1,
704 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
705 0x9b, 0x9b, 0x9b, 0x9b, 0x19, 0x1a, 0x9b, 0xba,
706 0xe5, 0xea, 0xf8, 0x01, 0x02, 0xe6, 0xa7, 0x03,
707 0xfa, 0xe8, 0x04, 0xf7, 0x05, 0xf5, 0xe2, 0x06,
708 0xeb, 0x07, 0xf0, 0x08, 0x80, 0xf6, 0xe7, 0x09,
709 0xe4, 0x0a, 0xa0, 0xe9, 0x0b, 0xe3, 0xf9, 0x0c,
710 0x0d, 0xed, 0x0e, 0x0f, 0xf3, 0x10, 0x11, 0xec,
711 0x12, 0xf4, 0xf2, 0x13, 0xee, 0x14, 0x15, 0x16,
712 0x17, 0x18, 0x0a, 0x0b, 0xf3, 0x9b, 0xf5, 0xe2,
713 0x01, 0x80, 0xa0, 0x02, 0xe5, 0xf2, 0xe9, 0x03,
714 0xec, 0x04, 0xf9, 0x05, 0xef, 0x06, 0xe1, 0x07,
715 0x08, 0x09, 0x10, 0x11, 0xc3, 0xcc, 0xc7, 0x9b,
716 0xe3, 0x01, 0x80, 0xec, 0xf9, 0x02, 0xf3, 0x03,
717 0xf5, 0x04, 0x05, 0xf2, 0x06, 0xe9, 0xa0, 0x07,
718 0x08, 0xef, 0xf4, 0x09, 0x0a, 0xe1, 0x0b, 0xe8,
719 0xeb, 0xe5, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
720 0xae, 0xf5, 0xf7, 0x01, 0xec, 0x02, 0xe4, 0xe7,
721 0xf2, 0x03, 0x9b, 0xef, 0x04, 0xf6, 0x05, 0x06,
722 0xf9, 0xf3, 0x07, 0xe9, 0xe1, 0x08, 0x09, 0x80,
723 0x0a, 0x0b, 0xe5, 0x0c, 0x0d, 0xa0, 0x1e, 0x1f,
724 0x9b, 0xa1, 0xad, 0xe8, 0xea, 0xf1, 0xf5, 0xfa,
725 0x01, 0x02, 0x03, 0x04, 0xba, 0xf8, 0xa7, 0xe2,
726 0xe9, 0x05, 0x06, 0x07, 0xe6, 0xed, 0xe7, 0xeb,
727 0x08, 0x09, 0xf6, 0xf0, 0x0a, 0xef, 0x0b, 0xe3,
728 0x0c, 0x0d, 0x0e, 0xf9, 0x0f, 0xe4, 0xec, 0x10,
729 0xe5, 0x11, 0xf4, 0xf7, 0x12, 0x13, 0xe1, 0x14,
730 0x15, 0x16, 0xee, 0xf3, 0x17, 0x80, 0x18, 0x19,
731 0xf2, 0x1a, 0x1b, 0xa0, 0x1c, 0x1d, 0xa0, 0x0b,
732 0xf5, 0x9b, 0x01, 0xec, 0xf3, 0xf2, 0x80, 0xe1,
733 0x02, 0x03, 0xf4, 0xe9, 0xef, 0xe6, 0x04, 0x05,
734 0x06, 0x07, 0xe5, 0x08, 0x09, 0x0a, 0x0f, 0x10,
735 0xba, 0xf9, 0xa7, 0xf4, 0x9b, 0x01, 0xe7, 0xec,
736 0x02, 0xee, 0x03, 0xef, 0xf5, 0x04, 0xf2, 0x05,
737 0x06, 0xe9, 0x07, 0xf3, 0xe1, 0x08, 0x09, 0x0a,
738 0x0b, 0xe5, 0x80, 0x0c, 0xe8, 0xa0, 0x0d, 0x0e,
739 0xe5, 0x0d, 0xe2, 0xf5, 0xf7, 0x9b, 0xec, 0x01,
740 0xf9, 0xee, 0x02, 0x03, 0x04, 0xf2, 0x05, 0x80,
741 0x06, 0xa0, 0xe1, 0xef, 0x07, 0xf4, 0xe9, 0x08,
742 0x09, 0x0a, 0x0b, 0x0c, 0x15, 0x16, 0xa1, 0xf8,
743 0xe9, 0xeb, 0x01, 0x80, 0x9b, 0xfa, 0xe2, 0x02,
744 0x03, 0x04, 0xa0, 0xf0, 0x05, 0x06, 0x07, 0xe1,
745 0x08, 0xe6, 0xf2, 0xed, 0xf6, 0x09, 0xe4, 0x0a,
746 0xef, 0xf4, 0xec, 0xf3, 0xe7, 0xe5, 0x0b, 0xe3,
747 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
748 0xee, 0x14, 0xef, 0x01, 0x9b, 0xe1, 0x0b, 0x0c,
749 0xd4, 0xef, 0xe6, 0xec, 0xf7, 0xe1, 0x01, 0xba,
750 0x02, 0x9b, 0xf9, 0x03, 0x04, 0x05, 0xf3, 0x06,
751 0x07, 0x08, 0xe9, 0xa0, 0x09, 0x80, 0xe5, 0x0a,
752 0x15, 0x16, 0xa7, 0xba, 0xe3, 0xf7, 0xf2, 0xad,
753 0xe2, 0x01, 0x02, 0x9b, 0xe6, 0x03, 0xed, 0xf6,
754 0x04, 0xeb, 0x05, 0xf4, 0x06, 0x07, 0x08, 0xf3,
755 0x09, 0xf5, 0x0a, 0xef, 0x0b, 0x0c, 0x80, 0xf9,
756 0xe1, 0x0d, 0xe4, 0xe9, 0xa0, 0x0e, 0x0f, 0xec,
757 0xe5, 0x10, 0x11, 0x12, 0x13, 0x14, 0x0a, 0x0b,
758 0xf9, 0x9b, 0xf5, 0xf3, 0x01, 0x02, 0xe2, 0xed,
759 0x80, 0x03, 0xf0, 0xef, 0x04, 0xa0, 0x05, 0xe9,
760 0x06, 0xe1, 0x07, 0x08, 0x09, 0xe5, 0x18, 0x19,
761 0xe2, 0xea, 0xf2, 0xe8, 0xec, 0xed, 0xfa, 0x9b,
762 0x01, 0xf5, 0x02, 0x03, 0xf6, 0x04, 0xba, 0xe6,
763 0x05, 0x06, 0xeb, 0xef, 0x07, 0xa7, 0xf9, 0x08,
764 0x09, 0x0a, 0x0b, 0xe3, 0x0c, 0xee, 0xe1, 0x0d,
765 0xf3, 0x0e, 0xe9, 0x0f, 0x10, 0xf4, 0x80, 0xe4,
766 0xe5, 0x11, 0x12, 0xe7, 0xa0, 0x13, 0x14, 0x15,
767 0x16, 0x17, 0x1b, 0x1c, 0xae, 0xfa, 0xbf, 0x01,
768 0xa7, 0x9b, 0x02, 0xe9, 0xf8, 0xf9, 0x03, 0xe5,
769 0xe8, 0x04, 0xe1, 0xeb, 0x05, 0xe2, 0x06, 0x07,
770 0xe3, 0x08, 0xe7, 0xf4, 0x09, 0x80, 0xf6, 0xf0,
771 0x0a, 0xe4, 0x0b, 0xf3, 0xf7, 0x0c, 0x0d, 0xef,
772 0xec, 0xa0, 0x0e, 0x0f, 0xed, 0xe6, 0x10, 0xf5,
773 0x11, 0x12, 0x13, 0x14, 0x15, 0xf2, 0x16, 0xee,
774 0x17, 0x18, 0x19, 0x1a, 0x0e, 0x0f, 0xed, 0xa7,
775 0x9b, 0xe4, 0x01, 0xf9, 0xf3, 0xf2, 0xf4, 0x02,
776 0xe8, 0x03, 0xec, 0xf0, 0x04, 0xe1, 0xe9, 0x05,
777 0x06, 0x80, 0xa0, 0x07, 0x08, 0x09, 0x0a, 0xe5,
778 0xef, 0x0b, 0x0c, 0x0d, 0x9b, 0xf5, 0x18, 0x19,
779 0xba, 0xac, 0xf6, 0x9b, 0xf0, 0xe2, 0x01, 0xe6,
780 0x02, 0xa7, 0xae, 0xe7, 0x03, 0xe3, 0xf5, 0x04,
781 0xed, 0x05, 0x06, 0x07, 0xeb, 0x08, 0x09, 0xee,
782 0xf2, 0x0a, 0xe4, 0x0b, 0xf9, 0xec, 0x0c, 0x0d,
783 0xf4, 0x80, 0x0e, 0xef, 0xf3, 0xa0, 0xe1, 0x0f,
784 0xe9, 0x10, 0x11, 0xe5, 0x12, 0x13, 0x14, 0x15,
785 0x16, 0x17, 0x19, 0x1a, 0xa7, 0xac, 0xbf, 0xc3,
786 0xc8, 0xe4, 0xe6, 0xed, 0xf2, 0xae, 0xec, 0xee,
787 0xf9, 0x01, 0x02, 0x03, 0x04, 0xba, 0x05, 0x9b,
788 0xf5, 0x06, 0x07, 0x08, 0x09, 0xeb, 0xf0, 0x0a,
789 0x0b, 0x0c, 0xe1, 0xe3, 0x0d, 0xe8, 0x0e, 0x0f,
790 0xef, 0x10, 0x11, 0xf3, 0x12, 0xe9, 0x13, 0xe5,
791 0x14, 0x15, 0xf4, 0x16, 0x17, 0xa0, 0x18, 0x80,
792 0x14, 0x15, 0xba, 0xbf, 0xe4, 0xf7, 0x9b, 0xa7,
793 0x01, 0xee, 0x02, 0x03, 0x04, 0xe3, 0xe2, 0xed,
794 0x05, 0xf9, 0x06, 0xf4, 0x07, 0xec, 0x08, 0xf5,
795 0xf2, 0x09, 0xe1, 0xf3, 0x0a, 0xef, 0x0b, 0x0c,
796 0x0d, 0xe9, 0x80, 0xe5, 0x0e, 0xa0, 0x0f, 0xe8,
797 0x10, 0x11, 0x12, 0x13, 0x11, 0x12, 0xeb, 0xfa,
798 0x80, 0xe6, 0x9b, 0x01, 0xa0, 0x02, 0x03, 0xe9,
799 0xe1, 0x04, 0xe4, 0xf0, 0xed, 0xe2, 0xe3, 0xe7,
800 0xec, 0x05, 0xe5, 0x06, 0x07, 0x08, 0x09, 0xf4,
801 0x0a, 0x0b, 0x0c, 0xf3, 0xee, 0x0d, 0x0e, 0xf2,
802 0x0f, 0x10, 0x04, 0xe5, 0xf3, 0xef, 0x9b, 0x01,
803 0xe1, 0x02, 0x03, 0xe9, 0x0b, 0x0c, 0xa7, 0xe2,
804 0xec, 0xe3, 0xf2, 0x01, 0x9b, 0x02, 0x03, 0x04,
805 0xe9, 0xef, 0xee, 0xe5, 0xe1, 0x80, 0x05, 0xa0,
806 0x06, 0x07, 0x08, 0x09, 0xf3, 0x0a, 0x05, 0x06,
807 0x9b, 0xa0, 0xe1, 0xe5, 0xe9, 0x01, 0x80, 0xf0,
808 0x02, 0xf4, 0x03, 0x04, 0xa0, 0x13, 0xe3, 0xad,
809 0xe4, 0xe9, 0xee, 0xef, 0xf0, 0xf4, 0xf6, 0xa1,
810 0xe1, 0xed, 0x01, 0xe2, 0x02, 0x03, 0x04, 0xa7,
811 0x05, 0x06, 0xf7, 0x07, 0x9b, 0xec, 0x08, 0xe5,
812 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xf3, 0x0f,
813 0x10, 0x11, 0x80, 0x12, 0x05, 0x06, 0xe5, 0xfa,
814 0xa0, 0xf9, 0x9b, 0x01, 0x80, 0xe9, 0x02, 0xe1,
815 0x03, 0x04, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
816 0x9b, 0x9b, 0x9b, 0x9b };
817
818 const unsigned short AtscHuffmanString::Huffman2Offsets[128] = {
819 0x0000, 0x002c, 0x002e, 0x0030, 0x0032, 0x0034, 0x0036, 0x0038,
820 0x003a, 0x003c, 0x003e, 0x0040, 0x0042, 0x0044, 0x0046, 0x0048,
821 0x004a, 0x004c, 0x004e, 0x0050, 0x0052, 0x0054, 0x0056, 0x0058,
822 0x005a, 0x005c, 0x005e, 0x0060, 0x0062, 0x0064, 0x0066, 0x0068,
823 0x006a, 0x00de, 0x00e0, 0x00ea, 0x00ec, 0x00ee, 0x00f0, 0x00f2,
824 0x00f8, 0x00fa, 0x00fc, 0x00fe, 0x0100, 0x0104, 0x0116, 0x0120,
825 0x0122, 0x012c, 0x0132, 0x0138, 0x013c, 0x0140, 0x0144, 0x0146,
826 0x014a, 0x014c, 0x0154, 0x0156, 0x0158, 0x015a, 0x015c, 0x015e,
827 0x0160, 0x0162, 0x0176, 0x0184, 0x0194, 0x01a2, 0x01b2, 0x01ba,
828 0x01c8, 0x01d2, 0x01de, 0x01ea, 0x01f2, 0x01fc, 0x0208, 0x0210,
829 0x021a, 0x0228, 0x022a, 0x0234, 0x024a, 0x025a, 0x025e, 0x0264,
830 0x026e, 0x0270, 0x0272, 0x0274, 0x0276, 0x0278, 0x027a, 0x027c,
831 0x027e, 0x0280, 0x02b4, 0x02ce, 0x02f0, 0x031a, 0x0358, 0x036e,
832 0x038e, 0x03ac, 0x03d8, 0x03e0, 0x03f4, 0x0424, 0x0440, 0x0476,
833 0x04ae, 0x04ce, 0x04d0, 0x0506, 0x0534, 0x0560, 0x0586, 0x0592,
834 0x05aa, 0x05b8, 0x05dc, 0x05ec, 0x05ee, 0x05f0, 0x05f2, 0x05f4 };
835
836 const unsigned char AtscHuffmanString::Huffman2Tables[] = {
837 0x14, 0x15, 0x9b, 0xd6, 0xc9, 0xcf, 0xd7, 0xc7,
838 0x01, 0xa2, 0xce, 0xcb, 0x02, 0x03, 0xc5, 0xcc,
839 0xc6, 0xc8, 0x04, 0xc4, 0x05, 0xc2, 0x06, 0xc3,
840 0xd2, 0x07, 0xd3, 0x08, 0xca, 0xd4, 0x09, 0xcd,
841 0xd0, 0x0a, 0xc1, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
842 0x10, 0x11, 0x12, 0x13, 0x9b, 0x9b, 0x9b, 0x9b,
843 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
844 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
845 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
846 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
847 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
848 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
849 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
850 0x9b, 0x9b, 0x38, 0x39, 0xad, 0xaf, 0xb7, 0xda,
851 0xa8, 0xb3, 0xb5, 0x01, 0x02, 0x9b, 0xb4, 0xf1,
852 0xa2, 0xd5, 0xd6, 0xd9, 0x03, 0x04, 0x05, 0xcf,
853 0x06, 0xc9, 0xf9, 0xea, 0xeb, 0xf5, 0xf6, 0x07,
854 0x08, 0x09, 0xb2, 0xc5, 0xc6, 0xb1, 0x0a, 0xee,
855 0xcb, 0x0b, 0xd4, 0x0c, 0xc4, 0xc8, 0xd2, 0x0d,
856 0x0e, 0x0f, 0xc7, 0xca, 0xce, 0xd0, 0xd7, 0x10,
857 0xc2, 0x11, 0xcc, 0xec, 0xe5, 0xe7, 0x12, 0xcd,
858 0x13, 0x14, 0xc3, 0x15, 0x16, 0x17, 0xed, 0x18,
859 0x19, 0xf2, 0x1a, 0xd3, 0x1b, 0x1c, 0xe4, 0x1d,
860 0xc1, 0xe3, 0x1e, 0xe9, 0xf0, 0xe2, 0xf7, 0x1f,
861 0xf3, 0xe6, 0x20, 0x21, 0x22, 0xe8, 0xef, 0x23,
862 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xf4,
863 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0xe1, 0x30, 0x31,
864 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x9b, 0x9b,
865 0x03, 0x04, 0x80, 0xae, 0xc8, 0xd4, 0x01, 0x02,
866 0x9b, 0xa0, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
867 0x9b, 0x9b, 0x02, 0xf3, 0xa0, 0xf4, 0x9b, 0x01,
868 0x9b, 0x9b, 0xac, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
869 0x01, 0xa0, 0x9b, 0xa2, 0x07, 0x08, 0xe2, 0xe4,
870 0xe5, 0xe6, 0xa0, 0xf2, 0xe1, 0x01, 0x02, 0xf3,
871 0xe3, 0x03, 0x04, 0x05, 0x9b, 0x06, 0x04, 0x80,
872 0xca, 0xd3, 0xa2, 0x01, 0x9b, 0x02, 0x03, 0xa0,
873 0x9b, 0xa0, 0x03, 0x04, 0x9b, 0xb7, 0xf4, 0xa0,
874 0xb0, 0xf3, 0x01, 0x02, 0xb9, 0x02, 0xb8, 0x9b,
875 0xa0, 0x01, 0xae, 0x02, 0xb6, 0x9b, 0x01, 0xa0,
876 0xa0, 0x01, 0x9b, 0xb0, 0xae, 0x01, 0x9b, 0xa0,
877 0xae, 0x01, 0xa0, 0x9b, 0x9b, 0x9b, 0x9b, 0x01,
878 0xac, 0xae, 0x9b, 0x9b, 0x02, 0x03, 0x9b, 0xa0,
879 0xb5, 0xb6, 0xb8, 0x01, 0x9b, 0xa0, 0x9b, 0xa0,
880 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0xa0,
881 0x9b, 0x9b, 0x08, 0x09, 0xe6, 0xf5, 0xf3, 0xf4,
882 0x9b, 0xe4, 0x01, 0xed, 0x02, 0x03, 0x04, 0xf2,
883 0x05, 0x06, 0xec, 0xee, 0x07, 0xa0, 0x05, 0x06,
884 0x9b, 0xec, 0xf5, 0x01, 0x02, 0xe1, 0xef, 0xe5,
885 0xe9, 0xf2, 0x03, 0x04, 0x06, 0x07, 0x9b, 0xe9,
886 0xf9, 0xf2, 0xf5, 0x01, 0x02, 0x03, 0xec, 0xef,
887 0xe1, 0x04, 0xe8, 0x05, 0x05, 0x06, 0xf9, 0xf2,
888 0xf5, 0x9b, 0xe5, 0xef, 0x01, 0x02, 0xe9, 0xe1,
889 0x03, 0x04, 0x06, 0x07, 0xe1, 0xe9, 0xee, 0xf6,
890 0xe4, 0xec, 0xf3, 0x01, 0x02, 0xf2, 0x03, 0x04,
891 0x9b, 0x05, 0x02, 0x03, 0xe5, 0xec, 0x9b, 0xef,
892 0x01, 0xf2, 0x05, 0x06, 0xf5, 0xef, 0x9b, 0xec,
893 0xe9, 0x01, 0xe1, 0xf2, 0x02, 0xe5, 0x03, 0x04,
894 0x03, 0x04, 0x9b, 0xe5, 0xe9, 0xf5, 0xe1, 0x01,
895 0xef, 0x02, 0x04, 0x05, 0xa0, 0xc9, 0xf3, 0x9b,
896 0xae, 0xf2, 0x01, 0x02, 0x03, 0xee, 0xef, 0x05,
897 0x9b, 0xae, 0xe9, 0xe5, 0x01, 0xf5, 0x02, 0xe1,
898 0x03, 0x04, 0xe5, 0x03, 0xe1, 0xe9, 0xf2, 0x9b,
899 0x01, 0x02, 0x03, 0x04, 0x9b, 0xe9, 0xf5, 0x01,
900 0xe5, 0x02, 0xef, 0xe1, 0xe1, 0x05, 0x9b, 0xe3,
901 0xef, 0x01, 0xf5, 0xe5, 0x02, 0x03, 0xe9, 0x04,
902 0xe5, 0x03, 0x9b, 0xe9, 0x01, 0xe1, 0xef, 0x02,
903 0x03, 0x04, 0xa7, 0xee, 0xec, 0xf2, 0xf3, 0x01,
904 0x9b, 0x02, 0xe1, 0x06, 0x9b, 0xe8, 0xe9, 0x01,
905 0xf2, 0xec, 0x02, 0xef, 0x03, 0xe5, 0x04, 0x05,
906 0x9b, 0x9b, 0x03, 0x04, 0x9b, 0xae, 0x01, 0xe9,
907 0x02, 0xe1, 0xe5, 0xef, 0x09, 0x0a, 0xf6, 0xf9,
908 0x01, 0xae, 0xe3, 0xe9, 0xf5, 0x9b, 0xe5, 0xef,
909 0x02, 0x03, 0xe1, 0x04, 0xe8, 0x05, 0x06, 0xf4,
910 0x07, 0x08, 0xe8, 0x07, 0xe5, 0xf7, 0xd6, 0xe1,
911 0x9b, 0xe9, 0xf2, 0x01, 0x02, 0x03, 0x04, 0xef,
912 0x05, 0x06, 0xae, 0x01, 0x9b, 0xee, 0xe9, 0x02,
913 0xe5, 0x9b, 0xa0, 0x01, 0x03, 0x04, 0x9b, 0xe8,
914 0xe5, 0xe1, 0xef, 0x01, 0xe9, 0x02, 0x9b, 0x9b,
915 0x9b, 0xef, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
916 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
917 0x18, 0x19, 0xe8, 0xef, 0xf8, 0x9b, 0xa7, 0xf7,
918 0xfa, 0x01, 0x02, 0x03, 0x04, 0xe5, 0xae, 0x05,
919 0xe6, 0xe2, 0x06, 0xf6, 0xeb, 0xf5, 0xe9, 0x07,
920 0xf0, 0xf9, 0xe7, 0x08, 0x09, 0xe4, 0x0a, 0xe3,
921 0x0b, 0xed, 0x0c, 0xf3, 0x0d, 0x0e, 0x0f, 0xec,
922 0x10, 0xf4, 0x11, 0x12, 0xf2, 0xa0, 0x13, 0x14,
923 0x15, 0xee, 0x16, 0x17, 0x0b, 0x0c, 0xe4, 0xf3,
924 0x9b, 0xae, 0xe2, 0x01, 0x02, 0x03, 0xec, 0xa0,
925 0x04, 0xe9, 0xf2, 0xf5, 0x05, 0xf9, 0xe1, 0x06,
926 0xef, 0x07, 0xe5, 0x08, 0x09, 0x0a, 0x0f, 0x10,
927 0xf1, 0xae, 0xc4, 0xf9, 0xac, 0x01, 0xe3, 0x02,
928 0x9b, 0xf2, 0x03, 0x04, 0xa0, 0xec, 0xf5, 0x05,
929 0x06, 0xe9, 0x07, 0xeb, 0x08, 0xf4, 0x09, 0xe5,
930 0x0a, 0xef, 0xe1, 0xe8, 0x0b, 0x0c, 0x0d, 0x0e,
931 0x13, 0x14, 0xa7, 0xbb, 0xe6, 0xed, 0xf7, 0xe7,
932 0xf6, 0x01, 0x02, 0x9b, 0xee, 0x03, 0x04, 0xec,
933 0x05, 0xf5, 0x06, 0xac, 0xe4, 0xf9, 0xf2, 0x07,
934 0x08, 0x09, 0xae, 0x0a, 0xef, 0x0b, 0xe1, 0xf3,
935 0x0c, 0xe9, 0x0d, 0x0e, 0x0f, 0x10, 0xe5, 0x11,
936 0x12, 0xa0, 0x1d, 0x1e, 0xa9, 0xe8, 0xf5, 0x9b,
937 0x01, 0xad, 0xbb, 0xeb, 0xfa, 0x02, 0xa7, 0xe6,
938 0xe2, 0xe7, 0x03, 0x04, 0x05, 0x06, 0xe9, 0xf8,
939 0x07, 0xac, 0xef, 0xf0, 0x08, 0xed, 0xf6, 0xf9,
940 0x09, 0xf7, 0x0a, 0x0b, 0xae, 0x0c, 0xe3, 0x0d,
941 0xe5, 0xf4, 0x0e, 0x0f, 0xe4, 0x10, 0xec, 0x11,
942 0xe1, 0x12, 0x13, 0x14, 0x15, 0x16, 0xee, 0xf3,
943 0x17, 0x18, 0xf2, 0xa0, 0x19, 0x1a, 0x1b, 0x1c,
944 0x09, 0x0a, 0xae, 0x9b, 0xec, 0x01, 0xf5, 0x02,
945 0xf4, 0xe6, 0x03, 0xe1, 0xe5, 0xe9, 0x04, 0xf2,
946 0xef, 0x05, 0x06, 0x07, 0xa0, 0x08, 0x0e, 0x0f,
947 0xad, 0xe7, 0x9b, 0xa7, 0xf9, 0x01, 0xec, 0x02,
948 0xac, 0xf2, 0x03, 0xae, 0xf3, 0xf5, 0x04, 0x05,
949 0xef, 0x06, 0x07, 0xe9, 0xe1, 0x08, 0x09, 0xe8,
950 0x0a, 0x0b, 0xe5, 0x0c, 0xa0, 0x0d, 0x0d, 0x0e,
951 0xa7, 0xac, 0xf3, 0xad, 0x01, 0x02, 0x9b, 0xf9,
952 0xf5, 0xae, 0x03, 0xee, 0x04, 0xf2, 0x05, 0x06,
953 0xf4, 0x07, 0x08, 0x09, 0xef, 0xe1, 0xa0, 0x0a,
954 0xe9, 0x0b, 0x0c, 0xe5, 0x14, 0x15, 0xac, 0xe2,
955 0xf8, 0x9b, 0xae, 0xfa, 0x01, 0xeb, 0x02, 0xa0,
956 0x03, 0x04, 0xf0, 0x05, 0x06, 0xe6, 0xf6, 0x07,
957 0xe4, 0xed, 0xe7, 0x08, 0xe1, 0xef, 0xf2, 0x09,
958 0x0a, 0x0b, 0xec, 0x0c, 0xe5, 0xe3, 0x0d, 0xf4,
959 0x0e, 0xf3, 0x0f, 0x10, 0x11, 0xee, 0x12, 0x13,
960 0x03, 0xef, 0x9b, 0xe1, 0xe5, 0xf5, 0x01, 0x02,
961 0x08, 0x09, 0xec, 0xf9, 0xa7, 0xee, 0x01, 0xac,
962 0x9b, 0xae, 0x02, 0x03, 0x04, 0xf3, 0x05, 0xe9,
963 0x06, 0xa0, 0x07, 0xe5, 0x16, 0x17, 0xa7, 0xad,
964 0xee, 0xe3, 0xeb, 0xf2, 0x9b, 0xe2, 0x01, 0x02,
965 0xf5, 0x03, 0xf4, 0xac, 0x04, 0x05, 0xe6, 0xed,
966 0xf6, 0x06, 0xae, 0xf0, 0x07, 0x08, 0xf3, 0x09,
967 0x0a, 0xe4, 0x0b, 0x0c, 0xf9, 0x0d, 0xef, 0x0e,
968 0xe1, 0x0f, 0x10, 0xe9, 0xec, 0x11, 0xa0, 0xe5,
969 0x12, 0x13, 0x14, 0x15, 0x0c, 0x0d, 0xa7, 0xbb,
970 0x9b, 0x01, 0xf9, 0xae, 0xe2, 0x02, 0xed, 0xf3,
971 0x03, 0xf5, 0xef, 0xf0, 0x04, 0x05, 0xe9, 0x06,
972 0x07, 0x08, 0x09, 0xa0, 0xe1, 0xe5, 0x0a, 0x0b,
973 0x19, 0x1a, 0xad, 0xbb, 0xe2, 0xea, 0xed, 0xf2,
974 0xfa, 0xe6, 0xec, 0x01, 0x02, 0x03, 0x9b, 0xf5,
975 0x04, 0xa7, 0xf6, 0xf9, 0x05, 0x06, 0xeb, 0xef,
976 0x07, 0x08, 0x09, 0x0a, 0xac, 0x0b, 0x0c, 0xe3,
977 0xae, 0x0d, 0xee, 0xe9, 0x0e, 0xe1, 0x0f, 0xf3,
978 0x10, 0x11, 0xf4, 0x12, 0xe7, 0xe5, 0x13, 0x14,
979 0xe4, 0x15, 0x16, 0x17, 0xa0, 0x18, 0x1a, 0x1b,
980 0xc2, 0x9b, 0xad, 0xac, 0xf8, 0x01, 0xae, 0x02,
981 0x03, 0xe5, 0xe7, 0xe8, 0xf9, 0xe9, 0xeb, 0x04,
982 0xe3, 0xe1, 0x05, 0xf6, 0x06, 0xe4, 0x07, 0xe2,
983 0xf0, 0x08, 0x09, 0xf3, 0xf4, 0xf7, 0xef, 0x0a,
984 0x0b, 0x0c, 0x0d, 0xec, 0x0e, 0x0f, 0x10, 0xf5,
985 0xed, 0x11, 0xe6, 0xa0, 0x12, 0xf2, 0x13, 0x14,
986 0x15, 0xee, 0x16, 0x17, 0x18, 0x19, 0x0e, 0x0f,
987 0xad, 0xed, 0xf9, 0x9b, 0xae, 0x01, 0xf3, 0x02,
988 0x03, 0xf5, 0xf4, 0xf0, 0x04, 0xef, 0x05, 0xe9,
989 0x06, 0xe8, 0xa0, 0xe1, 0xec, 0x07, 0xf2, 0x08,
990 0xe5, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x9b, 0xf5,
991 0x19, 0x1a, 0xa9, 0xbb, 0xf6, 0xe6, 0x01, 0x9b,
992 0xad, 0xe2, 0xf0, 0x02, 0xa7, 0x03, 0x04, 0x05,
993 0xf5, 0xe3, 0xac, 0xe7, 0xf2, 0x06, 0xeb, 0x07,
994 0xec, 0xed, 0xee, 0xf9, 0x08, 0xae, 0x09, 0x0a,
995 0xe4, 0x0b, 0x0c, 0xf4, 0x0d, 0xf3, 0x0e, 0x0f,
996 0x10, 0xe1, 0xef, 0x11, 0xe9, 0x12, 0x13, 0xe5,
997 0x14, 0xa0, 0x15, 0x16, 0x17, 0x18, 0xa0, 0x16,
998 0xa2, 0xa7, 0xe2, 0xeb, 0xed, 0xee, 0x9b, 0xf7,
999 0x01, 0x02, 0x03, 0xbb, 0xf9, 0xf0, 0x04, 0x05,
1000 0xec, 0x06, 0x07, 0x08, 0xf5, 0xe1, 0x09, 0xac,
1001 0xe3, 0x0a, 0xe8, 0x0b, 0xe9, 0x0c, 0xef, 0xf3,
1002 0xae, 0x0d, 0x0e, 0xe5, 0x0f, 0x10, 0x11, 0xf4,
1003 0x12, 0x13, 0x14, 0x15, 0x14, 0x15, 0xbb, 0xe2,
1004 0xad, 0xed, 0x01, 0x9b, 0xa7, 0xe3, 0xac, 0xec,
1005 0xee, 0x02, 0xf7, 0x03, 0x04, 0xf9, 0x05, 0x06,
1006 0x07, 0x08, 0xf4, 0xae, 0xf5, 0x09, 0x0a, 0xf2,
1007 0xe1, 0xf3, 0x0b, 0x0c, 0x0d, 0xe9, 0x0e, 0x0f,
1008 0xef, 0xe5, 0x10, 0xa0, 0xe8, 0x11, 0x12, 0x13,
1009 0x11, 0x12, 0xef, 0xf6, 0x9b, 0xeb, 0xf9, 0x01,
1010 0xa0, 0xe2, 0x02, 0xe1, 0x03, 0xed, 0x04, 0xe3,
1011 0xe9, 0x05, 0xe4, 0xe5, 0xe7, 0x06, 0xec, 0xf0,
1012 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xf3, 0x0c, 0xf4,
1013 0xee, 0x0d, 0xf2, 0x0e, 0x0f, 0x10, 0x05, 0xe5,
1014 0xf3, 0xf9, 0x9b, 0x01, 0xef, 0x02, 0x03, 0xe1,
1015 0x04, 0xe9, 0x0a, 0x0b, 0xae, 0x9b, 0xec, 0xed,
1016 0x01, 0x02, 0xf3, 0xee, 0xf2, 0x03, 0xe5, 0x04,
1017 0xe8, 0xa0, 0xe1, 0x05, 0xef, 0x06, 0x07, 0x08,
1018 0xe9, 0x09, 0x05, 0x06, 0xa0, 0xac, 0xad, 0xf4,
1019 0xe9, 0x01, 0x02, 0xe1, 0xe5, 0x03, 0x9b, 0x04,
1020 0x11, 0xa0, 0xbf, 0xe1, 0xe2, 0xe6, 0xed, 0xe4,
1021 0xe9, 0xf7, 0xa7, 0x01, 0x02, 0xbb, 0x03, 0x04,
1022 0xec, 0x05, 0x9b, 0xee, 0x06, 0xef, 0x07, 0xac,
1023 0xe5, 0xf3, 0x08, 0x09, 0x0a, 0xae, 0x0b, 0x0c,
1024 0x0d, 0x0e, 0x0f, 0x10, 0x06, 0x07, 0xa0, 0xae,
1025 0xe1, 0xe5, 0xec, 0xfa, 0x9b, 0xef, 0xe9, 0x01,
1026 0x02, 0x03, 0x04, 0x05, 0x9b, 0x9b, 0x9b, 0x9b,
1027 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b };
1028
processSection(const char * data,int size)1029 void DvbPmtFilter::processSection(const char *data, int size)
1030 {
1031 unsigned char tableId = data[0];
1032
1033 if (tableId != 0x02) {
1034 return;
1035 }
1036
1037 DvbPmtSection pmtSection(data, size);
1038
1039 if (!pmtSection.isValid() || (pmtSection.programNumber() != programNumber)) {
1040 return;
1041 }
1042
1043 if ((size == lastPmtSectionData.size()) &&
1044 (memcmp(data, lastPmtSectionData.constData(), size) == 0)) {
1045 return;
1046 }
1047
1048 lastPmtSectionData = pmtSection.toByteArray();
1049 emit pmtSectionChanged(lastPmtSectionData);
1050 }
1051
initPat(int transportStreamId,int programNumber,int pmtPid)1052 void DvbSectionGenerator::initPat(int transportStreamId, int programNumber, int pmtPid)
1053 {
1054 Q_ASSERT((pmtPid >= 0) && (pmtPid <= 0x1fff));
1055
1056 char *data = startSection(16);
1057 data[0] = 0x00;
1058 data[3] = char(transportStreamId >> 8);
1059 data[4] = char(transportStreamId);
1060 data[8] = char(programNumber >> 8);
1061 data[9] = char(programNumber);
1062 data[10] = 0xe0 | char(pmtPid >> 8);
1063 data[11] = char(pmtPid);
1064 endSection(16, 0x00);
1065 }
1066
initPmt(int pmtPid,const DvbPmtSection & section,const QList<int> & pids)1067 void DvbSectionGenerator::initPmt(int pmtPid, const DvbPmtSection §ion, const QList<int> &pids)
1068 {
1069 Q_ASSERT(section.isValid());
1070
1071 char *data = startSection(section.getSectionLength());
1072
1073 DvbPmtSectionEntry entry = section.entries();
1074 memcpy(data, section.getData(), entry.getData() - section.getData());
1075 int size = int(entry.getData() - section.getData());
1076
1077 while (entry.isValid()) {
1078 if (pids.contains(entry.pid())) {
1079 memcpy(data + size, entry.getData(), entry.getLength());
1080 size += entry.getLength();
1081 }
1082
1083 entry.advance();
1084 }
1085
1086 endSection(size + 4, pmtPid);
1087 }
1088
generatePackets()1089 QByteArray DvbSectionGenerator::generatePackets()
1090 {
1091 char *data = packets.data();
1092
1093 for (int i = 3; i < packets.size(); i += 188) {
1094 data[i] = (data[i] & 0xf0) | char(continuityCounter);
1095 continuityCounter = (continuityCounter + 1) & 0x0f;
1096 }
1097
1098 return packets;
1099 }
1100
startSection(int sectionLength)1101 char *DvbSectionGenerator::startSection(int sectionLength)
1102 {
1103 Q_ASSERT((sectionLength >= 4) && (sectionLength <= 0x1002));
1104 packets.resize(((sectionLength / 184) + 1) * 188);
1105 return packets.data() + 5;
1106 }
1107
endSection(int sectionLength,int pid)1108 void DvbSectionGenerator::endSection(int sectionLength, int pid)
1109 {
1110 Q_ASSERT((sectionLength >= 4) && (sectionLength <= 0x1002));
1111 Q_ASSERT((pid >= 0) && (pid <= 0x1fff));
1112
1113 packets.resize(((sectionLength / 184) + 1) * 188);
1114 char *data = packets.data();
1115
1116 data[0] = 0x47;
1117 data[1] = 0x40 | char(pid >> 8);
1118 data[2] = char(pid);
1119 data[3] = 0x10;
1120 data[4] = 0x00;
1121 data[6] = 0xb0 | char((sectionLength - 3) >> 8);
1122 data[7] = char(sectionLength - 3);
1123 data[10] = 0xc1 | char(versionNumber << 1);
1124 data[11] = 0x00;
1125 data[12] = 0x00;
1126
1127 int size = sectionLength + 5;
1128 unsigned int crc32 = 0xffffffff;
1129
1130 for (int i = 5; i < (size - 4); ++i) {
1131 unsigned char byte = data[i];
1132 crc32 = (crc32 << 8) ^ DvbStandardSection::crc32Table[(crc32 >> 24) ^ byte];
1133 }
1134
1135 data[size - 4] = char(crc32 >> 24);
1136 data[size - 3] = char(crc32 >> 16);
1137 data[size - 2] = char(crc32 >> 8);
1138 data[size - 1] = char(crc32);
1139
1140 for (int i = 188; i < size; i += 188) {
1141 // split the section into multiple packets if necessary
1142 memmove(data + i + 4, data + i, size - i);
1143 data[i] = 0x47;
1144 data[i + 1] = char(pid >> 8);
1145 data[i + 2] = char(pid);
1146 data[i + 3] = 0x10; // continuity counter is filled out in generatePackets()
1147 size += 4;
1148 }
1149
1150 // pad the unused bytes
1151 memset(data + size, 0xff, packets.size() - size);
1152
1153 // increment version number
1154 versionNumber = (versionNumber + 1) & 0x1f;
1155 }
1156
DvbPmtParser(const DvbPmtSection & section)1157 DvbPmtParser::DvbPmtParser(const DvbPmtSection §ion) : videoPid(-1), teletextPid(-1)
1158 {
1159 for (DvbPmtSectionEntry entry = section.entries(); entry.isValid(); entry.advance()) {
1160 QString streamLanguage;
1161 QString subtitleLanguage;
1162 bool teletextPresent = false;
1163 bool ac3Present = false;
1164
1165 for (DvbDescriptor descriptor = entry.descriptors(); descriptor.isValid();
1166 descriptor.advance()) {
1167 switch (descriptor.descriptorTag()) {
1168 case 0x0a: {
1169 DvbLanguageDescriptor languageDescriptor(descriptor);
1170
1171 if (!languageDescriptor.isValid()) {
1172 break;
1173 }
1174
1175 // ISO 8859-1 equals to unicode range 0x0000 - 0x00ff
1176 streamLanguage.clear();
1177 streamLanguage.append(QChar(languageDescriptor.languageCode1()));
1178 streamLanguage.append(QChar(languageDescriptor.languageCode2()));
1179 streamLanguage.append(QChar(languageDescriptor.languageCode3()));
1180 break;
1181 }
1182
1183 case 0x56:
1184 teletextPresent = true;
1185 break;
1186
1187 case 0x59: {
1188 DvbSubtitleDescriptor subtitleDescriptor(descriptor);
1189
1190 if (!subtitleDescriptor.isValid()) {
1191 break;
1192 }
1193
1194 if ((subtitleDescriptor.subtitleType() >= 0x01) &&
1195 (subtitleDescriptor.subtitleType() <= 0x03)) {
1196 // FIXME how to deal with vbi and teletext subtitles?
1197 qCInfo(logDvbSi, "Unsupported subtitle found: VBI/teletext (%d)", subtitleDescriptor.subtitleType());
1198 }
1199
1200 // ISO 8859-1 equals to unicode range 0x0000 - 0x00ff
1201 subtitleLanguage.clear();
1202 subtitleLanguage.append(QChar(subtitleDescriptor.languageCode1()));
1203 subtitleLanguage.append(QChar(subtitleDescriptor.languageCode2()));
1204 subtitleLanguage.append(QChar(subtitleDescriptor.languageCode3()));
1205 break;
1206 }
1207
1208 case 0x6a:
1209 case 0x7a:
1210 ac3Present = true;
1211 break;
1212 }
1213 }
1214
1215
1216 // Updated with Table 2-34 of ISO/IEC 13818-1:2018 / ITU-T H.222.0 2017
1217 // and with https://www.wikiwand.com/en/Program-specific_information
1218 // (as private IDs are not at ITU/ISO/IEC specs
1219
1220 switch (entry.streamType()) {
1221 case 0x01: // ISO/IEC 11172-2 (MPEG-1) video
1222 case 0x02: // ITU-T H.262 (MPEG2) video or ISO/IEC 11172-2
1223 case 0x10: // ISO/IEC 14496-2 (MPEG-4) video
1224 case 0x1b: // ITU-T H.264 video
1225 case 0x1e: // ISO/IEC 23002-3 (MPEG-4 auxiliary video)
1226 case 0x1f: // ITU-T H.264 Annex G (MPEG-4 SVC sub-bitstream on AVC)
1227 case 0x20: // ITU-T H.264 Annex H (MPEG-4 MVC sub-bitstream on AVC)
1228 case 0x21: // ITU-T T.800 (JPEG 2000 video)
1229 case 0x22: // ITU-T H.262 additional view for 3D
1230 case 0x23: // ITU-T H.264 additional view for 3D
1231 case 0x24: // ITU-T H.265 or HEVC sub-bitstream
1232 case 0x25: // ITU-T H.265 Annex A - HEVC video stream or subset
1233 case 0x26: // ITU-T H.264 Annex I - MVCD substream on HEVC
1234 case 0x28: // ITU-T H.265 Annex G - HEVC enhancemeng sub-partition
1235 case 0x29: // ITU-T H.265 Annex G - HEVC temporal enhancement
1236 case 0x2a: // ITU-T H.265 Annex H - HEVC enhancement
1237 case 0x2b: // ITU-T H.265 Annex H - HEVC temporal enhancement
1238 case 0x42: // CAVS video
1239 // User-private video streams
1240 case 0x80: // MPEG-2 MOTO video
1241 case 0xd1: // Dirac (Ultra HD video)
1242 if (videoPid < 0) {
1243 videoPid = entry.pid();
1244 } else {
1245 qCInfo(logDvbSi, "More than one video PID");
1246 }
1247
1248 break;
1249
1250 case 0x03: // ISO/IEC 11172-3 (MPEG1) audio
1251 case 0x04: // ISO/IEC 13818-3 (MPEG2) audio
1252 case 0x07: // ISO/IEC 13522 MHEG - DTS and DTS-HD Audio
1253 case 0x0f: // ISO/IEC 13818-7 Audio with ADTS transport syntax
1254 case 0x11: // ISO/IEC 14496-3 Audio (AAC / LATM)
1255 case 0x1c: // ISO/IEC 14496-3 Audio, without additional transport syntax
1256 case 0x2d: // ISO/IEC 23008-3 Audio with MHAS – main stream
1257 case 0x2e: // ISO/IEC 23008-3 Audio with MHAS – auxiliary stream
1258 // User-private audio streams
1259 case 0x81: // AC-3 audio (ATSC specific)
1260 case 0x83: // TrueHD lossless audio
1261 case 0x84: // SDDS
1262 case 0x85: // DTS on HDMV
1263 case 0x86: // DTS 8 channel
1264 case 0x87: // enhanced AC-3 audio (ATSC specific)
1265 case 0x8a: // DTS
1266 case 0x91: // A52 VLS
1267 case 0x94: // SDDS
1268 audioPids.append(qMakePair(entry.pid(), streamLanguage));
1269 break;
1270
1271 case 0x06: // private data - can be teletext, subtitle, ac3 or something else
1272 if (teletextPresent) {
1273 if (teletextPid < 0) {
1274 teletextPid = entry.pid();
1275 } else {
1276 qCInfo(logDvbSi, "More than one teletext PID");
1277 }
1278 }
1279
1280 if (!subtitleLanguage.isEmpty()) {
1281 subtitlePids.append(qMakePair(entry.pid(), subtitleLanguage));
1282
1283 if (teletextPresent) {
1284 qCInfo(logDvbSi, "Subtitle and teletext on the same PID");
1285 }
1286 }
1287
1288 if (ac3Present) {
1289 audioPids.append(qMakePair(entry.pid(), streamLanguage));
1290 }
1291
1292 break;
1293
1294 default:
1295 if (!subtitleLanguage.isEmpty()) {
1296 qCInfo(logDvbSi, "Subtitle with unexpected stream type found");
1297 }
1298
1299 if (teletextPresent) {
1300 qCInfo(logDvbSi, "Teletext with unexpected stream type found");
1301 }
1302
1303 break;
1304 }
1305 }
1306 }
1307
initEitSectionEntry(const char * data,int size)1308 void AtscEitSectionEntry::initEitSectionEntry(const char *data, int size)
1309 {
1310 if (size < 12) {
1311 if (size != 0) {
1312 qCInfo(logDvbSi, "Invalid entry");
1313 }
1314
1315 initSectionData();
1316 return;
1317 }
1318
1319 titleLength = quint8(data[9]);
1320
1321 if (titleLength > (size - 12)) {
1322 qCInfo(logDvbSi, "Adjusting length");
1323 titleLength = (size - 12);
1324 }
1325
1326 // too ugly to be automatically generated
1327 int entryLength = ((((quint8(data[10 + titleLength]) & 0xf) << 8) |
1328 quint8(data[11 + titleLength])) + 12 + titleLength);
1329
1330 if (entryLength > size) {
1331 qCInfo(logDvbSi, "Adjusting length");
1332 entryLength = size;
1333 }
1334
1335 initSectionData(data, entryLength, size);
1336 }
1337
1338 // everything below this line is automatically generated
1339
initPatSectionEntry(const char * data,int size)1340 void DvbPatSectionEntry::initPatSectionEntry(const char *data, int size)
1341 {
1342 if (size < 4) {
1343 if (size != 0) {
1344 qCWarning(logDvbSi, "Invalid entry at descriptor");
1345 }
1346
1347 initSectionData();
1348 return;
1349 }
1350
1351 initSectionData(data, 4, size);
1352 }
1353
initPmtSectionEntry(const char * data,int size)1354 void DvbPmtSectionEntry::initPmtSectionEntry(const char *data, int size)
1355 {
1356 if (size < 5) {
1357 if (size != 0) {
1358 qCWarning(logDvbSi, "Invalid entry at descriptor");
1359 }
1360
1361 initSectionData();
1362 return;
1363 }
1364
1365 int entryLength = ((((quint8(data[3]) & 0xf) << 8) | quint8(data[4])) + 5);
1366
1367 if (entryLength > size) {
1368 qCWarning(logDvbSi, "Adjusting length on descriptor");
1369 entryLength = size;
1370 }
1371
1372 initSectionData(data, entryLength, size);
1373 }
1374
initSdtSectionEntry(const char * data,int size)1375 void DvbSdtSectionEntry::initSdtSectionEntry(const char *data, int size)
1376 {
1377 if (size < 5) {
1378 if (size != 0) {
1379 qCWarning(logDvbSi, "Invalid entry at descriptor");
1380 }
1381
1382 initSectionData();
1383 return;
1384 }
1385
1386 int entryLength = ((((quint8(data[3]) & 0xf) << 8) | quint8(data[4])) + 5);
1387
1388 if (entryLength > size) {
1389 qCWarning(logDvbSi, "Adjusting length on descriptor");
1390 entryLength = size;
1391 }
1392
1393 initSectionData(data, entryLength, size);
1394 }
1395
initEitSectionEntry(const char * data,int size)1396 void DvbEitSectionEntry::initEitSectionEntry(const char *data, int size)
1397 {
1398 if (size < 12) {
1399 if (size != 0) {
1400 qCWarning(logDvbSi, "Invalid entry at descriptor");
1401 }
1402
1403 initSectionData();
1404 return;
1405 }
1406
1407 int entryLength = ((((quint8(data[10]) & 0xf) << 8) | quint8(data[11])) + 12);
1408
1409 if (entryLength > size) {
1410 qCWarning(logDvbSi, "Adjusting length on descriptor");
1411 entryLength = size;
1412 }
1413
1414 initSectionData(data, entryLength, size);
1415 }
1416
initEitContentEntry(const char * data,int size)1417 void DvbEitContentEntry::initEitContentEntry(const char *data, int size)
1418 {
1419 if (size < 2) {
1420 if (size != 0) {
1421 qCWarning(logDvbSi, "Invalid entry at descriptor");
1422 }
1423
1424 initSectionData();
1425 return;
1426 }
1427
1428 initSectionData(data, 2, size);
1429 }
1430
initParentalRatingEntry(const char * data,int size)1431 void DvbParentalRatingEntry::initParentalRatingEntry(const char *data, int size)
1432 {
1433 if (size < 4) {
1434 if (size != 0) {
1435 qCWarning(logDvbSi, "Invalid entry at descriptor");
1436 }
1437
1438 initSectionData();
1439 return;
1440 }
1441
1442 initSectionData(data, 4, size);
1443 }
1444
initNitSectionEntry(const char * data,int size)1445 void DvbNitSectionEntry::initNitSectionEntry(const char *data, int size)
1446 {
1447 if (size < 6) {
1448 if (size != 0) {
1449 qCWarning(logDvbSi, "Invalid entry at descriptor");
1450 }
1451
1452 initSectionData();
1453 return;
1454 }
1455
1456 int entryLength = ((((quint8(data[4]) & 0xf) << 8) | quint8(data[5])) + 6);
1457
1458 if (entryLength > size) {
1459 qCWarning(logDvbSi, "Adjusting length on descriptor");
1460 entryLength = size;
1461 }
1462
1463 initSectionData(data, entryLength, size);
1464 }
1465
initMgtSectionEntry(const char * data,int size)1466 void AtscMgtSectionEntry::initMgtSectionEntry(const char *data, int size)
1467 {
1468 if (size < 11) {
1469 if (size != 0) {
1470 qCWarning(logDvbSi, "Invalid entry at descriptor");
1471 }
1472
1473 initSectionData();
1474 return;
1475 }
1476
1477 int entryLength = ((((quint8(data[9]) & 0xf) << 8) | quint8(data[10])) + 11);
1478
1479 if (entryLength > size) {
1480 qCWarning(logDvbSi, "Adjusting length on descriptor");
1481 entryLength = size;
1482 }
1483
1484 initSectionData(data, entryLength, size);
1485 }
1486
initVctSectionEntry(const char * data,int size)1487 void AtscVctSectionEntry::initVctSectionEntry(const char *data, int size)
1488 {
1489 if (size < 32) {
1490 if (size != 0) {
1491 qCWarning(logDvbSi, "Invalid entry at descriptor");
1492 }
1493
1494 initSectionData();
1495 return;
1496 }
1497
1498 int entryLength = ((((quint8(data[30]) & 0x3) << 8) | quint8(data[31])) + 32);
1499
1500 if (entryLength > size) {
1501 qCWarning(logDvbSi, "Adjusting length on descriptor");
1502 entryLength = size;
1503 }
1504
1505 initSectionData(data, entryLength, size);
1506 }
1507
DvbLanguageDescriptor(const DvbDescriptor & descriptor)1508 DvbLanguageDescriptor::DvbLanguageDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor)
1509 {
1510 if (getLength() < 6) {
1511 qCWarning(logDvbSi, "Invalid descriptor");
1512 initSectionData();
1513 return;
1514 }
1515 }
1516
DvbSubtitleDescriptor(const DvbDescriptor & descriptor)1517 DvbSubtitleDescriptor::DvbSubtitleDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor)
1518 {
1519 if (getLength() < 10) {
1520 qCWarning(logDvbSi, "Invalid descriptor");
1521 initSectionData();
1522 return;
1523 }
1524 }
1525
DvbServiceDescriptor(const DvbDescriptor & descriptor)1526 DvbServiceDescriptor::DvbServiceDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor)
1527 {
1528 if (getLength() < 5) {
1529 qCWarning(logDvbSi, "Invalid descriptor");
1530 initSectionData();
1531 return;
1532 }
1533
1534 providerNameLength = at(3);
1535
1536 if (providerNameLength > (getLength() - 5)) {
1537 qCWarning(logDvbSi, "Adjusting length on descriptor");
1538 providerNameLength = (getLength() - 5);
1539 }
1540
1541 serviceNameLength = at(4 + providerNameLength);
1542
1543 if (serviceNameLength > (getLength() - (5 + providerNameLength))) {
1544 qCWarning(logDvbSi, "Adjusting length on descriptor");
1545 serviceNameLength = (getLength() - (5 + providerNameLength));
1546 }
1547 }
1548
DvbShortEventDescriptor(const DvbDescriptor & descriptor)1549 DvbShortEventDescriptor::DvbShortEventDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor)
1550 {
1551 if (getLength() < 7) {
1552 qCWarning(logDvbSi, "Invalid descriptor");
1553 initSectionData();
1554 return;
1555 }
1556
1557 eventNameLength = at(5);
1558
1559 if (eventNameLength > (getLength() - 7)) {
1560 qCWarning(logDvbSi, "Adjusting length on descriptor");
1561 eventNameLength = (getLength() - 7);
1562 }
1563
1564 textLength = at(6 + eventNameLength);
1565
1566 if (textLength > (getLength() - (7 + eventNameLength))) {
1567 qCWarning(logDvbSi, "Adjusting length on descriptor");
1568 textLength = (getLength() - (7 + eventNameLength));
1569 }
1570 }
1571
DvbExtendedEventDescriptor(const DvbDescriptor & descriptor)1572 DvbExtendedEventDescriptor::DvbExtendedEventDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor)
1573 {
1574 if (getLength() < 8) {
1575 qCWarning(logDvbSi, "Invalid descriptor");
1576 initSectionData();
1577 return;
1578 }
1579
1580 itemsLength = at(6);
1581
1582 if (itemsLength > (getLength() - 8)) {
1583 qCWarning(logDvbSi, "Adjusting length on descriptor");
1584 itemsLength = (getLength() - 8);
1585 }
1586
1587 textLength = at(7 + itemsLength);
1588
1589 if (textLength > (getLength() - (8 + itemsLength))) {
1590 qCWarning(logDvbSi, "Adjusting length on descriptor");
1591 textLength = (getLength() - (8 + itemsLength));
1592 }
1593 }
1594
DvbContentDescriptor(const DvbDescriptor & descriptor)1595 DvbContentDescriptor::DvbContentDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor)
1596 {
1597 if (getLength() < 2) {
1598 qCWarning(logDvbSi, "Invalid descriptor");
1599 initSectionData();
1600 return;
1601 }
1602 }
1603
DvbParentalRatingDescriptor(const DvbDescriptor & descriptor)1604 DvbParentalRatingDescriptor::DvbParentalRatingDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor)
1605 {
1606 if (getLength() < 2) {
1607 qCWarning(logDvbSi, "Invalid descriptor");
1608 initSectionData();
1609 return;
1610 }
1611 }
1612
DvbCableDescriptor(const DvbDescriptor & descriptor)1613 DvbCableDescriptor::DvbCableDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor)
1614 {
1615 if (getLength() < 13) {
1616 qCWarning(logDvbSi, "Invalid descriptor");
1617 initSectionData();
1618 return;
1619 }
1620 }
1621
DvbSatelliteDescriptor(const DvbDescriptor & descriptor)1622 DvbSatelliteDescriptor::DvbSatelliteDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor)
1623 {
1624 if (getLength() < 13) {
1625 qCWarning(logDvbSi, "Invalid descriptor");
1626 initSectionData();
1627 return;
1628 }
1629 }
1630
DvbTerrestrialDescriptor(const DvbDescriptor & descriptor)1631 DvbTerrestrialDescriptor::DvbTerrestrialDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor)
1632 {
1633 if (getLength() < 13) {
1634 qCWarning(logDvbSi, "Invalid descriptor");
1635 initSectionData();
1636 return;
1637 }
1638 }
1639
IsdbTerrestrialDescriptor(const DvbDescriptor & descriptor)1640 IsdbTerrestrialDescriptor::IsdbTerrestrialDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor)
1641 {
1642 if (getLength() < 4) {
1643 qCWarning(logDvbSi, "Invalid descriptor");
1644 initSectionData();
1645 return;
1646 }
1647 }
1648
AtscChannelNameDescriptor(const DvbDescriptor & descriptor)1649 AtscChannelNameDescriptor::AtscChannelNameDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor)
1650 {
1651 if (getLength() < 2) {
1652 qCWarning(logDvbSi, "Invalid descriptor");
1653 initSectionData();
1654 return;
1655 }
1656 }
1657
initPatSection(const char * data,int size)1658 void DvbPatSection::initPatSection(const char *data, int size)
1659 {
1660 if (size < 12) {
1661 initSectionData();
1662 return;
1663 }
1664
1665 initStandardSection(data, size);
1666 }
1667
initPmtSection(const char * data,int size)1668 void DvbPmtSection::initPmtSection(const char *data, int size)
1669 {
1670 if (size < 16) {
1671 initSectionData();
1672 return;
1673 }
1674
1675 initStandardSection(data, size);
1676 descriptorsLength = ((at(10) & 0xf) << 8) | at(11);
1677
1678 if (descriptorsLength > (getLength() - 16)) {
1679 qCWarning(logDvbSi, "Adjusting length on descriptor");
1680 descriptorsLength = (getLength() - 16);
1681 }
1682 }
1683
initSdtSection(const char * data,int size)1684 void DvbSdtSection::initSdtSection(const char *data, int size)
1685 {
1686 if (size < 15) {
1687 initSectionData();
1688 return;
1689 }
1690
1691 initStandardSection(data, size);
1692 }
1693
initEitSection(const char * data,int size)1694 void DvbEitSection::initEitSection(const char *data, int size)
1695 {
1696 if (size < 18) {
1697 initSectionData();
1698 return;
1699 }
1700
1701 initStandardSection(data, size);
1702 }
1703
initNitSection(const char * data,int size)1704 void DvbNitSection::initNitSection(const char *data, int size)
1705 {
1706 if (size < 16) {
1707 initSectionData();
1708 return;
1709 }
1710
1711 initStandardSection(data, size);
1712 descriptorsLength = ((at(8) & 0xf) << 8) | at(9);
1713
1714 if (descriptorsLength > (getLength() - 16)) {
1715 qCWarning(logDvbSi, "Adjusting length on descriptor");
1716 descriptorsLength = (getLength() - 16);
1717 }
1718
1719 entriesLength = ((at(10 + descriptorsLength) & 0xf) << 8) | at(11 + descriptorsLength);
1720
1721 if (entriesLength > (getLength() - (16 + descriptorsLength))) {
1722 qCWarning(logDvbSi, "Adjusting length on descriptor");
1723 entriesLength = (getLength() - (16 + descriptorsLength));
1724 }
1725 }
1726
initMgtSection(const char * data,int size)1727 void AtscMgtSection::initMgtSection(const char *data, int size)
1728 {
1729 if (size < 17) {
1730 initSectionData();
1731 return;
1732 }
1733
1734 initStandardSection(data, size);
1735 }
1736
initVctSection(const char * data,int size)1737 void AtscVctSection::initVctSection(const char *data, int size)
1738 {
1739 if (size < 14) {
1740 initSectionData();
1741 return;
1742 }
1743
1744 initStandardSection(data, size);
1745 }
1746
initEitSection(const char * data,int size)1747 void AtscEitSection::initEitSection(const char *data, int size)
1748 {
1749 if (size < 14) {
1750 initSectionData();
1751 return;
1752 }
1753
1754 initStandardSection(data, size);
1755 }
1756
initEttSection(const char * data,int size)1757 void AtscEttSection::initEttSection(const char *data, int size)
1758 {
1759 if (size < 17) {
1760 initSectionData();
1761 return;
1762 }
1763
1764 initStandardSection(data, size);
1765 }
1766