1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-04-15 18:09:11 +02:00

Code cleanup

This commit is contained in:
Martin Tůma 2021-08-10 20:44:16 +02:00
parent 82d2ac0871
commit 78e8b03d66
2 changed files with 78 additions and 49 deletions

View File

@ -6,8 +6,6 @@
using namespace IMG; using namespace IMG;
typedef QMap<QByteArray, VectorTile*> TileMap;
static SubFile::Type tileType(const char str[3]) static SubFile::Type tileType(const char str[3])
{ {
if (!memcmp(str, "TRE", 3)) if (!memcmp(str, "TRE", 3))
@ -26,25 +24,25 @@ static SubFile::Type tileType(const char str[3])
return SubFile::Unknown; return SubFile::Unknown;
} }
IMGData::IMGData(const QString &fileName) : _fileName(fileName) bool IMGData::readSubFileBlocks(QFile &file, quint64 offset, SubFile *subFile)
{ {
#define CHECK(condition) \ quint16 block;
if (!(condition)) { \
_errorString = "Unsupported or invalid IMG file"; \ if (!file.seek(offset + 0x20))
qDeleteAll(tileMap); \ return false;
return; \ for (int i = 0; i < 240; i++) {
if (!readValue(file, block))
return false;
if (block == 0xFFFF)
break;
subFile->addBlock(block);
} }
QFile file(fileName); return true;
TileMap tileMap;
QByteArray typFile;
if (!file.open(QFile::ReadOnly)) {
_errorString = file.errorString();
return;
} }
// Read IMG header bool IMGData::readIMGHeader(QFile &file)
{
char signature[7], identifier[7]; char signature[7], identifier[7];
file.read((char*)&_key, 1) && file.seek(0x10) file.read((char*)&_key, 1) && file.seek(0x10)
&& read(file, signature, sizeof(signature)) && file.seek(0x41) && read(file, signature, sizeof(signature)) && file.seek(0x41)
@ -52,24 +50,35 @@ IMGData::IMGData(const QString &fileName) : _fileName(fileName)
if (memcmp(signature, "DSKIMG", sizeof(signature)) if (memcmp(signature, "DSKIMG", sizeof(signature))
|| memcmp(identifier, "GARMIN", sizeof(identifier))) { || memcmp(identifier, "GARMIN", sizeof(identifier))) {
_errorString = "Not a Garmin IMG file"; _errorString = "Not a Garmin IMG file";
return; return false;
} }
char d1[20], d2[31]; char d1[20], d2[31];
quint8 e1, e2; quint8 e1, e2;
CHECK(file.seek(0x49) && read(file, d1, sizeof(d1)) && file.seek(0x61) if (!(file.seek(0x49) && read(file, d1, sizeof(d1)) && file.seek(0x61)
&& readValue(file, e1) && readValue(file, e2) && file.seek(0x65) && readValue(file, e1) && readValue(file, e2) && file.seek(0x65)
&& read(file, d2, sizeof(d2))); && read(file, d2, sizeof(d2)))) {
_errorString = "Error reading IMG header";
return false;
}
QByteArray nba(QByteArray(d1, sizeof(d1)) + QByteArray(d2, sizeof(d2))); QByteArray nba(QByteArray(d1, sizeof(d1)) + QByteArray(d2, sizeof(d2)));
_name = QString::fromLatin1(nba.constData(), nba.size()-1).trimmed(); _name = QString::fromLatin1(nba.constData(), nba.size()-1).trimmed();
_blockBits = e1 + e2; _blockBits = e1 + e2;
// Read the FAT table return true;
}
bool IMGData::readFAT(QFile &file, TileMap &tileMap)
{
QByteArray typFile;
quint8 flag; quint8 flag;
quint64 offset = 0x200; quint64 offset = 0x200;
// Skip unused FAT blocks if any // Skip unused FAT blocks if any
while (true) { while (true) {
CHECK(file.seek(offset) && readValue(file, flag)); if (!(file.seek(offset) && readValue(file, flag)))
return false;
if (flag) if (flag)
break; break;
offset += 512; offset += 512;
@ -79,17 +88,18 @@ IMGData::IMGData(const QString &fileName) : _fileName(fileName)
char name[8], type[3]; char name[8], type[3];
quint32 size; quint32 size;
quint16 part; quint16 part;
CHECK(file.seek(offset + 12) && readValue(file, size)); if (!(file.seek(offset + 12) && readValue(file, size)))
return false;
offset += 512; offset += 512;
int cnt = (size - offset) / 512; int cnt = (size - offset) / 512;
// Read FAT blocks describing the IMG sub-files // Read FAT blocks describing the IMG sub-files
for (int i = 0; i < cnt; i++) { for (int i = 0; i < cnt; i++) {
quint16 block; if (!(file.seek(offset) && readValue(file, flag)
CHECK(file.seek(offset) && readValue(file, flag)
&& read(file, name, sizeof(name)) && read(file, name, sizeof(name))
&& read(file, type, sizeof(type)) && readValue(file, size) && read(file, type, sizeof(type)) && readValue(file, size)
&& readValue(file, part)); && readValue(file, part)))
return false;
SubFile::Type tt = tileType(type); SubFile::Type tt = tileType(type);
QByteArray fn(name, sizeof(name)); QByteArray fn(name, sizeof(name));
@ -104,15 +114,8 @@ IMGData::IMGData(const QString &fileName) : _fileName(fileName)
SubFile *subFile = part ? tile->file(tt) SubFile *subFile = part ? tile->file(tt)
: tile->addFile(this, tt); : tile->addFile(this, tt);
CHECK(subFile); if (!(subFile && readSubFileBlocks(file, offset, subFile)))
return false;
CHECK(file.seek(offset + 0x20));
for (int i = 0; i < 240; i++) {
CHECK(readValue(file, block));
if (block == 0xFFFF)
break;
subFile->addBlock(block);
}
} else if (tt == SubFile::TYP) { } else if (tt == SubFile::TYP) {
SubFile *typ = 0; SubFile *typ = 0;
if (typFile.isNull()) { if (typFile.isNull()) {
@ -122,28 +125,26 @@ IMGData::IMGData(const QString &fileName) : _fileName(fileName)
} else if (fn == typFile) } else if (fn == typFile)
typ = _typ; typ = _typ;
if (typ) { if (typ && !readSubFileBlocks(file, offset, typ))
CHECK(file.seek(offset + 0x20)); return false;
for (int i = 0; i < 240; i++) {
CHECK(readValue(file, block));
if (block == 0xFFFF)
break;
typ->addBlock(block);
}
}
} }
offset += 512; offset += 512;
} }
// Create tile tree return true;
}
bool IMGData::createTileTree(const TileMap &tileMap)
{
int minMapZoom = 24; int minMapZoom = 24;
for (TileMap::const_iterator it = tileMap.constBegin(); for (TileMap::const_iterator it = tileMap.constBegin();
it != tileMap.constEnd(); ++it) { it != tileMap.constEnd(); ++it) {
VectorTile *tile = it.value(); VectorTile *tile = it.value();
if (!tile->init()) { if (!tile->init()) {
qWarning("%s: %s: Invalid map tile", qPrintable(file.fileName()), qWarning("%s: %s: Invalid map tile", qPrintable(_fileName),
qPrintable(it.key())); qPrintable(it.key()));
delete tile; delete tile;
continue; continue;
@ -177,9 +178,31 @@ IMGData::IMGData(const QString &fileName) : _fileName(fileName)
if (!_baseMap) if (!_baseMap)
_zooms.setMin(_zooms.min() - 2); _zooms.setMin(_zooms.min() - 2);
if (!_tileTree.Count()) return (_tileTree.Count() > 0);
}
IMGData::IMGData(const QString &fileName) : _fileName(fileName)
{
QFile file(fileName);
TileMap tileMap;
if (!file.open(QFile::ReadOnly)) {
_errorString = file.errorString();
return;
}
if (!readIMGHeader(file))
return;
if (!readFAT(file, tileMap)) {
_errorString = "Error reading FAT data";
qDeleteAll(tileMap);
return;
}
if (!createTileTree(tileMap)) {
_errorString = "No usable map tile found"; _errorString = "No usable map tile found";
else return;
}
_valid = true; _valid = true;
} }

View File

@ -18,8 +18,14 @@ public:
bool readBlock(QFile &file, int blockNum, char *data) const; bool readBlock(QFile &file, int blockNum, char *data) const;
private: private:
typedef QMap<QByteArray, VectorTile*> TileMap;
qint64 read(QFile &file, char *data, qint64 maxSize) const; qint64 read(QFile &file, char *data, qint64 maxSize) const;
template<class T> bool readValue(QFile &file, T &val) const; template<class T> bool readValue(QFile &file, T &val) const;
bool readSubFileBlocks(QFile &file, quint64 offset, SubFile *subFile);
bool readFAT(QFile &file, TileMap &tileMap);
bool readIMGHeader(QFile &file);
bool createTileTree(const TileMap &tileMap);
QString _fileName; QString _fileName;
quint8 _key; quint8 _key;