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 &section, 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 &section) : 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