Add importing of single page .t42 files, wrt #2
This commit is contained in:
179
hamming.h
Normal file
179
hamming.h
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
#ifndef HAMMING_H
|
||||||
|
#define HAMMING_H
|
||||||
|
|
||||||
|
// Hamming 8/4 decoding table
|
||||||
|
// decoded_value = hamming_8_4_decode[encoded_value]
|
||||||
|
// 0xff - double bit error that can't be corrected
|
||||||
|
const unsigned char hamming_8_4_decode[256] = {
|
||||||
|
0x01, 0xff, 0x01, 0x01, 0xff, 0x00, 0x01, 0xff,
|
||||||
|
0xff, 0x02, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x07,
|
||||||
|
0xff, 0x00, 0x01, 0xff, 0x00, 0x00, 0xff, 0x00,
|
||||||
|
0x06, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x03, 0xff,
|
||||||
|
0xff, 0x0c, 0x01, 0xff, 0x04, 0xff, 0xff, 0x07,
|
||||||
|
0x06, 0xff, 0xff, 0x07, 0xff, 0x07, 0x07, 0x07,
|
||||||
|
0x06, 0xff, 0xff, 0x05, 0xff, 0x00, 0x0d, 0xff,
|
||||||
|
0x06, 0x06, 0x06, 0xff, 0x06, 0xff, 0xff, 0x07,
|
||||||
|
0xff, 0x02, 0x01, 0xff, 0x04, 0xff, 0xff, 0x09,
|
||||||
|
0x02, 0x02, 0xff, 0x02, 0xff, 0x02, 0x03, 0xff,
|
||||||
|
0x08, 0xff, 0xff, 0x05, 0xff, 0x00, 0x03, 0xff,
|
||||||
|
0xff, 0x02, 0x03, 0xff, 0x03, 0xff, 0x03, 0x03,
|
||||||
|
0x04, 0xff, 0xff, 0x05, 0x04, 0x04, 0x04, 0xff,
|
||||||
|
0xff, 0x02, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x07,
|
||||||
|
0xff, 0x05, 0x05, 0x05, 0x04, 0xff, 0xff, 0x05,
|
||||||
|
0x06, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x03, 0xff,
|
||||||
|
0xff, 0x0c, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x09,
|
||||||
|
0x0a, 0xff, 0xff, 0x0b, 0x0a, 0x0a, 0x0a, 0xff,
|
||||||
|
0x08, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x0d, 0xff,
|
||||||
|
0xff, 0x0b, 0x0b, 0x0b, 0x0a, 0xff, 0xff, 0x0b,
|
||||||
|
0x0c, 0x0c, 0xff, 0x0c, 0xff, 0x0c, 0x0d, 0xff,
|
||||||
|
0xff, 0x0c, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x07,
|
||||||
|
0xff, 0x0c, 0x0d, 0xff, 0x0d, 0xff, 0x0d, 0x0d,
|
||||||
|
0x06, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x0d, 0xff,
|
||||||
|
0x08, 0xff, 0xff, 0x09, 0xff, 0x09, 0x09, 0x09,
|
||||||
|
0xff, 0x02, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x09,
|
||||||
|
0x08, 0x08, 0x08, 0xff, 0x08, 0xff, 0xff, 0x09,
|
||||||
|
0x08, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x03, 0xff,
|
||||||
|
0xff, 0x0c, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x09,
|
||||||
|
0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x0e, 0x0f, 0xff,
|
||||||
|
0x08, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x0d, 0xff,
|
||||||
|
0xff, 0x0e, 0x0f, 0xff, 0x0e, 0x0e, 0xff, 0x0e
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned char hamming_24_18_parities[3][256] = {
|
||||||
|
{ // Parities of first byte
|
||||||
|
0x00, 0x21, 0x22, 0x03, 0x23, 0x02, 0x01, 0x20,
|
||||||
|
0x24, 0x05, 0x06, 0x27, 0x07, 0x26, 0x25, 0x04,
|
||||||
|
0x25, 0x04, 0x07, 0x26, 0x06, 0x27, 0x24, 0x05,
|
||||||
|
0x01, 0x20, 0x23, 0x02, 0x22, 0x03, 0x00, 0x21,
|
||||||
|
0x26, 0x07, 0x04, 0x25, 0x05, 0x24, 0x27, 0x06,
|
||||||
|
0x02, 0x23, 0x20, 0x01, 0x21, 0x00, 0x03, 0x22,
|
||||||
|
0x03, 0x22, 0x21, 0x00, 0x20, 0x01, 0x02, 0x23,
|
||||||
|
0x27, 0x06, 0x05, 0x24, 0x04, 0x25, 0x26, 0x07,
|
||||||
|
0x27, 0x06, 0x05, 0x24, 0x04, 0x25, 0x26, 0x07,
|
||||||
|
0x03, 0x22, 0x21, 0x00, 0x20, 0x01, 0x02, 0x23,
|
||||||
|
0x02, 0x23, 0x20, 0x01, 0x21, 0x00, 0x03, 0x22,
|
||||||
|
0x26, 0x07, 0x04, 0x25, 0x05, 0x24, 0x27, 0x06,
|
||||||
|
0x01, 0x20, 0x23, 0x02, 0x22, 0x03, 0x00, 0x21,
|
||||||
|
0x25, 0x04, 0x07, 0x26, 0x06, 0x27, 0x24, 0x05,
|
||||||
|
0x24, 0x05, 0x06, 0x27, 0x07, 0x26, 0x25, 0x04,
|
||||||
|
0x00, 0x21, 0x22, 0x03, 0x23, 0x02, 0x01, 0x20,
|
||||||
|
0x28, 0x09, 0x0a, 0x2b, 0x0b, 0x2a, 0x29, 0x08,
|
||||||
|
0x0c, 0x2d, 0x2e, 0x0f, 0x2f, 0x0e, 0x0d, 0x2c,
|
||||||
|
0x0d, 0x2c, 0x2f, 0x0e, 0x2e, 0x0f, 0x0c, 0x2d,
|
||||||
|
0x29, 0x08, 0x0b, 0x2a, 0x0a, 0x2b, 0x28, 0x09,
|
||||||
|
0x0e, 0x2f, 0x2c, 0x0d, 0x2d, 0x0c, 0x0f, 0x2e,
|
||||||
|
0x2a, 0x0b, 0x08, 0x29, 0x09, 0x28, 0x2b, 0x0a,
|
||||||
|
0x2b, 0x0a, 0x09, 0x28, 0x08, 0x29, 0x2a, 0x0b,
|
||||||
|
0x0f, 0x2e, 0x2d, 0x0c, 0x2c, 0x0d, 0x0e, 0x2f,
|
||||||
|
0x0f, 0x2e, 0x2d, 0x0c, 0x2c, 0x0d, 0x0e, 0x2f,
|
||||||
|
0x2b, 0x0a, 0x09, 0x28, 0x08, 0x29, 0x2a, 0x0b,
|
||||||
|
0x2a, 0x0b, 0x08, 0x29, 0x09, 0x28, 0x2b, 0x0a,
|
||||||
|
0x0e, 0x2f, 0x2c, 0x0d, 0x2d, 0x0c, 0x0f, 0x2e,
|
||||||
|
0x29, 0x08, 0x0b, 0x2a, 0x0a, 0x2b, 0x28, 0x09,
|
||||||
|
0x0d, 0x2c, 0x2f, 0x0e, 0x2e, 0x0f, 0x0c, 0x2d,
|
||||||
|
0x0c, 0x2d, 0x2e, 0x0f, 0x2f, 0x0e, 0x0d, 0x2c,
|
||||||
|
0x28, 0x09, 0x0a, 0x2b, 0x0b, 0x2a, 0x29, 0x08
|
||||||
|
},
|
||||||
|
{ // Parities of second byte
|
||||||
|
0x00, 0x29, 0x2a, 0x03, 0x2b, 0x02, 0x01, 0x28,
|
||||||
|
0x2c, 0x05, 0x06, 0x2f, 0x07, 0x2e, 0x2d, 0x04,
|
||||||
|
0x2d, 0x04, 0x07, 0x2e, 0x06, 0x2f, 0x2c, 0x05,
|
||||||
|
0x01, 0x28, 0x2b, 0x02, 0x2a, 0x03, 0x00, 0x29,
|
||||||
|
0x2e, 0x07, 0x04, 0x2d, 0x05, 0x2c, 0x2f, 0x06,
|
||||||
|
0x02, 0x2b, 0x28, 0x01, 0x29, 0x00, 0x03, 0x2a,
|
||||||
|
0x03, 0x2a, 0x29, 0x00, 0x28, 0x01, 0x02, 0x2b,
|
||||||
|
0x2f, 0x06, 0x05, 0x2c, 0x04, 0x2d, 0x2e, 0x07,
|
||||||
|
0x2f, 0x06, 0x05, 0x2c, 0x04, 0x2d, 0x2e, 0x07,
|
||||||
|
0x03, 0x2a, 0x29, 0x00, 0x28, 0x01, 0x02, 0x2b,
|
||||||
|
0x02, 0x2b, 0x28, 0x01, 0x29, 0x00, 0x03, 0x2a,
|
||||||
|
0x2e, 0x07, 0x04, 0x2d, 0x05, 0x2c, 0x2f, 0x06,
|
||||||
|
0x01, 0x28, 0x2b, 0x02, 0x2a, 0x03, 0x00, 0x29,
|
||||||
|
0x2d, 0x04, 0x07, 0x2e, 0x06, 0x2f, 0x2c, 0x05,
|
||||||
|
0x2c, 0x05, 0x06, 0x2f, 0x07, 0x2e, 0x2d, 0x04,
|
||||||
|
0x00, 0x29, 0x2a, 0x03, 0x2b, 0x02, 0x01, 0x28,
|
||||||
|
0x30, 0x19, 0x1a, 0x33, 0x1b, 0x32, 0x31, 0x18,
|
||||||
|
0x1c, 0x35, 0x36, 0x1f, 0x37, 0x1e, 0x1d, 0x34,
|
||||||
|
0x1d, 0x34, 0x37, 0x1e, 0x36, 0x1f, 0x1c, 0x35,
|
||||||
|
0x31, 0x18, 0x1b, 0x32, 0x1a, 0x33, 0x30, 0x19,
|
||||||
|
0x1e, 0x37, 0x34, 0x1d, 0x35, 0x1c, 0x1f, 0x36,
|
||||||
|
0x32, 0x1b, 0x18, 0x31, 0x19, 0x30, 0x33, 0x1a,
|
||||||
|
0x33, 0x1a, 0x19, 0x30, 0x18, 0x31, 0x32, 0x1b,
|
||||||
|
0x1f, 0x36, 0x35, 0x1c, 0x34, 0x1d, 0x1e, 0x37,
|
||||||
|
0x1f, 0x36, 0x35, 0x1c, 0x34, 0x1d, 0x1e, 0x37,
|
||||||
|
0x33, 0x1a, 0x19, 0x30, 0x18, 0x31, 0x32, 0x1b,
|
||||||
|
0x32, 0x1b, 0x18, 0x31, 0x19, 0x30, 0x33, 0x1a,
|
||||||
|
0x1e, 0x37, 0x34, 0x1d, 0x35, 0x1c, 0x1f, 0x36,
|
||||||
|
0x31, 0x18, 0x1b, 0x32, 0x1a, 0x33, 0x30, 0x19,
|
||||||
|
0x1d, 0x34, 0x37, 0x1e, 0x36, 0x1f, 0x1c, 0x35,
|
||||||
|
0x1c, 0x35, 0x36, 0x1f, 0x37, 0x1e, 0x1d, 0x34,
|
||||||
|
0x30, 0x19, 0x1a, 0x33, 0x1b, 0x32, 0x31, 0x18
|
||||||
|
},
|
||||||
|
{ // Parities of third byte
|
||||||
|
0x3f, 0x0e, 0x0d, 0x3c, 0x0c, 0x3d, 0x3e, 0x0f,
|
||||||
|
0x0b, 0x3a, 0x39, 0x08, 0x38, 0x09, 0x0a, 0x3b,
|
||||||
|
0x0a, 0x3b, 0x38, 0x09, 0x39, 0x08, 0x0b, 0x3a,
|
||||||
|
0x3e, 0x0f, 0x0c, 0x3d, 0x0d, 0x3c, 0x3f, 0x0e,
|
||||||
|
0x09, 0x38, 0x3b, 0x0a, 0x3a, 0x0b, 0x08, 0x39,
|
||||||
|
0x3d, 0x0c, 0x0f, 0x3e, 0x0e, 0x3f, 0x3c, 0x0d,
|
||||||
|
0x3c, 0x0d, 0x0e, 0x3f, 0x0f, 0x3e, 0x3d, 0x0c,
|
||||||
|
0x08, 0x39, 0x3a, 0x0b, 0x3b, 0x0a, 0x09, 0x38,
|
||||||
|
0x08, 0x39, 0x3a, 0x0b, 0x3b, 0x0a, 0x09, 0x38,
|
||||||
|
0x3c, 0x0d, 0x0e, 0x3f, 0x0f, 0x3e, 0x3d, 0x0c,
|
||||||
|
0x3d, 0x0c, 0x0f, 0x3e, 0x0e, 0x3f, 0x3c, 0x0d,
|
||||||
|
0x09, 0x38, 0x3b, 0x0a, 0x3a, 0x0b, 0x08, 0x39,
|
||||||
|
0x3e, 0x0f, 0x0c, 0x3d, 0x0d, 0x3c, 0x3f, 0x0e,
|
||||||
|
0x0a, 0x3b, 0x38, 0x09, 0x39, 0x08, 0x0b, 0x3a,
|
||||||
|
0x0b, 0x3a, 0x39, 0x08, 0x38, 0x09, 0x0a, 0x3b,
|
||||||
|
0x3f, 0x0e, 0x0d, 0x3c, 0x0c, 0x3d, 0x3e, 0x0f,
|
||||||
|
0x1f, 0x2e, 0x2d, 0x1c, 0x2c, 0x1d, 0x1e, 0x2f,
|
||||||
|
0x2b, 0x1a, 0x19, 0x28, 0x18, 0x29, 0x2a, 0x1b,
|
||||||
|
0x2a, 0x1b, 0x18, 0x29, 0x19, 0x28, 0x2b, 0x1a,
|
||||||
|
0x1e, 0x2f, 0x2c, 0x1d, 0x2d, 0x1c, 0x1f, 0x2e,
|
||||||
|
0x29, 0x18, 0x1b, 0x2a, 0x1a, 0x2b, 0x28, 0x19,
|
||||||
|
0x1d, 0x2c, 0x2f, 0x1e, 0x2e, 0x1f, 0x1c, 0x2d,
|
||||||
|
0x1c, 0x2d, 0x2e, 0x1f, 0x2f, 0x1e, 0x1d, 0x2c,
|
||||||
|
0x28, 0x19, 0x1a, 0x2b, 0x1b, 0x2a, 0x29, 0x18,
|
||||||
|
0x28, 0x19, 0x1a, 0x2b, 0x1b, 0x2a, 0x29, 0x18,
|
||||||
|
0x1c, 0x2d, 0x2e, 0x1f, 0x2f, 0x1e, 0x1d, 0x2c,
|
||||||
|
0x1d, 0x2c, 0x2f, 0x1e, 0x2e, 0x1f, 0x1c, 0x2d,
|
||||||
|
0x29, 0x18, 0x1b, 0x2a, 0x1a, 0x2b, 0x28, 0x19,
|
||||||
|
0x1e, 0x2f, 0x2c, 0x1d, 0x2d, 0x1c, 0x1f, 0x2e,
|
||||||
|
0x2a, 0x1b, 0x18, 0x29, 0x19, 0x28, 0x2b, 0x1a,
|
||||||
|
0x2b, 0x1a, 0x19, 0x28, 0x18, 0x29, 0x2a, 0x1b,
|
||||||
|
0x1f, 0x2e, 0x2d, 0x1c, 0x2c, 0x1d, 0x1e, 0x2f
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char hamming_24_18_decode_d1_d4[64] = {
|
||||||
|
0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
|
||||||
|
0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
|
||||||
|
0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
|
||||||
|
0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
|
||||||
|
0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
|
||||||
|
0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mapping from parity checks in hamming_24_18_parities to incorrect bit
|
||||||
|
// 0x80000000 - double bit error that can't be corrected
|
||||||
|
static const unsigned int hamming_24_18_decode_correct [64] = {
|
||||||
|
0x00000000, 0x80000000, 0x80000000, 0x80000000,
|
||||||
|
0x80000000, 0x80000000, 0x80000000, 0x80000000,
|
||||||
|
0x80000000, 0x80000000, 0x80000000, 0x80000000,
|
||||||
|
0x80000000, 0x80000000, 0x80000000, 0x80000000,
|
||||||
|
0x80000000, 0x80000000, 0x80000000, 0x80000000,
|
||||||
|
0x80000000, 0x80000000, 0x80000000, 0x80000000,
|
||||||
|
0x80000000, 0x80000000, 0x80000000, 0x80000000,
|
||||||
|
0x80000000, 0x80000000, 0x80000000, 0x80000000,
|
||||||
|
0x00000000, 0x00000000, 0x00000000, 0x00000001,
|
||||||
|
0x00000000, 0x00000002, 0x00000004, 0x00000008,
|
||||||
|
0x00000000, 0x00000010, 0x00000020, 0x00000040,
|
||||||
|
0x00000080, 0x00000100, 0x00000200, 0x00000400,
|
||||||
|
0x00000000, 0x00000800, 0x00001000, 0x00002000,
|
||||||
|
0x00004000, 0x00008000, 0x00010000, 0x00020000,
|
||||||
|
0x80000000, 0x80000000, 0x80000000, 0x80000000,
|
||||||
|
0x80000000, 0x80000000, 0x80000000, 0x80000000
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
190
loadsave.cpp
190
loadsave.cpp
@@ -26,6 +26,7 @@
|
|||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
#include "document.h"
|
#include "document.h"
|
||||||
|
#include "hamming.h"
|
||||||
#include "levelonepage.h"
|
#include "levelonepage.h"
|
||||||
#include "pagebase.h"
|
#include "pagebase.h"
|
||||||
|
|
||||||
@@ -166,6 +167,195 @@ void loadTTI(QFile *inFile, TeletextDocument *document)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void importT42(QFile *inFile, TeletextDocument *document)
|
||||||
|
{
|
||||||
|
unsigned char inLine[42];
|
||||||
|
int readMagazineNumber, readPacketNumber;
|
||||||
|
int foundMagazineNumber = -1;
|
||||||
|
int foundPageNumber = -1;
|
||||||
|
bool firstPacket0Found = false;
|
||||||
|
bool pageBodyPacketsFound = false;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (inFile->read((char *)inLine, 42) != 42)
|
||||||
|
// Reached end of .t42 file, or less than 42 bytes left
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Magazine and packet numbers
|
||||||
|
inLine[0] = hamming_8_4_decode[inLine[0]];
|
||||||
|
inLine[1] = hamming_8_4_decode[inLine[1]];
|
||||||
|
if (inLine[0] == 0xff || inLine[1] == 0xff)
|
||||||
|
// Error decoding magazine or packet number
|
||||||
|
continue;
|
||||||
|
readMagazineNumber = inLine[0] & 0x07;
|
||||||
|
readPacketNumber = (inLine[0] >> 3) | (inLine[1] << 1);
|
||||||
|
|
||||||
|
if (readPacketNumber == 0) {
|
||||||
|
// Hamming decode page number, subcodes and control bits
|
||||||
|
for (int i=2; i<10; i++)
|
||||||
|
inLine[i] = hamming_8_4_decode[inLine[i]];
|
||||||
|
// See if the page number is valid
|
||||||
|
if (inLine[2] == 0xff || inLine[3] == 0xff)
|
||||||
|
// Error decoding page number
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const int readPageNumber = (inLine[3] << 4) | inLine[2];
|
||||||
|
|
||||||
|
if (readPageNumber == 0xff)
|
||||||
|
// Time filling header
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// A second or subsequent X/0 has been found
|
||||||
|
if (firstPacket0Found) {
|
||||||
|
if (readMagazineNumber != foundMagazineNumber)
|
||||||
|
// Packet from different magazine broadcast in parallel mode
|
||||||
|
continue;
|
||||||
|
if ((readPageNumber == foundPageNumber) && pageBodyPacketsFound)
|
||||||
|
// X/0 with same page number found after page body packets loaded - assume end of page
|
||||||
|
break;
|
||||||
|
if (readPageNumber != foundPageNumber) {
|
||||||
|
// More than one page in .t42 file - end of current page reached
|
||||||
|
qDebug("More than one page in .t42 file");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Could get here if X/0 with same page number was found with no body packets inbetween
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// First X/0 found
|
||||||
|
foundMagazineNumber = readMagazineNumber;
|
||||||
|
foundPageNumber = readPageNumber;
|
||||||
|
firstPacket0Found = true;
|
||||||
|
|
||||||
|
document->setPageNumber((foundMagazineNumber << 8) | foundPageNumber);
|
||||||
|
|
||||||
|
document->subPage(0)->setControlBit(PageBase::C4ErasePage, inLine[5] & 0x08);
|
||||||
|
document->subPage(0)->setControlBit(PageBase::C5Newsflash, inLine[7] & 0x04);
|
||||||
|
document->subPage(0)->setControlBit(PageBase::C6Subtitle, inLine[7] & 0x08);
|
||||||
|
for (int i=0; i<4; i++)
|
||||||
|
document->subPage(0)->setControlBit(PageBase::C7SuppressHeader+i, inLine[8] & (1 << i));
|
||||||
|
document->subPage(0)->setControlBit(PageBase::C11SerialMagazine, inLine[9] & 0x01);
|
||||||
|
document->subPage(0)->setControlBit(PageBase::C12NOS, inLine[9] & 0x08);
|
||||||
|
document->subPage(0)->setControlBit(PageBase::C13NOS, inLine[9] & 0x04);
|
||||||
|
document->subPage(0)->setControlBit(PageBase::C14NOS, inLine[9] & 0x02);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No X/0 has been found yet, keep looking for one
|
||||||
|
if (!firstPacket0Found)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Disregard whole-magazine packets
|
||||||
|
if (readPacketNumber > 28)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// We get here when a page-body packet belonging to the found X/0 header was found
|
||||||
|
pageBodyPacketsFound = true;
|
||||||
|
|
||||||
|
// At the moment this only loads a Level One Page properly
|
||||||
|
// because it assumes X/1 to X/25 is odd partity
|
||||||
|
if (readPacketNumber < 25) {
|
||||||
|
for (int i=2; i<42; i++)
|
||||||
|
// TODO - obey odd parity?
|
||||||
|
inLine[i] &= 0x7f;
|
||||||
|
document->subPage(0)->setPacket(readPacketNumber, QByteArray((const char *)&inLine[2], 40));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// X/26, X/27 or X/28
|
||||||
|
int readDesignationCode = hamming_8_4_decode[inLine[2]];
|
||||||
|
|
||||||
|
if (readDesignationCode == 0xff)
|
||||||
|
// Error decoding designation code
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (readPacketNumber == 27 && readDesignationCode < 4) {
|
||||||
|
// X/27/0 to X/27/3 for Editorial Linking
|
||||||
|
// Decode Hamming 8/4 on each of the six links, checking for errors on the way
|
||||||
|
for (int i=0; i<6; i++) {
|
||||||
|
bool decodingError = false;
|
||||||
|
const int b = 3 + i*6; // First byte of this link
|
||||||
|
|
||||||
|
for (int j=0; j<6; j++) {
|
||||||
|
inLine[b+j] = hamming_8_4_decode[inLine[b+j]];
|
||||||
|
if (inLine[b+j] == 0xff) {
|
||||||
|
decodingError = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decodingError) {
|
||||||
|
// Error found in at least one byte of the link
|
||||||
|
// Neutralise the whole link to same magazine, page FF, subcode 3F7F
|
||||||
|
qDebug("X/27/%d link %d decoding error", readDesignationCode, i);
|
||||||
|
inLine[b] = 0xf;
|
||||||
|
inLine[b+1] = 0xf;
|
||||||
|
inLine[b+2] = 0xf;
|
||||||
|
inLine[b+3] = 0x7;
|
||||||
|
inLine[b+4] = 0xf;
|
||||||
|
inLine[b+5] = 0x3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document->subPage(0)->setPacket(readPacketNumber, readDesignationCode, QByteArray((const char *)&inLine[2], 40));
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// X/26, or X/27/4 to X/27/15, or X/28
|
||||||
|
// Decode Hamming 24/18
|
||||||
|
for (int i=0; i<13; i++) {
|
||||||
|
const int b = 3 + i*3; // First byte of triplet
|
||||||
|
|
||||||
|
const int p0 = inLine[b];
|
||||||
|
const int p1 = inLine[b+1];
|
||||||
|
const int p2 = inLine[b+2];
|
||||||
|
|
||||||
|
unsigned int D1_D4;
|
||||||
|
unsigned int D5_D11;
|
||||||
|
unsigned int D12_D18;
|
||||||
|
unsigned int ABCDEF;
|
||||||
|
int32_t d;
|
||||||
|
|
||||||
|
D1_D4 = hamming_24_18_decode_d1_d4[p0 >> 2];
|
||||||
|
D5_D11 = p1 & 0x7f;
|
||||||
|
D12_D18 = p2 & 0x7f;
|
||||||
|
|
||||||
|
d = D1_D4 | (D5_D11 << 4) | (D12_D18 << 11);
|
||||||
|
|
||||||
|
ABCDEF = (hamming_24_18_parities[0][p0] ^ hamming_24_18_parities[1][p1] ^ hamming_24_18_parities[2][p2]);
|
||||||
|
|
||||||
|
d ^= (int)hamming_24_18_decode_correct[ABCDEF];
|
||||||
|
|
||||||
|
if ((d & 0x80000000) == 0x80000000) {
|
||||||
|
// Error decoding Hamming 24/18
|
||||||
|
qDebug("X/%d/%d triplet %d decoding error", readPacketNumber, readDesignationCode, i);
|
||||||
|
if (readPacketNumber == 26) {
|
||||||
|
// Enhancements packet, set to "dummy" Address 41, Mode 0x1e, Data 0
|
||||||
|
inLine[b] = 41;
|
||||||
|
inLine[b+1] = 0x1e;
|
||||||
|
inLine[b+2] = 0;
|
||||||
|
} else {
|
||||||
|
// Zero out whole decoded triplet, bound to make things go wrong...
|
||||||
|
inLine[b] = 0x00;
|
||||||
|
inLine[b+1] = 0x00;
|
||||||
|
inLine[b+2] = 0x00;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inLine[b] = d & 0x0003f;
|
||||||
|
inLine[b+1] = (d & 0x00fc0) >> 6;
|
||||||
|
inLine[b+2] = d >> 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document->subPage(0)->setPacket(readPacketNumber, readDesignationCode, QByteArray((const char *)&inLine[2], 40));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!firstPacket0Found)
|
||||||
|
qDebug("No X/0 found");
|
||||||
|
else if (!pageBodyPacketsFound)
|
||||||
|
qDebug("X/0 found, but no page body packets were found");
|
||||||
|
}
|
||||||
|
|
||||||
// Used by saveTTI and HashString
|
// Used by saveTTI and HashString
|
||||||
int controlBitsToPS(PageBase *subPage)
|
int controlBitsToPS(PageBase *subPage)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,7 +30,8 @@
|
|||||||
#include "levelonepage.h"
|
#include "levelonepage.h"
|
||||||
#include "pagebase.h"
|
#include "pagebase.h"
|
||||||
|
|
||||||
void loadTTI(QFile *inFile, TeletextDocument *document);
|
void loadTTI(QFile *, TeletextDocument *);
|
||||||
|
void importT42(QFile *, TeletextDocument *);
|
||||||
|
|
||||||
int controlBitsToPS(PageBase *);
|
int controlBitsToPS(PageBase *);
|
||||||
|
|
||||||
|
|||||||
@@ -844,14 +844,27 @@ void MainWindow::loadFile(const QString &fileName)
|
|||||||
int levelSeen;
|
int levelSeen;
|
||||||
|
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
const QFileInfo fileInfo(file);
|
||||||
|
QIODevice::OpenMode fileOpenMode;
|
||||||
|
|
||||||
|
if (fileInfo.suffix() == "t42")
|
||||||
|
fileOpenMode = QFile::ReadOnly;
|
||||||
|
else
|
||||||
|
fileOpenMode = QFile::ReadOnly | QFile::Text;
|
||||||
|
|
||||||
|
if (!file.open(fileOpenMode)) {
|
||||||
QMessageBox::warning(this, tr("QTeletextMaker"), tr("Cannot read file %1:\n%2.").arg(QDir::toNativeSeparators(fileName), file.errorString()));
|
QMessageBox::warning(this, tr("QTeletextMaker"), tr("Cannot read file %1:\n%2.").arg(QDir::toNativeSeparators(fileName), file.errorString()));
|
||||||
setCurrentFile(QString());
|
setCurrentFile(QString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
|
|
||||||
|
if (fileInfo.suffix() == "t42")
|
||||||
|
importT42(&file, m_textWidget->document());
|
||||||
|
else
|
||||||
loadTTI(&file, m_textWidget->document());
|
loadTTI(&file, m_textWidget->document());
|
||||||
|
|
||||||
levelSeen = m_textWidget->document()->levelRequired();
|
levelSeen = m_textWidget->document()->levelRequired();
|
||||||
m_levelRadioButton[levelSeen]->toggle();
|
m_levelRadioButton[levelSeen]->toggle();
|
||||||
m_textWidget->pageRender()->setRenderLevel(levelSeen);
|
m_textWidget->pageRender()->setRenderLevel(levelSeen);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ QT += widgets
|
|||||||
requires(qtConfig(filedialog))
|
requires(qtConfig(filedialog))
|
||||||
|
|
||||||
HEADERS = document.h \
|
HEADERS = document.h \
|
||||||
|
hamming.h \
|
||||||
keymap.h \
|
keymap.h \
|
||||||
levelonecommands.h \
|
levelonecommands.h \
|
||||||
levelonepage.h \
|
levelonepage.h \
|
||||||
@@ -37,6 +38,8 @@ SOURCES = document.cpp \
|
|||||||
x26triplets.cpp
|
x26triplets.cpp
|
||||||
RESOURCES = qteletextmaker.qrc
|
RESOURCES = qteletextmaker.qrc
|
||||||
|
|
||||||
|
CONFIG += debug
|
||||||
|
|
||||||
# install
|
# install
|
||||||
target.path = /usr/local/bin
|
target.path = /usr/local/bin
|
||||||
INSTALLS += target
|
INSTALLS += target
|
||||||
|
|||||||
Reference in New Issue
Block a user