File indexing completed on 2024-05-12 04:52:19
0001 /* 0002 * dvbsi.cpp 0003 * 0004 * Copyright (C) 2008-2011 Christoph Pfister <christophpfister@gmail.com> 0005 * 0006 * This program is free software; you can redistribute it and/or modify 0007 * it under the terms of the GNU General Public License as published by 0008 * the Free Software Foundation; either version 2 of the License, or 0009 * (at your option) any later version. 0010 * 0011 * This program is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 * GNU General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU General Public License along 0017 * with this program; if not, write to the Free Software Foundation, Inc., 0018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 0019 */ 0020 0021 #include "../log.h" 0022 0023 #include <QTextCodec> 0024 0025 #include "dvbsi.h" 0026 0027 void DvbSection::initSection(const char *data, int size) 0028 { 0029 if (size < 3) { 0030 initSectionData(); 0031 return; 0032 } 0033 0034 int sectionLength = ((((quint8(data[1]) & 0xf) << 8) | quint8(data[2])) + 3); 0035 0036 if (sectionLength > size) { 0037 qCInfo(logDvbSi, "Adjusting length"); 0038 sectionLength = size; 0039 } 0040 0041 initSectionData(data, sectionLength, size); 0042 } 0043 0044 int DvbStandardSection::verifyCrc32(const char *data, int size) 0045 { 0046 unsigned int crc32 = 0xffffffff; 0047 0048 for (int i = 0; i < size; ++i) { 0049 crc32 = ((crc32 << 8) ^ crc32Table[(crc32 >> 24) ^ quint8(data[i])]); 0050 } 0051 0052 return crc32; 0053 } 0054 0055 /* 0056 * unsigned int crc32TableValue(int index) 0057 * { 0058 * unsigned int value = 0; 0059 * 0060 * for (int i = 8; i >= 0; --i) { 0061 * if (((value & 0x80000000) != 0) ^ ((index & (1 << i)) != 0)) { 0062 * value = (value << 1) ^ 0x04c11db7; 0063 * } else { 0064 * value <<= 1; 0065 * } 0066 * } 0067 * 0068 * return value; 0069 * } 0070 */ 0071 0072 const unsigned int DvbStandardSection::crc32Table[] = 0073 { 0074 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0075 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 0076 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0077 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0078 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0079 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 0080 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0081 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, 0082 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0083 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0084 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0085 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 0086 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0087 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, 0088 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0089 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0090 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0091 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, 0092 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0093 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0094 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0095 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0096 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0097 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 0098 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0099 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0100 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0101 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0102 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0103 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0104 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0105 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, 0106 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0107 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0108 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0109 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, 0110 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0111 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, 0112 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0113 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0114 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0115 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, 0116 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0117 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 0118 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0119 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0120 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0121 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, 0122 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0123 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0124 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0125 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0126 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0127 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 0128 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0129 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0130 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0131 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0132 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0133 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0134 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0135 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, 0136 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0137 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 0138 }; 0139 0140 void DvbStandardSection::initStandardSection(const char *data, int size) 0141 { 0142 if (size < 12) { 0143 initSectionData(); 0144 return; 0145 } 0146 0147 initSection(data, size); 0148 } 0149 0150 class Iso6937Codec : public QTextCodec 0151 { 0152 public: 0153 Iso6937Codec() { } 0154 ~Iso6937Codec() { } 0155 0156 QByteArray name() const override 0157 { 0158 return "ISO 6937"; // actually a superset of ISO 6937 0159 } 0160 0161 int mibEnum() const override 0162 { 0163 return 14; 0164 } 0165 0166 QByteArray convertFromUnicode(const QChar *, int, QTextCodec::ConverterState *) const override 0167 { 0168 return QByteArray(); 0169 } 0170 0171 QString convertToUnicode(const char *input, int size, QTextCodec::ConverterState *) const override 0172 { 0173 QString result; 0174 unsigned short diacriticalMark = 0; 0175 0176 for (; size > 0; ++input, --size) { 0177 unsigned short value = table[quint8(*input)]; 0178 0179 if (value == 0xffff) { 0180 continue; 0181 } 0182 0183 if ((value & 0xff00) == 0x0300) { 0184 // diacritical mark 0185 diacriticalMark = value; 0186 continue; 0187 } 0188 0189 result.append(value); 0190 0191 if (diacriticalMark != 0) { 0192 result.append(diacriticalMark); 0193 diacriticalMark = 0; 0194 } 0195 } 0196 0197 return result.normalized(QString::NormalizationForm_C); 0198 } 0199 0200 private: 0201 static const unsigned short table[]; 0202 }; 0203 0204 const unsigned short Iso6937Codec::table[] = { 0205 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0206 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0207 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0208 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0209 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0210 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0211 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0212 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0213 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0214 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0215 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0216 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0217 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0218 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0219 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0220 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0221 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0222 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0223 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0224 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0225 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0xffff, 0x00a7, 0226 0x00a4, 0x2018, 0x201c, 0x00ab, 0x2190, 0x2191, 0x2192, 0x2193, 0227 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00d7, 0x00b5, 0x00b6, 0x00b7, 0228 0x00f7, 0x2019, 0x201d, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, 0229 0xffff, 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0306, 0x0307, 0230 0x0308, 0xffff, 0x030a, 0x0327, 0xffff, 0x030b, 0x0328, 0x030c, 0231 0x2015, 0x00b9, 0x00ae, 0x00a9, 0x2122, 0x266a, 0x00ac, 0x00a6, 0232 0xffff, 0xffff, 0xffff, 0xffff, 0x215b, 0x215c, 0x215d, 0x215e, 0233 0x2126, 0x00c6, 0x0110, 0x00aa, 0x0126, 0xffff, 0x0132, 0x013f, 0234 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00de, 0x0166, 0x014a, 0x0149, 0235 0x0138, 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0140, 0236 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x0167, 0x014b, 0x00ad 0237 }; 0238 0239 QString DvbSiText::convertText(const char *data, int size) 0240 { 0241 TextEncoding encoding = Iso6937; 0242 0243 if (size < 1) { 0244 return QString(); 0245 } 0246 0247 if (size >2 && data[0] == 0x0e && data[size - 1] == 0x0f ) { 0248 // Remove LS0 and LS1 codes found on some ISDB-T streams 0249 data++; 0250 size -= 2; 0251 0252 encoding = Iso8859_1; 0253 } 0254 0255 if (override6937) 0256 encoding = Iso8859_1; 0257 0258 if (quint8(data[0]) < 0x20) { 0259 switch (data[0]) { 0260 case 0x00: encoding = Iso6937; break; 0261 case 0x01: encoding = Iso8859_5; break; 0262 case 0x02: encoding = Iso8859_6; break; 0263 case 0x03: encoding = Iso8859_7; break; 0264 case 0x04: encoding = Iso8859_8; break; 0265 case 0x05: encoding = Iso8859_9; break; 0266 case 0x06: encoding = Iso8859_10; break; 0267 case 0x07: encoding = Iso8859_11; break; 0268 case 0x09: encoding = Iso8859_13; break; 0269 case 0x0a: encoding = Iso8859_14; break; 0270 case 0x0b: encoding = Iso8859_15; break; 0271 case 0x11: encoding = Iso10646_ucs2; break; 0272 case 0x12: encoding = Iso2022_kr; break; 0273 case 0x13: encoding = Gb2312; break; 0274 case 0x14: encoding = Utf_16be; break; 0275 case 0x15: encoding = Utf_8; break; 0276 case 0x10: { 0277 if (size < 3) { 0278 return QString(); 0279 } 0280 0281 if (data[1] != 0) { 0282 return QString(); 0283 } 0284 0285 switch (data[2]) { 0286 case 0x01: encoding = Iso8859_1; break; 0287 case 0x02: encoding = Iso8859_2; break; 0288 case 0x03: encoding = Iso8859_3; break; 0289 case 0x04: encoding = Iso8859_4; break; 0290 case 0x05: encoding = Iso8859_5; break; 0291 case 0x06: encoding = Iso8859_6; break; 0292 case 0x07: encoding = Iso8859_7; break; 0293 case 0x08: encoding = Iso8859_8; break; 0294 case 0x09: encoding = Iso8859_9; break; 0295 case 0x0a: encoding = Iso8859_10; break; 0296 case 0x0b: encoding = Iso8859_11; break; 0297 case 0x0d: encoding = Iso8859_13; break; 0298 case 0x0e: encoding = Iso8859_14; break; 0299 case 0x0f: encoding = Iso8859_15; break; 0300 default: 0301 return QString(); 0302 } 0303 0304 data += 2; 0305 size -= 2; 0306 break; 0307 } 0308 } 0309 0310 data++; 0311 size--; 0312 } 0313 0314 if (codecTable[encoding] == NULL) { 0315 QTextCodec *codec = NULL; 0316 0317 switch (encoding) { 0318 case Iso6937: codec = new Iso6937Codec(); break; 0319 case Iso8859_1: codec = QTextCodec::codecForName("ISO 8859-1"); break; 0320 case Iso8859_2: codec = QTextCodec::codecForName("ISO 8859-2"); break; 0321 case Iso8859_3: codec = QTextCodec::codecForName("ISO 8859-3"); break; 0322 case Iso8859_4: codec = QTextCodec::codecForName("ISO 8859-4"); break; 0323 case Iso8859_5: codec = QTextCodec::codecForName("ISO 8859-5"); break; 0324 case Iso8859_6: codec = QTextCodec::codecForName("ISO 8859-6"); break; 0325 case Iso8859_7: codec = QTextCodec::codecForName("ISO 8859-7"); break; 0326 case Iso8859_8: codec = QTextCodec::codecForName("ISO 8859-8"); break; 0327 case Iso8859_9: codec = QTextCodec::codecForName("ISO 8859-9"); break; 0328 case Iso8859_10: codec = QTextCodec::codecForName("ISO 8859-10"); break; 0329 case Iso8859_11: codec = QTextCodec::codecForName("ISO 8859-11"); break; 0330 case Iso8859_13: codec = QTextCodec::codecForName("ISO 8859-13"); break; 0331 case Iso8859_14: codec = QTextCodec::codecForName("ISO 8859-14"); break; 0332 case Iso8859_15: codec = QTextCodec::codecForName("ISO 8859-15"); break; 0333 case Iso10646_ucs2: codec = QTextCodec::codecForName("UTF-16"); break; 0334 case Iso2022_kr: codec = QTextCodec::codecForName("ISO 2022-KR"); break; 0335 case Gb2312: codec = QTextCodec::codecForName("GB2312"); break; 0336 case Utf_16be: codec = QTextCodec::codecForName("UTF-16BE"); break; 0337 case Utf_8: codec = QTextCodec::codecForName("UTF-8"); break; 0338 } 0339 0340 Q_ASSERT(codec != NULL); 0341 codecTable[encoding] = codec; 0342 } 0343 0344 if (encoding <= Iso8859_15) { 0345 // only strip control codes for one-byte character tables 0346 0347 char *dest = new char[size]; 0348 char *destIt = dest; 0349 0350 for (const char *it = data; it != (data + size); ++it) { 0351 unsigned char value = *it; 0352 0353 if ((value < 0x80) || (value > 0x9f)) { 0354 *(destIt++) = value; 0355 } 0356 } 0357 0358 QString result = codecTable[encoding]->toUnicode(dest, int(destIt - dest)); 0359 delete[] dest; 0360 0361 return result; 0362 } 0363 0364 return codecTable[encoding]->toUnicode(data, size); 0365 } 0366 0367 void DvbSiText::setOverride6937(bool override) 0368 { 0369 override6937 = override; 0370 } 0371 0372 QTextCodec *DvbSiText::codecTable[EncodingTypeMax + 1] = { NULL }; 0373 bool DvbSiText::override6937 = false; 0374 0375 void DvbDescriptor::initDescriptor(const char *data, int size) 0376 { 0377 if (size < 2) { 0378 if (size != 0) { 0379 qCInfo(logDvbSi, "Invalid descriptor"); 0380 } 0381 0382 initSectionData(); 0383 return; 0384 } 0385 0386 int descriptorLength = (quint8(data[1]) + 2); 0387 0388 if (descriptorLength > size) { 0389 qCInfo(logDvbSi, "Adjusting length"); 0390 descriptorLength = size; 0391 } 0392 0393 initSectionData(data, descriptorLength, size); 0394 } 0395 0396 QString AtscPsipText::interpretTextData(const char *data, unsigned int len, 0397 unsigned int mode) 0398 { 0399 // Based on the "mode" values in A/65C Table 6.41, convert 0400 // the data into a string 0401 QString result; 0402 0403 if ((mode <= 0x06) || 0404 (mode >= 0x09 && mode <= 0x10) || 0405 (mode >= 0x20 && mode <= 0x27) || 0406 (mode >= 0x30 && mode <= 0x33)) { 0407 // Select UNICODE Code range based on mode as leading octet 0408 for (unsigned int i = 0; i < len; i++) { 0409 QChar val = (data[i] | (mode << 8)); 0410 result += val; 0411 } 0412 } else if (mode == 0x3f) { 0413 // UTF-16 0414 for (unsigned int i = 0; i < len; i += 2) { 0415 QChar val = ((unsigned char)data[i] * 256) + (unsigned char)data[i+1]; 0416 result += val; 0417 } 0418 } else { 0419 // We currently don't support the following: 0420 // 0x3e Standard Compression Scheme for UNICODE (SCSU) 0421 // 0x40/0x41 Taiwan 0422 // 0x48 South Korea 0423 qCInfo(logDvbSi, "Unsupported ATSC Text mode %d", mode); 0424 } 0425 return result; 0426 } 0427 0428 QString AtscPsipText::convertText(const char *data, int size) 0429 { 0430 QString result; 0431 0432 if (size < 1) { 0433 return QString(); 0434 } 0435 0436 unsigned int num_strings = quint8(data[0]); 0437 0438 if (num_strings == 0) { 0439 return result; 0440 } 0441 0442 // Note that for now we are only supporting the first string sent. If 0443 // multiple languages are sent, we only grab the first one provided 0444 int offset = 1; 0445 0446 // First three bytes are the ISO 639 language code 0447 offset += 3; 0448 0449 if (offset > size) { 0450 qCInfo(logDvbSi, "Adjusting length"); 0451 return result; 0452 } 0453 0454 int num_segments = quint8(data[offset++]); 0455 0456 for (int j = 0; j < num_segments; j++) { 0457 if ((offset + 3) > size) { 0458 qCInfo(logDvbSi, "Adjusting length"); 0459 return result; 0460 } 0461 0462 int comp_type = quint8(data[offset++]); 0463 int mode = quint8(data[offset++]); 0464 int num_bytes = quint8(data[offset++]); 0465 0466 if ((offset + num_bytes) > size) { 0467 qCInfo(logDvbSi, "Adjusting length"); 0468 return result; 0469 } 0470 0471 const char *comp_string = (data + offset); 0472 0473 if (comp_type == 0x00) { 0474 // Uncompressed 0475 result += interpretTextData(comp_string, 0476 num_bytes, mode); 0477 } else if ((comp_type == 0x01 || comp_type == 0x02) && 0478 mode == 0x00) { 0479 // Huffman Compression 0480 // As per the spec, only mode 0x00 supports Huffman coding 0481 result += 0482 AtscHuffmanString::convertText(comp_string, num_bytes, comp_type); 0483 } else { 0484 qCInfo(logDvbSi, "Unsupported compression / mode %d %d", comp_type, mode); 0485 } 0486 0487 offset += num_bytes; 0488 } 0489 0490 return result; 0491 } 0492 0493 QString AtscHuffmanString::convertText(const char *data_, int length, int table) 0494 { 0495 AtscHuffmanString huffmanstring(data_, length, table); 0496 huffmanstring.decompress(); 0497 return huffmanstring.result; 0498 } 0499 0500 AtscHuffmanString::AtscHuffmanString(const char *data_, int length, int table) : data(data_), 0501 bitsLeft(8 * length) 0502 { 0503 if (table == 1) { 0504 offsets = Huffman1Offsets; 0505 tableBase = Huffman1Tables; 0506 } else { 0507 offsets = Huffman2Offsets; 0508 tableBase = Huffman2Tables; 0509 } 0510 } 0511 0512 AtscHuffmanString::~AtscHuffmanString() { } 0513 0514 bool AtscHuffmanString::hasBits() 0515 { 0516 return bitsLeft > 0; 0517 } 0518 0519 unsigned char AtscHuffmanString::getBit() 0520 { 0521 if (bitsLeft >= 1) { 0522 int shift = (--bitsLeft % 8); 0523 unsigned char value = (data[0] >> shift) & 0x1; 0524 0525 if (shift == 0) { 0526 data++; 0527 } 0528 return value; 0529 } 0530 0531 return 0; 0532 } 0533 0534 unsigned char AtscHuffmanString::getByte() 0535 { 0536 if (bitsLeft >= 8) { 0537 int shift = ((bitsLeft - 1) % 8); 0538 // Note this takes advantage of the fact that there is always 0539 // at least one byte remaining (to avoid a read-past end 0540 // condition) 0541 unsigned char value = ((((data[0] << 8) | quint8(data[1])) >> (shift + 1)) & 0xff); 0542 0543 bitsLeft -= 8; 0544 data++; 0545 return value; 0546 } 0547 0548 return 0; 0549 } 0550 0551 void AtscHuffmanString::decompress() 0552 { 0553 const unsigned char *table = tableBase; 0554 0555 while (hasBits()) { 0556 int index = 0; 0557 0558 do { 0559 index = table[2 * index + getBit()]; 0560 } while (index < 128); 0561 0562 index &= 0x7f; 0563 0564 if (index == 27) { 0565 // escape --> uncompressed character(s) 0566 while (true) { 0567 index = getByte(); 0568 0569 if (index < 128) { 0570 break; 0571 } 0572 0573 result += QChar(index); 0574 } 0575 } 0576 0577 if (index == 0) { 0578 // end 0579 break; 0580 } 0581 0582 result += QChar(index); 0583 table = tableBase + offsets[index]; 0584 } 0585 } 0586 0587 const unsigned short AtscHuffmanString::Huffman1Offsets[128] = { 0588 0x0000, 0x003a, 0x003c, 0x003e, 0x0040, 0x0042, 0x0044, 0x0046, 0589 0x0048, 0x004a, 0x004c, 0x004e, 0x0050, 0x0052, 0x0054, 0x0056, 0590 0x0058, 0x005a, 0x005c, 0x005e, 0x0060, 0x0062, 0x0064, 0x0066, 0591 0x0068, 0x006a, 0x006c, 0x006e, 0x0070, 0x0072, 0x0074, 0x0076, 0592 0x0078, 0x00ce, 0x00d2, 0x00d4, 0x00d6, 0x00d8, 0x00da, 0x00dc, 0593 0x00e6, 0x00e8, 0x00ea, 0x00f0, 0x00f2, 0x00f4, 0x0106, 0x0112, 0594 0x0114, 0x011c, 0x0128, 0x0130, 0x0134, 0x0136, 0x0138, 0x013a, 0595 0x013c, 0x013e, 0x0146, 0x0148, 0x014a, 0x014c, 0x014e, 0x0150, 0596 0x0152, 0x0154, 0x017e, 0x0192, 0x01ac, 0x01ba, 0x01d2, 0x01e4, 0597 0x01fa, 0x0206, 0x021e, 0x0226, 0x0232, 0x023e, 0x0252, 0x0264, 0598 0x027a, 0x0294, 0x0298, 0x02a4, 0x02c8, 0x02de, 0x02e6, 0x02f4, 0599 0x0304, 0x0306, 0x030c, 0x0310, 0x0312, 0x0314, 0x0316, 0x0318, 0600 0x031a, 0x031c, 0x0352, 0x036a, 0x038e, 0x03ae, 0x03ee, 0x0406, 0601 0x0428, 0x0444, 0x0472, 0x0476, 0x0490, 0x04be, 0x04d6, 0x050a, 0602 0x0544, 0x0564, 0x0566, 0x059a, 0x05d0, 0x05fc, 0x0622, 0x062c, 0603 0x0646, 0x0654, 0x067c, 0x068a, 0x068c, 0x068e, 0x0690, 0x0692 }; 0604 0605 const unsigned char AtscHuffmanString::Huffman1Tables[] = { 0606 0x1b, 0x1c, 0xb4, 0xa4, 0xb2, 0xb7, 0xda, 0x01, 0607 0xd1, 0x02, 0x03, 0x9b, 0x04, 0xd5, 0xd9, 0x05, 0608 0xcb, 0xd6, 0x06, 0xcf, 0x07, 0x08, 0xca, 0x09, 0609 0xc9, 0xc5, 0xc6, 0x0a, 0xd2, 0xc4, 0xc7, 0xcc, 0610 0xd0, 0xc8, 0xd7, 0xce, 0x0b, 0xc1, 0x0c, 0xc2, 0611 0xcd, 0xc3, 0x0d, 0x0e, 0x0f, 0x10, 0xd3, 0x11, 0612 0xd4, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0613 0x19, 0x1a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0614 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0615 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0616 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0617 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0618 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0619 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0620 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0621 0x29, 0x2a, 0xd8, 0xe5, 0xb9, 0x01, 0xa7, 0xb1, 0622 0xec, 0xd1, 0x02, 0xad, 0xb2, 0xda, 0xe3, 0xb3, 0623 0x03, 0xe4, 0xe6, 0x04, 0x9b, 0xe2, 0x05, 0x06, 0624 0x07, 0x08, 0x09, 0xd5, 0x0a, 0xd6, 0x0b, 0xd9, 0625 0x0c, 0xa6, 0xe9, 0xcb, 0xc5, 0xcf, 0x0d, 0x0e, 0626 0xca, 0xc9, 0x0f, 0xc7, 0x10, 0x11, 0xe1, 0x12, 0627 0x13, 0xc6, 0xd2, 0xc8, 0xce, 0xc1, 0xc4, 0xd0, 0628 0xcc, 0x14, 0x15, 0xef, 0xc2, 0xd7, 0x16, 0xcd, 0629 0x17, 0xf4, 0xd4, 0x18, 0x19, 0x1a, 0xc3, 0xd3, 0630 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0631 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x01, 0x80, 0632 0xa0, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0xb1, 0x9b, 0633 0x9b, 0x9b, 0x9b, 0xa0, 0x04, 0xf3, 0xe4, 0xb9, 0634 0x01, 0xf4, 0xa0, 0x9b, 0x02, 0x03, 0x9b, 0x9b, 0635 0x9b, 0x9b, 0x01, 0x02, 0x9b, 0xc1, 0xc8, 0xd3, 0636 0x9b, 0x9b, 0x9b, 0xa0, 0x07, 0x08, 0xb1, 0xd2, 0637 0xd3, 0xd4, 0xd5, 0xad, 0xcd, 0xc1, 0x01, 0x02, 0638 0x03, 0xa0, 0x04, 0x9b, 0x05, 0x06, 0xa0, 0x05, 0639 0xc9, 0xd7, 0xd3, 0x01, 0x02, 0x9b, 0xae, 0x80, 0640 0x03, 0x04, 0x9b, 0x9b, 0x02, 0x03, 0xad, 0x9b, 0641 0x01, 0x80, 0xa0, 0xb0, 0x04, 0x05, 0x80, 0x9b, 0642 0xb1, 0xb2, 0xa0, 0xb0, 0xb9, 0x01, 0x02, 0x03, 0643 0x02, 0x03, 0xb1, 0xba, 0x01, 0xb0, 0x9b, 0x80, 0644 0x80, 0x01, 0xb0, 0x9b, 0x9b, 0xb8, 0x9b, 0x9b, 0645 0x9b, 0x9b, 0x9b, 0xb0, 0x9b, 0xa0, 0x02, 0x03, 0646 0xb1, 0xb3, 0xb9, 0xb0, 0x01, 0x9b, 0x9b, 0xa0, 0647 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0648 0x9b, 0x80, 0x9b, 0x9b, 0x13, 0x14, 0xaa, 0xad, 0649 0xae, 0xf6, 0xe7, 0xf4, 0xe2, 0xe9, 0x01, 0x02, 0650 0xc2, 0xf0, 0x9b, 0xf3, 0xe3, 0xe6, 0xf7, 0x03, 0651 0xf5, 0x04, 0x05, 0x06, 0xf2, 0x07, 0x08, 0x09, 0652 0x0a, 0x0b, 0x0c, 0xe4, 0xa0, 0x0d, 0xec, 0xee, 0653 0x0e, 0xed, 0x0f, 0x10, 0x11, 0x12, 0x08, 0x09, 0654 0xc1, 0xd3, 0x9b, 0x01, 0xc3, 0x02, 0xe9, 0xec, 0655 0x03, 0xf2, 0xf5, 0x04, 0xef, 0xe1, 0x05, 0xe5, 0656 0x06, 0x07, 0x0b, 0x0c, 0xc1, 0xf9, 0x01, 0xc2, 0657 0xcf, 0xe5, 0xf5, 0x9b, 0xe9, 0x02, 0xa0, 0x03, 0658 0x04, 0x05, 0xf2, 0x06, 0xec, 0x07, 0xe1, 0x08, 0659 0x09, 0xe8, 0x0a, 0xef, 0x05, 0x06, 0xf9, 0x9b, 0660 0x01, 0xf5, 0x02, 0xf2, 0xe9, 0xe5, 0xef, 0x03, 0661 0xe1, 0x04, 0x0a, 0x0b, 0xf1, 0xf5, 0xf3, 0x01, 0662 0xed, 0xf9, 0xc3, 0x02, 0xec, 0xee, 0xe4, 0xf8, 0663 0x03, 0x9b, 0xf6, 0x04, 0x05, 0xe1, 0x06, 0x07, 0664 0x08, 0x09, 0x07, 0x08, 0xa0, 0x9b, 0xcc, 0x01, 0665 0xe5, 0x02, 0xec, 0xf5, 0xef, 0x03, 0xe9, 0xf2, 0666 0x04, 0x05, 0xe1, 0x06, 0x09, 0x0a, 0xae, 0xec, 0667 0xf9, 0xc1, 0xe8, 0x01, 0x9b, 0x02, 0x03, 0x04, 0668 0xe1, 0xf5, 0xe9, 0x05, 0xe5, 0x06, 0xf2, 0xef, 0669 0x07, 0x08, 0xef, 0x05, 0x80, 0x9b, 0xf5, 0x01, 0670 0x02, 0xe9, 0xe1, 0x03, 0xe5, 0x04, 0xee, 0x0b, 0671 0xba, 0xd4, 0xae, 0xf2, 0xe3, 0x01, 0xa0, 0x02, 0672 0x80, 0x9b, 0xed, 0x03, 0xc9, 0xf3, 0xf4, 0x04, 0673 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x02, 0x03, 0674 0x9b, 0xf5, 0x01, 0xe1, 0xef, 0xe5, 0x05, 0xe9, 0675 0xe1, 0xef, 0xf5, 0xee, 0x9b, 0xe5, 0x01, 0x02, 0676 0x03, 0x04, 0x04, 0x05, 0xa0, 0x9b, 0x01, 0xf5, 0677 0x02, 0xe5, 0xef, 0x03, 0xe1, 0xe9, 0x08, 0x09, 0678 0xaa, 0xd4, 0x01, 0x9b, 0xe3, 0x02, 0xf2, 0x03, 0679 0xe5, 0x04, 0xf5, 0xf9, 0xe9, 0x05, 0xef, 0x06, 0680 0x07, 0xe1, 0xe5, 0x08, 0xce, 0xa0, 0xc6, 0xf5, 0681 0x01, 0x02, 0x9b, 0xc2, 0x03, 0xe1, 0x04, 0xef, 0682 0x05, 0xe9, 0x06, 0x07, 0x09, 0x0a, 0xe4, 0xf3, 0683 0xe6, 0xf6, 0xf7, 0xf0, 0xf2, 0x01, 0xec, 0x02, 0684 0x03, 0xa0, 0x9b, 0x04, 0x05, 0xf5, 0x06, 0x07, 0685 0xee, 0x08, 0x0b, 0x0c, 0xa0, 0xf3, 0xf9, 0xae, 0686 0xd2, 0xc7, 0x01, 0x9b, 0x02, 0xf5, 0x03, 0x04, 0687 0x05, 0xe9, 0xec, 0x06, 0xe5, 0x07, 0xef, 0x08, 0688 0xe1, 0x09, 0xf2, 0x0a, 0x01, 0xf5, 0x9b, 0xd6, 0689 0x04, 0x05, 0xe8, 0x9b, 0x01, 0xf5, 0x02, 0xe1, 0690 0xe9, 0xef, 0x03, 0xe5, 0x10, 0x11, 0xaa, 0xec, 0691 0xf1, 0xae, 0xa0, 0xf7, 0xed, 0xee, 0x01, 0x02, 0692 0x9b, 0xeb, 0x03, 0x04, 0x05, 0x06, 0xe3, 0x07, 0693 0xef, 0x08, 0xe9, 0xf5, 0x09, 0xe1, 0xe5, 0xf0, 0694 0xe8, 0x0a, 0x0b, 0x0c, 0x0d, 0xf4, 0x0e, 0x0f, 0695 0xe8, 0x0a, 0xad, 0xce, 0x9b, 0x01, 0xd6, 0x02, 0696 0xf5, 0xf7, 0x03, 0x04, 0xe1, 0xe5, 0xe9, 0x05, 0697 0xf2, 0x06, 0xef, 0x07, 0x08, 0x09, 0xee, 0x03, 0698 0xec, 0xae, 0x01, 0x9b, 0x02, 0xf0, 0x06, 0xe9, 0699 0xa0, 0xc3, 0xef, 0x9b, 0xe5, 0x01, 0x80, 0x02, 0700 0x03, 0xe1, 0x04, 0x05, 0x06, 0x07, 0xc6, 0xd7, 0701 0x01, 0x9b, 0xf2, 0x02, 0x03, 0xe8, 0xe5, 0xe1, 0702 0x04, 0xe9, 0xef, 0x05, 0x9b, 0x9b, 0x02, 0xef, 0703 0xe1, 0x9b, 0x01, 0xe5, 0x01, 0xef, 0x9b, 0xe1, 0704 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0705 0x9b, 0x9b, 0x9b, 0x9b, 0x19, 0x1a, 0x9b, 0xba, 0706 0xe5, 0xea, 0xf8, 0x01, 0x02, 0xe6, 0xa7, 0x03, 0707 0xfa, 0xe8, 0x04, 0xf7, 0x05, 0xf5, 0xe2, 0x06, 0708 0xeb, 0x07, 0xf0, 0x08, 0x80, 0xf6, 0xe7, 0x09, 0709 0xe4, 0x0a, 0xa0, 0xe9, 0x0b, 0xe3, 0xf9, 0x0c, 0710 0x0d, 0xed, 0x0e, 0x0f, 0xf3, 0x10, 0x11, 0xec, 0711 0x12, 0xf4, 0xf2, 0x13, 0xee, 0x14, 0x15, 0x16, 0712 0x17, 0x18, 0x0a, 0x0b, 0xf3, 0x9b, 0xf5, 0xe2, 0713 0x01, 0x80, 0xa0, 0x02, 0xe5, 0xf2, 0xe9, 0x03, 0714 0xec, 0x04, 0xf9, 0x05, 0xef, 0x06, 0xe1, 0x07, 0715 0x08, 0x09, 0x10, 0x11, 0xc3, 0xcc, 0xc7, 0x9b, 0716 0xe3, 0x01, 0x80, 0xec, 0xf9, 0x02, 0xf3, 0x03, 0717 0xf5, 0x04, 0x05, 0xf2, 0x06, 0xe9, 0xa0, 0x07, 0718 0x08, 0xef, 0xf4, 0x09, 0x0a, 0xe1, 0x0b, 0xe8, 0719 0xeb, 0xe5, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f, 0720 0xae, 0xf5, 0xf7, 0x01, 0xec, 0x02, 0xe4, 0xe7, 0721 0xf2, 0x03, 0x9b, 0xef, 0x04, 0xf6, 0x05, 0x06, 0722 0xf9, 0xf3, 0x07, 0xe9, 0xe1, 0x08, 0x09, 0x80, 0723 0x0a, 0x0b, 0xe5, 0x0c, 0x0d, 0xa0, 0x1e, 0x1f, 0724 0x9b, 0xa1, 0xad, 0xe8, 0xea, 0xf1, 0xf5, 0xfa, 0725 0x01, 0x02, 0x03, 0x04, 0xba, 0xf8, 0xa7, 0xe2, 0726 0xe9, 0x05, 0x06, 0x07, 0xe6, 0xed, 0xe7, 0xeb, 0727 0x08, 0x09, 0xf6, 0xf0, 0x0a, 0xef, 0x0b, 0xe3, 0728 0x0c, 0x0d, 0x0e, 0xf9, 0x0f, 0xe4, 0xec, 0x10, 0729 0xe5, 0x11, 0xf4, 0xf7, 0x12, 0x13, 0xe1, 0x14, 0730 0x15, 0x16, 0xee, 0xf3, 0x17, 0x80, 0x18, 0x19, 0731 0xf2, 0x1a, 0x1b, 0xa0, 0x1c, 0x1d, 0xa0, 0x0b, 0732 0xf5, 0x9b, 0x01, 0xec, 0xf3, 0xf2, 0x80, 0xe1, 0733 0x02, 0x03, 0xf4, 0xe9, 0xef, 0xe6, 0x04, 0x05, 0734 0x06, 0x07, 0xe5, 0x08, 0x09, 0x0a, 0x0f, 0x10, 0735 0xba, 0xf9, 0xa7, 0xf4, 0x9b, 0x01, 0xe7, 0xec, 0736 0x02, 0xee, 0x03, 0xef, 0xf5, 0x04, 0xf2, 0x05, 0737 0x06, 0xe9, 0x07, 0xf3, 0xe1, 0x08, 0x09, 0x0a, 0738 0x0b, 0xe5, 0x80, 0x0c, 0xe8, 0xa0, 0x0d, 0x0e, 0739 0xe5, 0x0d, 0xe2, 0xf5, 0xf7, 0x9b, 0xec, 0x01, 0740 0xf9, 0xee, 0x02, 0x03, 0x04, 0xf2, 0x05, 0x80, 0741 0x06, 0xa0, 0xe1, 0xef, 0x07, 0xf4, 0xe9, 0x08, 0742 0x09, 0x0a, 0x0b, 0x0c, 0x15, 0x16, 0xa1, 0xf8, 0743 0xe9, 0xeb, 0x01, 0x80, 0x9b, 0xfa, 0xe2, 0x02, 0744 0x03, 0x04, 0xa0, 0xf0, 0x05, 0x06, 0x07, 0xe1, 0745 0x08, 0xe6, 0xf2, 0xed, 0xf6, 0x09, 0xe4, 0x0a, 0746 0xef, 0xf4, 0xec, 0xf3, 0xe7, 0xe5, 0x0b, 0xe3, 0747 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0748 0xee, 0x14, 0xef, 0x01, 0x9b, 0xe1, 0x0b, 0x0c, 0749 0xd4, 0xef, 0xe6, 0xec, 0xf7, 0xe1, 0x01, 0xba, 0750 0x02, 0x9b, 0xf9, 0x03, 0x04, 0x05, 0xf3, 0x06, 0751 0x07, 0x08, 0xe9, 0xa0, 0x09, 0x80, 0xe5, 0x0a, 0752 0x15, 0x16, 0xa7, 0xba, 0xe3, 0xf7, 0xf2, 0xad, 0753 0xe2, 0x01, 0x02, 0x9b, 0xe6, 0x03, 0xed, 0xf6, 0754 0x04, 0xeb, 0x05, 0xf4, 0x06, 0x07, 0x08, 0xf3, 0755 0x09, 0xf5, 0x0a, 0xef, 0x0b, 0x0c, 0x80, 0xf9, 0756 0xe1, 0x0d, 0xe4, 0xe9, 0xa0, 0x0e, 0x0f, 0xec, 0757 0xe5, 0x10, 0x11, 0x12, 0x13, 0x14, 0x0a, 0x0b, 0758 0xf9, 0x9b, 0xf5, 0xf3, 0x01, 0x02, 0xe2, 0xed, 0759 0x80, 0x03, 0xf0, 0xef, 0x04, 0xa0, 0x05, 0xe9, 0760 0x06, 0xe1, 0x07, 0x08, 0x09, 0xe5, 0x18, 0x19, 0761 0xe2, 0xea, 0xf2, 0xe8, 0xec, 0xed, 0xfa, 0x9b, 0762 0x01, 0xf5, 0x02, 0x03, 0xf6, 0x04, 0xba, 0xe6, 0763 0x05, 0x06, 0xeb, 0xef, 0x07, 0xa7, 0xf9, 0x08, 0764 0x09, 0x0a, 0x0b, 0xe3, 0x0c, 0xee, 0xe1, 0x0d, 0765 0xf3, 0x0e, 0xe9, 0x0f, 0x10, 0xf4, 0x80, 0xe4, 0766 0xe5, 0x11, 0x12, 0xe7, 0xa0, 0x13, 0x14, 0x15, 0767 0x16, 0x17, 0x1b, 0x1c, 0xae, 0xfa, 0xbf, 0x01, 0768 0xa7, 0x9b, 0x02, 0xe9, 0xf8, 0xf9, 0x03, 0xe5, 0769 0xe8, 0x04, 0xe1, 0xeb, 0x05, 0xe2, 0x06, 0x07, 0770 0xe3, 0x08, 0xe7, 0xf4, 0x09, 0x80, 0xf6, 0xf0, 0771 0x0a, 0xe4, 0x0b, 0xf3, 0xf7, 0x0c, 0x0d, 0xef, 0772 0xec, 0xa0, 0x0e, 0x0f, 0xed, 0xe6, 0x10, 0xf5, 0773 0x11, 0x12, 0x13, 0x14, 0x15, 0xf2, 0x16, 0xee, 0774 0x17, 0x18, 0x19, 0x1a, 0x0e, 0x0f, 0xed, 0xa7, 0775 0x9b, 0xe4, 0x01, 0xf9, 0xf3, 0xf2, 0xf4, 0x02, 0776 0xe8, 0x03, 0xec, 0xf0, 0x04, 0xe1, 0xe9, 0x05, 0777 0x06, 0x80, 0xa0, 0x07, 0x08, 0x09, 0x0a, 0xe5, 0778 0xef, 0x0b, 0x0c, 0x0d, 0x9b, 0xf5, 0x18, 0x19, 0779 0xba, 0xac, 0xf6, 0x9b, 0xf0, 0xe2, 0x01, 0xe6, 0780 0x02, 0xa7, 0xae, 0xe7, 0x03, 0xe3, 0xf5, 0x04, 0781 0xed, 0x05, 0x06, 0x07, 0xeb, 0x08, 0x09, 0xee, 0782 0xf2, 0x0a, 0xe4, 0x0b, 0xf9, 0xec, 0x0c, 0x0d, 0783 0xf4, 0x80, 0x0e, 0xef, 0xf3, 0xa0, 0xe1, 0x0f, 0784 0xe9, 0x10, 0x11, 0xe5, 0x12, 0x13, 0x14, 0x15, 0785 0x16, 0x17, 0x19, 0x1a, 0xa7, 0xac, 0xbf, 0xc3, 0786 0xc8, 0xe4, 0xe6, 0xed, 0xf2, 0xae, 0xec, 0xee, 0787 0xf9, 0x01, 0x02, 0x03, 0x04, 0xba, 0x05, 0x9b, 0788 0xf5, 0x06, 0x07, 0x08, 0x09, 0xeb, 0xf0, 0x0a, 0789 0x0b, 0x0c, 0xe1, 0xe3, 0x0d, 0xe8, 0x0e, 0x0f, 0790 0xef, 0x10, 0x11, 0xf3, 0x12, 0xe9, 0x13, 0xe5, 0791 0x14, 0x15, 0xf4, 0x16, 0x17, 0xa0, 0x18, 0x80, 0792 0x14, 0x15, 0xba, 0xbf, 0xe4, 0xf7, 0x9b, 0xa7, 0793 0x01, 0xee, 0x02, 0x03, 0x04, 0xe3, 0xe2, 0xed, 0794 0x05, 0xf9, 0x06, 0xf4, 0x07, 0xec, 0x08, 0xf5, 0795 0xf2, 0x09, 0xe1, 0xf3, 0x0a, 0xef, 0x0b, 0x0c, 0796 0x0d, 0xe9, 0x80, 0xe5, 0x0e, 0xa0, 0x0f, 0xe8, 0797 0x10, 0x11, 0x12, 0x13, 0x11, 0x12, 0xeb, 0xfa, 0798 0x80, 0xe6, 0x9b, 0x01, 0xa0, 0x02, 0x03, 0xe9, 0799 0xe1, 0x04, 0xe4, 0xf0, 0xed, 0xe2, 0xe3, 0xe7, 0800 0xec, 0x05, 0xe5, 0x06, 0x07, 0x08, 0x09, 0xf4, 0801 0x0a, 0x0b, 0x0c, 0xf3, 0xee, 0x0d, 0x0e, 0xf2, 0802 0x0f, 0x10, 0x04, 0xe5, 0xf3, 0xef, 0x9b, 0x01, 0803 0xe1, 0x02, 0x03, 0xe9, 0x0b, 0x0c, 0xa7, 0xe2, 0804 0xec, 0xe3, 0xf2, 0x01, 0x9b, 0x02, 0x03, 0x04, 0805 0xe9, 0xef, 0xee, 0xe5, 0xe1, 0x80, 0x05, 0xa0, 0806 0x06, 0x07, 0x08, 0x09, 0xf3, 0x0a, 0x05, 0x06, 0807 0x9b, 0xa0, 0xe1, 0xe5, 0xe9, 0x01, 0x80, 0xf0, 0808 0x02, 0xf4, 0x03, 0x04, 0xa0, 0x13, 0xe3, 0xad, 0809 0xe4, 0xe9, 0xee, 0xef, 0xf0, 0xf4, 0xf6, 0xa1, 0810 0xe1, 0xed, 0x01, 0xe2, 0x02, 0x03, 0x04, 0xa7, 0811 0x05, 0x06, 0xf7, 0x07, 0x9b, 0xec, 0x08, 0xe5, 0812 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xf3, 0x0f, 0813 0x10, 0x11, 0x80, 0x12, 0x05, 0x06, 0xe5, 0xfa, 0814 0xa0, 0xf9, 0x9b, 0x01, 0x80, 0xe9, 0x02, 0xe1, 0815 0x03, 0x04, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0816 0x9b, 0x9b, 0x9b, 0x9b }; 0817 0818 const unsigned short AtscHuffmanString::Huffman2Offsets[128] = { 0819 0x0000, 0x002c, 0x002e, 0x0030, 0x0032, 0x0034, 0x0036, 0x0038, 0820 0x003a, 0x003c, 0x003e, 0x0040, 0x0042, 0x0044, 0x0046, 0x0048, 0821 0x004a, 0x004c, 0x004e, 0x0050, 0x0052, 0x0054, 0x0056, 0x0058, 0822 0x005a, 0x005c, 0x005e, 0x0060, 0x0062, 0x0064, 0x0066, 0x0068, 0823 0x006a, 0x00de, 0x00e0, 0x00ea, 0x00ec, 0x00ee, 0x00f0, 0x00f2, 0824 0x00f8, 0x00fa, 0x00fc, 0x00fe, 0x0100, 0x0104, 0x0116, 0x0120, 0825 0x0122, 0x012c, 0x0132, 0x0138, 0x013c, 0x0140, 0x0144, 0x0146, 0826 0x014a, 0x014c, 0x0154, 0x0156, 0x0158, 0x015a, 0x015c, 0x015e, 0827 0x0160, 0x0162, 0x0176, 0x0184, 0x0194, 0x01a2, 0x01b2, 0x01ba, 0828 0x01c8, 0x01d2, 0x01de, 0x01ea, 0x01f2, 0x01fc, 0x0208, 0x0210, 0829 0x021a, 0x0228, 0x022a, 0x0234, 0x024a, 0x025a, 0x025e, 0x0264, 0830 0x026e, 0x0270, 0x0272, 0x0274, 0x0276, 0x0278, 0x027a, 0x027c, 0831 0x027e, 0x0280, 0x02b4, 0x02ce, 0x02f0, 0x031a, 0x0358, 0x036e, 0832 0x038e, 0x03ac, 0x03d8, 0x03e0, 0x03f4, 0x0424, 0x0440, 0x0476, 0833 0x04ae, 0x04ce, 0x04d0, 0x0506, 0x0534, 0x0560, 0x0586, 0x0592, 0834 0x05aa, 0x05b8, 0x05dc, 0x05ec, 0x05ee, 0x05f0, 0x05f2, 0x05f4 }; 0835 0836 const unsigned char AtscHuffmanString::Huffman2Tables[] = { 0837 0x14, 0x15, 0x9b, 0xd6, 0xc9, 0xcf, 0xd7, 0xc7, 0838 0x01, 0xa2, 0xce, 0xcb, 0x02, 0x03, 0xc5, 0xcc, 0839 0xc6, 0xc8, 0x04, 0xc4, 0x05, 0xc2, 0x06, 0xc3, 0840 0xd2, 0x07, 0xd3, 0x08, 0xca, 0xd4, 0x09, 0xcd, 0841 0xd0, 0x0a, 0xc1, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0842 0x10, 0x11, 0x12, 0x13, 0x9b, 0x9b, 0x9b, 0x9b, 0843 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0844 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0845 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0846 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0847 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0848 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0849 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0850 0x9b, 0x9b, 0x38, 0x39, 0xad, 0xaf, 0xb7, 0xda, 0851 0xa8, 0xb3, 0xb5, 0x01, 0x02, 0x9b, 0xb4, 0xf1, 0852 0xa2, 0xd5, 0xd6, 0xd9, 0x03, 0x04, 0x05, 0xcf, 0853 0x06, 0xc9, 0xf9, 0xea, 0xeb, 0xf5, 0xf6, 0x07, 0854 0x08, 0x09, 0xb2, 0xc5, 0xc6, 0xb1, 0x0a, 0xee, 0855 0xcb, 0x0b, 0xd4, 0x0c, 0xc4, 0xc8, 0xd2, 0x0d, 0856 0x0e, 0x0f, 0xc7, 0xca, 0xce, 0xd0, 0xd7, 0x10, 0857 0xc2, 0x11, 0xcc, 0xec, 0xe5, 0xe7, 0x12, 0xcd, 0858 0x13, 0x14, 0xc3, 0x15, 0x16, 0x17, 0xed, 0x18, 0859 0x19, 0xf2, 0x1a, 0xd3, 0x1b, 0x1c, 0xe4, 0x1d, 0860 0xc1, 0xe3, 0x1e, 0xe9, 0xf0, 0xe2, 0xf7, 0x1f, 0861 0xf3, 0xe6, 0x20, 0x21, 0x22, 0xe8, 0xef, 0x23, 0862 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xf4, 0863 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0xe1, 0x30, 0x31, 0864 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x9b, 0x9b, 0865 0x03, 0x04, 0x80, 0xae, 0xc8, 0xd4, 0x01, 0x02, 0866 0x9b, 0xa0, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0867 0x9b, 0x9b, 0x02, 0xf3, 0xa0, 0xf4, 0x9b, 0x01, 0868 0x9b, 0x9b, 0xac, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0869 0x01, 0xa0, 0x9b, 0xa2, 0x07, 0x08, 0xe2, 0xe4, 0870 0xe5, 0xe6, 0xa0, 0xf2, 0xe1, 0x01, 0x02, 0xf3, 0871 0xe3, 0x03, 0x04, 0x05, 0x9b, 0x06, 0x04, 0x80, 0872 0xca, 0xd3, 0xa2, 0x01, 0x9b, 0x02, 0x03, 0xa0, 0873 0x9b, 0xa0, 0x03, 0x04, 0x9b, 0xb7, 0xf4, 0xa0, 0874 0xb0, 0xf3, 0x01, 0x02, 0xb9, 0x02, 0xb8, 0x9b, 0875 0xa0, 0x01, 0xae, 0x02, 0xb6, 0x9b, 0x01, 0xa0, 0876 0xa0, 0x01, 0x9b, 0xb0, 0xae, 0x01, 0x9b, 0xa0, 0877 0xae, 0x01, 0xa0, 0x9b, 0x9b, 0x9b, 0x9b, 0x01, 0878 0xac, 0xae, 0x9b, 0x9b, 0x02, 0x03, 0x9b, 0xa0, 0879 0xb5, 0xb6, 0xb8, 0x01, 0x9b, 0xa0, 0x9b, 0xa0, 0880 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0xa0, 0881 0x9b, 0x9b, 0x08, 0x09, 0xe6, 0xf5, 0xf3, 0xf4, 0882 0x9b, 0xe4, 0x01, 0xed, 0x02, 0x03, 0x04, 0xf2, 0883 0x05, 0x06, 0xec, 0xee, 0x07, 0xa0, 0x05, 0x06, 0884 0x9b, 0xec, 0xf5, 0x01, 0x02, 0xe1, 0xef, 0xe5, 0885 0xe9, 0xf2, 0x03, 0x04, 0x06, 0x07, 0x9b, 0xe9, 0886 0xf9, 0xf2, 0xf5, 0x01, 0x02, 0x03, 0xec, 0xef, 0887 0xe1, 0x04, 0xe8, 0x05, 0x05, 0x06, 0xf9, 0xf2, 0888 0xf5, 0x9b, 0xe5, 0xef, 0x01, 0x02, 0xe9, 0xe1, 0889 0x03, 0x04, 0x06, 0x07, 0xe1, 0xe9, 0xee, 0xf6, 0890 0xe4, 0xec, 0xf3, 0x01, 0x02, 0xf2, 0x03, 0x04, 0891 0x9b, 0x05, 0x02, 0x03, 0xe5, 0xec, 0x9b, 0xef, 0892 0x01, 0xf2, 0x05, 0x06, 0xf5, 0xef, 0x9b, 0xec, 0893 0xe9, 0x01, 0xe1, 0xf2, 0x02, 0xe5, 0x03, 0x04, 0894 0x03, 0x04, 0x9b, 0xe5, 0xe9, 0xf5, 0xe1, 0x01, 0895 0xef, 0x02, 0x04, 0x05, 0xa0, 0xc9, 0xf3, 0x9b, 0896 0xae, 0xf2, 0x01, 0x02, 0x03, 0xee, 0xef, 0x05, 0897 0x9b, 0xae, 0xe9, 0xe5, 0x01, 0xf5, 0x02, 0xe1, 0898 0x03, 0x04, 0xe5, 0x03, 0xe1, 0xe9, 0xf2, 0x9b, 0899 0x01, 0x02, 0x03, 0x04, 0x9b, 0xe9, 0xf5, 0x01, 0900 0xe5, 0x02, 0xef, 0xe1, 0xe1, 0x05, 0x9b, 0xe3, 0901 0xef, 0x01, 0xf5, 0xe5, 0x02, 0x03, 0xe9, 0x04, 0902 0xe5, 0x03, 0x9b, 0xe9, 0x01, 0xe1, 0xef, 0x02, 0903 0x03, 0x04, 0xa7, 0xee, 0xec, 0xf2, 0xf3, 0x01, 0904 0x9b, 0x02, 0xe1, 0x06, 0x9b, 0xe8, 0xe9, 0x01, 0905 0xf2, 0xec, 0x02, 0xef, 0x03, 0xe5, 0x04, 0x05, 0906 0x9b, 0x9b, 0x03, 0x04, 0x9b, 0xae, 0x01, 0xe9, 0907 0x02, 0xe1, 0xe5, 0xef, 0x09, 0x0a, 0xf6, 0xf9, 0908 0x01, 0xae, 0xe3, 0xe9, 0xf5, 0x9b, 0xe5, 0xef, 0909 0x02, 0x03, 0xe1, 0x04, 0xe8, 0x05, 0x06, 0xf4, 0910 0x07, 0x08, 0xe8, 0x07, 0xe5, 0xf7, 0xd6, 0xe1, 0911 0x9b, 0xe9, 0xf2, 0x01, 0x02, 0x03, 0x04, 0xef, 0912 0x05, 0x06, 0xae, 0x01, 0x9b, 0xee, 0xe9, 0x02, 0913 0xe5, 0x9b, 0xa0, 0x01, 0x03, 0x04, 0x9b, 0xe8, 0914 0xe5, 0xe1, 0xef, 0x01, 0xe9, 0x02, 0x9b, 0x9b, 0915 0x9b, 0xef, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0916 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0917 0x18, 0x19, 0xe8, 0xef, 0xf8, 0x9b, 0xa7, 0xf7, 0918 0xfa, 0x01, 0x02, 0x03, 0x04, 0xe5, 0xae, 0x05, 0919 0xe6, 0xe2, 0x06, 0xf6, 0xeb, 0xf5, 0xe9, 0x07, 0920 0xf0, 0xf9, 0xe7, 0x08, 0x09, 0xe4, 0x0a, 0xe3, 0921 0x0b, 0xed, 0x0c, 0xf3, 0x0d, 0x0e, 0x0f, 0xec, 0922 0x10, 0xf4, 0x11, 0x12, 0xf2, 0xa0, 0x13, 0x14, 0923 0x15, 0xee, 0x16, 0x17, 0x0b, 0x0c, 0xe4, 0xf3, 0924 0x9b, 0xae, 0xe2, 0x01, 0x02, 0x03, 0xec, 0xa0, 0925 0x04, 0xe9, 0xf2, 0xf5, 0x05, 0xf9, 0xe1, 0x06, 0926 0xef, 0x07, 0xe5, 0x08, 0x09, 0x0a, 0x0f, 0x10, 0927 0xf1, 0xae, 0xc4, 0xf9, 0xac, 0x01, 0xe3, 0x02, 0928 0x9b, 0xf2, 0x03, 0x04, 0xa0, 0xec, 0xf5, 0x05, 0929 0x06, 0xe9, 0x07, 0xeb, 0x08, 0xf4, 0x09, 0xe5, 0930 0x0a, 0xef, 0xe1, 0xe8, 0x0b, 0x0c, 0x0d, 0x0e, 0931 0x13, 0x14, 0xa7, 0xbb, 0xe6, 0xed, 0xf7, 0xe7, 0932 0xf6, 0x01, 0x02, 0x9b, 0xee, 0x03, 0x04, 0xec, 0933 0x05, 0xf5, 0x06, 0xac, 0xe4, 0xf9, 0xf2, 0x07, 0934 0x08, 0x09, 0xae, 0x0a, 0xef, 0x0b, 0xe1, 0xf3, 0935 0x0c, 0xe9, 0x0d, 0x0e, 0x0f, 0x10, 0xe5, 0x11, 0936 0x12, 0xa0, 0x1d, 0x1e, 0xa9, 0xe8, 0xf5, 0x9b, 0937 0x01, 0xad, 0xbb, 0xeb, 0xfa, 0x02, 0xa7, 0xe6, 0938 0xe2, 0xe7, 0x03, 0x04, 0x05, 0x06, 0xe9, 0xf8, 0939 0x07, 0xac, 0xef, 0xf0, 0x08, 0xed, 0xf6, 0xf9, 0940 0x09, 0xf7, 0x0a, 0x0b, 0xae, 0x0c, 0xe3, 0x0d, 0941 0xe5, 0xf4, 0x0e, 0x0f, 0xe4, 0x10, 0xec, 0x11, 0942 0xe1, 0x12, 0x13, 0x14, 0x15, 0x16, 0xee, 0xf3, 0943 0x17, 0x18, 0xf2, 0xa0, 0x19, 0x1a, 0x1b, 0x1c, 0944 0x09, 0x0a, 0xae, 0x9b, 0xec, 0x01, 0xf5, 0x02, 0945 0xf4, 0xe6, 0x03, 0xe1, 0xe5, 0xe9, 0x04, 0xf2, 0946 0xef, 0x05, 0x06, 0x07, 0xa0, 0x08, 0x0e, 0x0f, 0947 0xad, 0xe7, 0x9b, 0xa7, 0xf9, 0x01, 0xec, 0x02, 0948 0xac, 0xf2, 0x03, 0xae, 0xf3, 0xf5, 0x04, 0x05, 0949 0xef, 0x06, 0x07, 0xe9, 0xe1, 0x08, 0x09, 0xe8, 0950 0x0a, 0x0b, 0xe5, 0x0c, 0xa0, 0x0d, 0x0d, 0x0e, 0951 0xa7, 0xac, 0xf3, 0xad, 0x01, 0x02, 0x9b, 0xf9, 0952 0xf5, 0xae, 0x03, 0xee, 0x04, 0xf2, 0x05, 0x06, 0953 0xf4, 0x07, 0x08, 0x09, 0xef, 0xe1, 0xa0, 0x0a, 0954 0xe9, 0x0b, 0x0c, 0xe5, 0x14, 0x15, 0xac, 0xe2, 0955 0xf8, 0x9b, 0xae, 0xfa, 0x01, 0xeb, 0x02, 0xa0, 0956 0x03, 0x04, 0xf0, 0x05, 0x06, 0xe6, 0xf6, 0x07, 0957 0xe4, 0xed, 0xe7, 0x08, 0xe1, 0xef, 0xf2, 0x09, 0958 0x0a, 0x0b, 0xec, 0x0c, 0xe5, 0xe3, 0x0d, 0xf4, 0959 0x0e, 0xf3, 0x0f, 0x10, 0x11, 0xee, 0x12, 0x13, 0960 0x03, 0xef, 0x9b, 0xe1, 0xe5, 0xf5, 0x01, 0x02, 0961 0x08, 0x09, 0xec, 0xf9, 0xa7, 0xee, 0x01, 0xac, 0962 0x9b, 0xae, 0x02, 0x03, 0x04, 0xf3, 0x05, 0xe9, 0963 0x06, 0xa0, 0x07, 0xe5, 0x16, 0x17, 0xa7, 0xad, 0964 0xee, 0xe3, 0xeb, 0xf2, 0x9b, 0xe2, 0x01, 0x02, 0965 0xf5, 0x03, 0xf4, 0xac, 0x04, 0x05, 0xe6, 0xed, 0966 0xf6, 0x06, 0xae, 0xf0, 0x07, 0x08, 0xf3, 0x09, 0967 0x0a, 0xe4, 0x0b, 0x0c, 0xf9, 0x0d, 0xef, 0x0e, 0968 0xe1, 0x0f, 0x10, 0xe9, 0xec, 0x11, 0xa0, 0xe5, 0969 0x12, 0x13, 0x14, 0x15, 0x0c, 0x0d, 0xa7, 0xbb, 0970 0x9b, 0x01, 0xf9, 0xae, 0xe2, 0x02, 0xed, 0xf3, 0971 0x03, 0xf5, 0xef, 0xf0, 0x04, 0x05, 0xe9, 0x06, 0972 0x07, 0x08, 0x09, 0xa0, 0xe1, 0xe5, 0x0a, 0x0b, 0973 0x19, 0x1a, 0xad, 0xbb, 0xe2, 0xea, 0xed, 0xf2, 0974 0xfa, 0xe6, 0xec, 0x01, 0x02, 0x03, 0x9b, 0xf5, 0975 0x04, 0xa7, 0xf6, 0xf9, 0x05, 0x06, 0xeb, 0xef, 0976 0x07, 0x08, 0x09, 0x0a, 0xac, 0x0b, 0x0c, 0xe3, 0977 0xae, 0x0d, 0xee, 0xe9, 0x0e, 0xe1, 0x0f, 0xf3, 0978 0x10, 0x11, 0xf4, 0x12, 0xe7, 0xe5, 0x13, 0x14, 0979 0xe4, 0x15, 0x16, 0x17, 0xa0, 0x18, 0x1a, 0x1b, 0980 0xc2, 0x9b, 0xad, 0xac, 0xf8, 0x01, 0xae, 0x02, 0981 0x03, 0xe5, 0xe7, 0xe8, 0xf9, 0xe9, 0xeb, 0x04, 0982 0xe3, 0xe1, 0x05, 0xf6, 0x06, 0xe4, 0x07, 0xe2, 0983 0xf0, 0x08, 0x09, 0xf3, 0xf4, 0xf7, 0xef, 0x0a, 0984 0x0b, 0x0c, 0x0d, 0xec, 0x0e, 0x0f, 0x10, 0xf5, 0985 0xed, 0x11, 0xe6, 0xa0, 0x12, 0xf2, 0x13, 0x14, 0986 0x15, 0xee, 0x16, 0x17, 0x18, 0x19, 0x0e, 0x0f, 0987 0xad, 0xed, 0xf9, 0x9b, 0xae, 0x01, 0xf3, 0x02, 0988 0x03, 0xf5, 0xf4, 0xf0, 0x04, 0xef, 0x05, 0xe9, 0989 0x06, 0xe8, 0xa0, 0xe1, 0xec, 0x07, 0xf2, 0x08, 0990 0xe5, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x9b, 0xf5, 0991 0x19, 0x1a, 0xa9, 0xbb, 0xf6, 0xe6, 0x01, 0x9b, 0992 0xad, 0xe2, 0xf0, 0x02, 0xa7, 0x03, 0x04, 0x05, 0993 0xf5, 0xe3, 0xac, 0xe7, 0xf2, 0x06, 0xeb, 0x07, 0994 0xec, 0xed, 0xee, 0xf9, 0x08, 0xae, 0x09, 0x0a, 0995 0xe4, 0x0b, 0x0c, 0xf4, 0x0d, 0xf3, 0x0e, 0x0f, 0996 0x10, 0xe1, 0xef, 0x11, 0xe9, 0x12, 0x13, 0xe5, 0997 0x14, 0xa0, 0x15, 0x16, 0x17, 0x18, 0xa0, 0x16, 0998 0xa2, 0xa7, 0xe2, 0xeb, 0xed, 0xee, 0x9b, 0xf7, 0999 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 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 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 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 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 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 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 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 QString fourcc; 1163 bool teletextPresent = false; 1164 bool audioPresent = false; 1165 bool videoPresent = false; 1166 1167 for (DvbDescriptor descriptor = entry.descriptors(); descriptor.isValid(); 1168 descriptor.advance()) { 1169 switch (descriptor.descriptorTag()) { 1170 case 0x05: { 1171 DvbRegistrationDescriptor registrationDescriptor(descriptor); 1172 fourcc.clear(); 1173 fourcc.append(QChar(registrationDescriptor.formatIdentifier0())); 1174 fourcc.append(QChar(registrationDescriptor.formatIdentifier1())); 1175 fourcc.append(QChar(registrationDescriptor.formatIdentifier2())); 1176 fourcc.append(QChar(registrationDescriptor.formatIdentifier3())); 1177 1178 /* Handle audio and video fourcc's */ 1179 if (entry.streamType() == 0x06 && 1180 (fourcc == "EAC3" || 1181 fourcc == "AC-3" || 1182 fourcc == "DTS1" || 1183 fourcc == "DTS2" || 1184 fourcc == "DTS3" || 1185 fourcc == "BSSD")) 1186 audioPresent = true; 1187 else if ((entry.streamType() == 0x06 && fourcc == "HEVC") || 1188 (entry.streamType() == 0xea && fourcc == "VC-1")) 1189 videoPresent = true; 1190 break; 1191 } 1192 1193 case 0x0a: { 1194 DvbLanguageDescriptor languageDescriptor(descriptor); 1195 1196 if (!languageDescriptor.isValid()) { 1197 break; 1198 } 1199 1200 // ISO 8859-1 equals to unicode range 0x0000 - 0x00ff 1201 streamLanguage.clear(); 1202 streamLanguage.append(QChar(languageDescriptor.languageCode1())); 1203 streamLanguage.append(QChar(languageDescriptor.languageCode2())); 1204 streamLanguage.append(QChar(languageDescriptor.languageCode3())); 1205 break; 1206 } 1207 1208 case 0x56: 1209 teletextPresent = true; 1210 break; 1211 1212 case 0x59: { 1213 DvbSubtitleDescriptor subtitleDescriptor(descriptor); 1214 1215 if (!subtitleDescriptor.isValid()) { 1216 break; 1217 } 1218 1219 if ((subtitleDescriptor.subtitleType() >= 0x01) && 1220 (subtitleDescriptor.subtitleType() <= 0x03)) { 1221 // FIXME how to deal with vbi and teletext subtitles? 1222 qCInfo(logDvbSi, "Unsupported subtitle found: VBI/teletext (%d)", subtitleDescriptor.subtitleType()); 1223 } 1224 1225 // ISO 8859-1 equals to unicode range 0x0000 - 0x00ff 1226 subtitleLanguage.clear(); 1227 subtitleLanguage.append(QChar(subtitleDescriptor.languageCode1())); 1228 subtitleLanguage.append(QChar(subtitleDescriptor.languageCode2())); 1229 subtitleLanguage.append(QChar(subtitleDescriptor.languageCode3())); 1230 break; 1231 } 1232 1233 case 0x6a: 1234 case 0x7a: 1235 audioPresent = true; 1236 break; 1237 } 1238 } 1239 1240 /* 1241 * The code above already checks for streamType. So, 1242 * once we add a video channel here, just rely on it, 1243 * without parsing the streamType() again. 1244 */ 1245 if (videoPresent) { 1246 if (videoPid < 0) { 1247 videoPid = entry.pid(); 1248 } else { 1249 qCInfo(logDvbSi, "More than one video PID"); 1250 } 1251 continue; 1252 } 1253 1254 // Updated with Table 2-34 of ISO/IEC 13818-1:2018 / ITU-T H.222.0 2017 1255 // and with https://www.wikiwand.com/en/Program-specific_information 1256 // (as private IDs are not at ITU/ISO/IEC specs 1257 1258 switch (entry.streamType()) { 1259 case 0x01: // ISO/IEC 11172-2 (MPEG-1) video 1260 case 0x02: // ITU-T H.262 (MPEG2) video or ISO/IEC 11172-2 1261 case 0x10: // ISO/IEC 14496-2 (MPEG-4) video 1262 case 0x1b: // ITU-T H.264 video 1263 case 0x1e: // ISO/IEC 23002-3 (MPEG-4 auxiliary video) 1264 case 0x1f: // ITU-T H.264 Annex G (MPEG-4 SVC sub-bitstream on AVC) 1265 case 0x20: // ITU-T H.264 Annex H (MPEG-4 MVC sub-bitstream on AVC) 1266 case 0x21: // ITU-T T.800 (JPEG 2000 video) 1267 case 0x22: // ITU-T H.262 additional view for 3D 1268 case 0x23: // ITU-T H.264 additional view for 3D 1269 case 0x24: // ITU-T H.265 or HEVC sub-bitstream 1270 case 0x25: // ITU-T H.265 Annex A - HEVC video stream or subset 1271 case 0x26: // ITU-T H.264 Annex I - MVCD substream on HEVC 1272 case 0x28: // ITU-T H.265 Annex G - HEVC enhancemeng sub-partition 1273 case 0x29: // ITU-T H.265 Annex G - HEVC temporal enhancement 1274 case 0x2a: // ITU-T H.265 Annex H - HEVC enhancement 1275 case 0x2b: // ITU-T H.265 Annex H - HEVC temporal enhancement 1276 case 0x42: // CAVS video 1277 // User-private video streams 1278 case 0x80: // MPEG-2 MOTO video 1279 case 0xd1: // Dirac (Ultra HD video) 1280 if (videoPid < 0) { 1281 videoPid = entry.pid(); 1282 } else { 1283 qCInfo(logDvbSi, "More than one video PID"); 1284 } 1285 1286 break; 1287 1288 case 0x03: // ISO/IEC 11172-3 (MPEG1) audio 1289 case 0x04: // ISO/IEC 13818-3 (MPEG2) audio 1290 case 0x07: // ISO/IEC 13522 MHEG - DTS and DTS-HD Audio 1291 case 0x0f: // ISO/IEC 13818-7 Audio with ADTS transport syntax 1292 case 0x11: // ISO/IEC 14496-3 Audio (AAC / LATM) 1293 case 0x1c: // ISO/IEC 14496-3 Audio, without additional transport syntax 1294 case 0x2d: // ISO/IEC 23008-3 Audio with MHAS – main stream 1295 case 0x2e: // ISO/IEC 23008-3 Audio with MHAS – auxiliary stream 1296 // User-private audio streams 1297 case 0x81: // AC-3 audio (ATSC specific) 1298 case 0x83: // TrueHD lossless audio 1299 case 0x84: // SDDS 1300 case 0x85: // DTS on HDMV 1301 case 0x86: // DTS 8 channel 1302 case 0x87: // enhanced AC-3 audio (ATSC specific) 1303 case 0x8a: // DTS 1304 case 0x91: // A52 VLS 1305 case 0x94: // SDDS 1306 audioPids.append(qMakePair(entry.pid(), streamLanguage)); 1307 break; 1308 1309 case 0x06: // private data - can be teletext, subtitle, ac3 or something else 1310 if (teletextPresent) { 1311 if (teletextPid < 0) { 1312 teletextPid = entry.pid(); 1313 } else { 1314 qCInfo(logDvbSi, "More than one teletext PID"); 1315 } 1316 } 1317 1318 if (!subtitleLanguage.isEmpty()) { 1319 subtitlePids.append(qMakePair(entry.pid(), subtitleLanguage)); 1320 1321 if (teletextPresent) { 1322 qCInfo(logDvbSi, "Subtitle and teletext on the same PID"); 1323 } 1324 } 1325 1326 if (audioPresent) { 1327 audioPids.append(qMakePair(entry.pid(), streamLanguage)); 1328 } 1329 1330 break; 1331 1332 default: 1333 if (!subtitleLanguage.isEmpty()) { 1334 qCInfo(logDvbSi, "Subtitle with unexpected stream type found"); 1335 } 1336 1337 if (teletextPresent) { 1338 qCInfo(logDvbSi, "Teletext with unexpected stream type found"); 1339 } 1340 1341 break; 1342 } 1343 } 1344 } 1345 1346 void AtscEitSectionEntry::initEitSectionEntry(const char *data, int size) 1347 { 1348 if (size < 12) { 1349 if (size != 0) { 1350 qCInfo(logDvbSi, "Invalid entry"); 1351 } 1352 1353 initSectionData(); 1354 return; 1355 } 1356 1357 titleLength = quint8(data[9]); 1358 1359 if (titleLength > (size - 12)) { 1360 qCInfo(logDvbSi, "Adjusting length"); 1361 titleLength = (size - 12); 1362 } 1363 1364 // too ugly to be automatically generated 1365 int entryLength = ((((quint8(data[10 + titleLength]) & 0xf) << 8) | 1366 quint8(data[11 + titleLength])) + 12 + titleLength); 1367 1368 if (entryLength > size) { 1369 qCInfo(logDvbSi, "Adjusting length"); 1370 entryLength = size; 1371 } 1372 1373 initSectionData(data, entryLength, size); 1374 } 1375 1376 // everything below this line is automatically generated 1377 1378 void DvbPatSectionEntry::initPatSectionEntry(const char *data, int size) 1379 { 1380 if (size < 4) { 1381 if (size != 0) { 1382 qCWarning(logDvbSi, "Invalid entry at descriptor"); 1383 } 1384 1385 initSectionData(); 1386 return; 1387 } 1388 1389 initSectionData(data, 4, size); 1390 } 1391 1392 void DvbPmtSectionEntry::initPmtSectionEntry(const char *data, int size) 1393 { 1394 if (size < 5) { 1395 if (size != 0) { 1396 qCWarning(logDvbSi, "Invalid entry at descriptor"); 1397 } 1398 1399 initSectionData(); 1400 return; 1401 } 1402 1403 int entryLength = ((((quint8(data[3]) & 0xf) << 8) | quint8(data[4])) + 5); 1404 1405 if (entryLength > size) { 1406 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1407 entryLength = size; 1408 } 1409 1410 initSectionData(data, entryLength, size); 1411 } 1412 1413 void DvbSdtSectionEntry::initSdtSectionEntry(const char *data, int size) 1414 { 1415 if (size < 5) { 1416 if (size != 0) { 1417 qCWarning(logDvbSi, "Invalid entry at descriptor"); 1418 } 1419 1420 initSectionData(); 1421 return; 1422 } 1423 1424 int entryLength = ((((quint8(data[3]) & 0xf) << 8) | quint8(data[4])) + 5); 1425 1426 if (entryLength > size) { 1427 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1428 entryLength = size; 1429 } 1430 1431 initSectionData(data, entryLength, size); 1432 } 1433 1434 void DvbEitSectionEntry::initEitSectionEntry(const char *data, int size) 1435 { 1436 if (size < 12) { 1437 if (size != 0) { 1438 qCWarning(logDvbSi, "Invalid entry at descriptor"); 1439 } 1440 1441 initSectionData(); 1442 return; 1443 } 1444 1445 int entryLength = ((((quint8(data[10]) & 0xf) << 8) | quint8(data[11])) + 12); 1446 1447 if (entryLength > size) { 1448 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1449 entryLength = size; 1450 } 1451 1452 initSectionData(data, entryLength, size); 1453 } 1454 1455 void DvbEitContentEntry::initEitContentEntry(const char *data, int size) 1456 { 1457 if (size < 2) { 1458 if (size != 0) { 1459 qCWarning(logDvbSi, "Invalid entry at descriptor"); 1460 } 1461 1462 initSectionData(); 1463 return; 1464 } 1465 1466 initSectionData(data, 2, size); 1467 } 1468 1469 void DvbParentalRatingEntry::initParentalRatingEntry(const char *data, int size) 1470 { 1471 if (size < 4) { 1472 if (size != 0) { 1473 qCWarning(logDvbSi, "Invalid entry at descriptor"); 1474 } 1475 1476 initSectionData(); 1477 return; 1478 } 1479 1480 initSectionData(data, 4, size); 1481 } 1482 1483 void DvbNitSectionEntry::initNitSectionEntry(const char *data, int size) 1484 { 1485 if (size < 6) { 1486 if (size != 0) { 1487 qCWarning(logDvbSi, "Invalid entry at descriptor"); 1488 } 1489 1490 initSectionData(); 1491 return; 1492 } 1493 1494 int entryLength = ((((quint8(data[4]) & 0xf) << 8) | quint8(data[5])) + 6); 1495 1496 if (entryLength > size) { 1497 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1498 entryLength = size; 1499 } 1500 1501 initSectionData(data, entryLength, size); 1502 } 1503 1504 void AtscMgtSectionEntry::initMgtSectionEntry(const char *data, int size) 1505 { 1506 if (size < 11) { 1507 if (size != 0) { 1508 qCWarning(logDvbSi, "Invalid entry at descriptor"); 1509 } 1510 1511 initSectionData(); 1512 return; 1513 } 1514 1515 int entryLength = ((((quint8(data[9]) & 0xf) << 8) | quint8(data[10])) + 11); 1516 1517 if (entryLength > size) { 1518 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1519 entryLength = size; 1520 } 1521 1522 initSectionData(data, entryLength, size); 1523 } 1524 1525 void AtscVctSectionEntry::initVctSectionEntry(const char *data, int size) 1526 { 1527 if (size < 32) { 1528 if (size != 0) { 1529 qCWarning(logDvbSi, "Invalid entry at descriptor"); 1530 } 1531 1532 initSectionData(); 1533 return; 1534 } 1535 1536 int entryLength = ((((quint8(data[30]) & 0x3) << 8) | quint8(data[31])) + 32); 1537 1538 if (entryLength > size) { 1539 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1540 entryLength = size; 1541 } 1542 1543 initSectionData(data, entryLength, size); 1544 } 1545 1546 DvbRegistrationDescriptor::DvbRegistrationDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor) 1547 { 1548 if (getLength() < 6) { 1549 qCWarning(logDvbSi, "Invalid descriptor"); 1550 initSectionData(); 1551 return; 1552 } 1553 } 1554 1555 DvbLanguageDescriptor::DvbLanguageDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor) 1556 { 1557 if (getLength() < 6) { 1558 qCWarning(logDvbSi, "Invalid descriptor"); 1559 initSectionData(); 1560 return; 1561 } 1562 } 1563 1564 DvbSubtitleDescriptor::DvbSubtitleDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor) 1565 { 1566 if (getLength() < 10) { 1567 qCWarning(logDvbSi, "Invalid descriptor"); 1568 initSectionData(); 1569 return; 1570 } 1571 } 1572 1573 DvbServiceDescriptor::DvbServiceDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor) 1574 { 1575 if (getLength() < 5) { 1576 qCWarning(logDvbSi, "Invalid descriptor"); 1577 initSectionData(); 1578 return; 1579 } 1580 1581 providerNameLength = at(3); 1582 1583 if (providerNameLength > (getLength() - 5)) { 1584 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1585 providerNameLength = (getLength() - 5); 1586 } 1587 1588 serviceNameLength = at(4 + providerNameLength); 1589 1590 if (serviceNameLength > (getLength() - (5 + providerNameLength))) { 1591 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1592 serviceNameLength = (getLength() - (5 + providerNameLength)); 1593 } 1594 } 1595 1596 DvbShortEventDescriptor::DvbShortEventDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor) 1597 { 1598 if (getLength() < 7) { 1599 qCWarning(logDvbSi, "Invalid descriptor"); 1600 initSectionData(); 1601 return; 1602 } 1603 1604 eventNameLength = at(5); 1605 1606 if (eventNameLength > (getLength() - 7)) { 1607 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1608 eventNameLength = (getLength() - 7); 1609 } 1610 1611 textLength = at(6 + eventNameLength); 1612 1613 if (textLength > (getLength() - (7 + eventNameLength))) { 1614 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1615 textLength = (getLength() - (7 + eventNameLength)); 1616 } 1617 } 1618 1619 DvbExtendedEventDescriptor::DvbExtendedEventDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor) 1620 { 1621 if (getLength() < 8) { 1622 qCWarning(logDvbSi, "Invalid descriptor"); 1623 initSectionData(); 1624 return; 1625 } 1626 1627 itemsLength = at(6); 1628 1629 if (itemsLength > (getLength() - 8)) { 1630 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1631 itemsLength = (getLength() - 8); 1632 } 1633 1634 textLength = at(7 + itemsLength); 1635 1636 if (textLength > (getLength() - (8 + itemsLength))) { 1637 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1638 textLength = (getLength() - (8 + itemsLength)); 1639 } 1640 } 1641 1642 DvbContentDescriptor::DvbContentDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor) 1643 { 1644 if (getLength() < 2) { 1645 qCWarning(logDvbSi, "Invalid descriptor"); 1646 initSectionData(); 1647 return; 1648 } 1649 } 1650 1651 DvbParentalRatingDescriptor::DvbParentalRatingDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor) 1652 { 1653 if (getLength() < 2) { 1654 qCWarning(logDvbSi, "Invalid descriptor"); 1655 initSectionData(); 1656 return; 1657 } 1658 } 1659 1660 DvbCableDescriptor::DvbCableDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor) 1661 { 1662 if (getLength() < 13) { 1663 qCWarning(logDvbSi, "Invalid descriptor"); 1664 initSectionData(); 1665 return; 1666 } 1667 } 1668 1669 DvbSatelliteDescriptor::DvbSatelliteDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor) 1670 { 1671 if (getLength() < 13) { 1672 qCWarning(logDvbSi, "Invalid descriptor"); 1673 initSectionData(); 1674 return; 1675 } 1676 } 1677 1678 DvbTerrestrialDescriptor::DvbTerrestrialDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor) 1679 { 1680 if (getLength() < 13) { 1681 qCWarning(logDvbSi, "Invalid descriptor"); 1682 initSectionData(); 1683 return; 1684 } 1685 } 1686 1687 IsdbTerrestrialDescriptor::IsdbTerrestrialDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor) 1688 { 1689 if (getLength() < 4) { 1690 qCWarning(logDvbSi, "Invalid descriptor"); 1691 initSectionData(); 1692 return; 1693 } 1694 } 1695 1696 AtscChannelNameDescriptor::AtscChannelNameDescriptor(const DvbDescriptor &descriptor) : DvbDescriptor(descriptor) 1697 { 1698 if (getLength() < 2) { 1699 qCWarning(logDvbSi, "Invalid descriptor"); 1700 initSectionData(); 1701 return; 1702 } 1703 } 1704 1705 void DvbPatSection::initPatSection(const char *data, int size) 1706 { 1707 if (size < 12) { 1708 initSectionData(); 1709 return; 1710 } 1711 1712 initStandardSection(data, size); 1713 } 1714 1715 void DvbPmtSection::initPmtSection(const char *data, int size) 1716 { 1717 if (size < 16) { 1718 initSectionData(); 1719 return; 1720 } 1721 1722 initStandardSection(data, size); 1723 descriptorsLength = ((at(10) & 0xf) << 8) | at(11); 1724 1725 if (descriptorsLength > (getLength() - 16)) { 1726 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1727 descriptorsLength = (getLength() - 16); 1728 } 1729 } 1730 1731 void DvbSdtSection::initSdtSection(const char *data, int size) 1732 { 1733 if (size < 15) { 1734 initSectionData(); 1735 return; 1736 } 1737 1738 initStandardSection(data, size); 1739 } 1740 1741 void DvbEitSection::initEitSection(const char *data, int size) 1742 { 1743 if (size < 18) { 1744 initSectionData(); 1745 return; 1746 } 1747 1748 initStandardSection(data, size); 1749 } 1750 1751 void DvbNitSection::initNitSection(const char *data, int size) 1752 { 1753 if (size < 16) { 1754 initSectionData(); 1755 return; 1756 } 1757 1758 initStandardSection(data, size); 1759 descriptorsLength = ((at(8) & 0xf) << 8) | at(9); 1760 1761 if (descriptorsLength > (getLength() - 16)) { 1762 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1763 descriptorsLength = (getLength() - 16); 1764 } 1765 1766 entriesLength = ((at(10 + descriptorsLength) & 0xf) << 8) | at(11 + descriptorsLength); 1767 1768 if (entriesLength > (getLength() - (16 + descriptorsLength))) { 1769 qCWarning(logDvbSi, "Adjusting length on descriptor"); 1770 entriesLength = (getLength() - (16 + descriptorsLength)); 1771 } 1772 } 1773 1774 void AtscMgtSection::initMgtSection(const char *data, int size) 1775 { 1776 if (size < 17) { 1777 initSectionData(); 1778 return; 1779 } 1780 1781 initStandardSection(data, size); 1782 } 1783 1784 void AtscVctSection::initVctSection(const char *data, int size) 1785 { 1786 if (size < 14) { 1787 initSectionData(); 1788 return; 1789 } 1790 1791 initStandardSection(data, size); 1792 } 1793 1794 void AtscEitSection::initEitSection(const char *data, int size) 1795 { 1796 if (size < 14) { 1797 initSectionData(); 1798 return; 1799 } 1800 1801 initStandardSection(data, size); 1802 } 1803 1804 void AtscEttSection::initEttSection(const char *data, int size) 1805 { 1806 if (size < 17) { 1807 initSectionData(); 1808 return; 1809 } 1810 1811 initStandardSection(data, size); 1812 } 1813 1814 #include "moc_dvbsi.cpp"