Skip to content

Commit

Permalink
Reduce the number of file opens for IMG files
Browse files Browse the repository at this point in the history
  • Loading branch information
tumic0 committed Nov 29, 2024
1 parent 9ac10e2 commit f620bbc
Show file tree
Hide file tree
Showing 16 changed files with 166 additions and 140 deletions.
2 changes: 1 addition & 1 deletion src/map/IMG/gmapdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ bool GMAPData::loadTile(const QDir &dir)
}
}

if (!tile->init()) {
if (!tile->init(0)) {
qWarning("%s: Invalid map tile", qPrintable(dir.path()));
delete tile;
return false;
Expand Down
42 changes: 21 additions & 21 deletions src/map/IMG/imgdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ static SubFile::Type tileType(const char str[3])
return SubFile::Unknown;
}

bool IMGData::readSubFileBlocks(QFile &file, quint64 offset, SubFile *subFile)
bool IMGData::readSubFileBlocks(QFile *file, quint64 offset, SubFile *subFile)
{
quint16 block;

if (!file.seek(offset + 0x20))
if (!file->seek(offset + 0x20))
return false;
for (int i = 0; i < 240; i++) {
if (!readValue(file, block))
Expand All @@ -46,11 +46,11 @@ bool IMGData::readSubFileBlocks(QFile &file, quint64 offset, SubFile *subFile)
return true;
}

bool IMGData::readIMGHeader(QFile &file)
bool IMGData::readIMGHeader(QFile *file)
{
char signature[7], identifier[7];
if (!(file.read((char*)&_key, 1) && file.seek(0x10)
&& read(file, signature, sizeof(signature)) && file.seek(0x41)
if (!(file->read((char*)&_key, 1) && file->seek(0x10)
&& read(file, signature, sizeof(signature)) && file->seek(0x41)
&& read(file, identifier, sizeof(identifier)))
|| memcmp(signature, "DSKIMG", sizeof(signature))
|| memcmp(identifier, "GARMIN", sizeof(identifier))) {
Expand All @@ -60,8 +60,8 @@ bool IMGData::readIMGHeader(QFile &file)

char d1[20], d2[31];
quint8 e1, e2;
if (!(file.seek(0x49) && read(file, d1, sizeof(d1)) && file.seek(0x61)
&& readValue(file, e1) && readValue(file, e2) && file.seek(0x65)
if (!(file->seek(0x49) && read(file, d1, sizeof(d1)) && file->seek(0x61)
&& readValue(file, e1) && readValue(file, e2) && file->seek(0x65)
&& read(file, d2, sizeof(d2)))) {
_errorString = "Error reading IMG header";
return false;
Expand All @@ -74,15 +74,15 @@ bool IMGData::readIMGHeader(QFile &file)
return true;
}

bool IMGData::readFAT(QFile &file, TileMap &tileMap)
bool IMGData::readFAT(QFile *file, TileMap &tileMap)
{
QByteArray typFile;
quint8 flag;
quint64 offset = 0x200;

// Skip unused FAT blocks if any
while (true) {
if (!(file.seek(offset) && readValue(file, flag)))
if (!(file->seek(offset) && readValue(file, flag)))
return false;
if (flag)
break;
Expand All @@ -93,14 +93,14 @@ bool IMGData::readFAT(QFile &file, TileMap &tileMap)
char name[8], type[3];
quint32 size;
quint16 part;
if (!(file.seek(offset + 12) && readValue(file, size)))
if (!(file->seek(offset + 12) && readValue(file, size)))
return false;
offset += 512;
int cnt = (size - offset) / 512;

// Read FAT blocks describing the IMG sub-files
for (int i = 0; i < cnt; i++) {
if (!(file.seek(offset) && readValue(file, flag)
if (!(file->seek(offset) && readValue(file, flag)
&& read(file, name, sizeof(name))
&& read(file, type, sizeof(type)) && readValue(file, size)
&& readValue(file, part)))
Expand Down Expand Up @@ -140,13 +140,13 @@ bool IMGData::readFAT(QFile &file, TileMap &tileMap)
return true;
}

bool IMGData::createTileTree(const TileMap &tileMap)
bool IMGData::createTileTree(QFile *file, const TileMap &tileMap)
{
for (TileMap::const_iterator it = tileMap.constBegin();
it != tileMap.constEnd(); ++it) {
VectorTile *tile = it.value();

if (!tile->init()) {
if (!tile->init(file)) {
qWarning("%s: %s: Invalid map tile", qPrintable(_fileName),
qPrintable(it.key()));
delete tile;
Expand Down Expand Up @@ -177,14 +177,14 @@ IMGData::IMGData(const QString &fileName) : MapData(fileName)
return;
}

if (!readIMGHeader(file))
if (!readIMGHeader(&file))
return;
if (!readFAT(file, tileMap)) {
if (!readFAT(&file, tileMap)) {
_errorString = "Error reading FAT data";
qDeleteAll(tileMap);
return;
}
if (!createTileTree(tileMap)) {
if (!createTileTree(&file, tileMap)) {
_errorString = "No usable map tile found";
return;
}
Expand All @@ -194,16 +194,16 @@ IMGData::IMGData(const QString &fileName) : MapData(fileName)
_valid = true;
}

qint64 IMGData::read(QFile &file, char *data, qint64 maxSize) const
qint64 IMGData::read(QFile *file, char *data, qint64 maxSize) const
{
qint64 ret = file.read(data, maxSize);
qint64 ret = file->read(data, maxSize);
if (_key)
for (int i = 0; i < ret; i++)
data[i] ^= _key;
return ret;
}

template<class T> bool IMGData::readValue(QFile &file, T &val) const
template<class T> bool IMGData::readValue(QFile *file, T &val) const
{
T data;

Expand All @@ -215,9 +215,9 @@ template<class T> bool IMGData::readValue(QFile &file, T &val) const
return true;
}

bool IMGData::readBlock(QFile &file, int blockNum, char *data) const
bool IMGData::readBlock(QFile *file, int blockNum, char *data) const
{
if (!file.seek((quint64)blockNum << _blockBits))
if (!file->seek((quint64)blockNum << _blockBits))
return false;
if (read(file, data, 1ULL<<_blockBits) < (qint64)(1ULL<<_blockBits))
return false;
Expand Down
14 changes: 7 additions & 7 deletions src/map/IMG/imgdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ class IMGData : public MapData
IMGData(const QString &fileName);

unsigned blockBits() const {return _blockBits;}
bool readBlock(QFile &file, int blockNum, char *data) const;
bool readBlock(QFile *file, int blockNum, char *data) const;

private:
typedef QMap<QByteArray, VectorTile*> TileMap;

qint64 read(QFile &file, char *data, qint64 maxSize) 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);
qint64 read(QFile *file, char *data, qint64 maxSize) 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(QFile *file, const TileMap &tileMap);

quint8 _key;
unsigned _blockBits;
Expand Down
30 changes: 17 additions & 13 deletions src/map/IMG/mapdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,24 @@ using namespace IMG;
bool MapData::polyCb(VectorTile *tile, void *context)
{
PolyCTX *ctx = (PolyCTX*)context;
tile->polys(ctx->rect, ctx->zoom, ctx->polygons, ctx->lines,
tile->polys(ctx->file, ctx->rect, ctx->zoom, ctx->polygons, ctx->lines,
ctx->cache, ctx->lock);
return true;
}

bool MapData::pointCb(VectorTile *tile, void *context)
{
PointCTX *ctx = (PointCTX*)context;
tile->points(ctx->rect, ctx->zoom, ctx->points, ctx->cache, ctx->lock);
tile->points(ctx->file, ctx->rect, ctx->zoom, ctx->points, ctx->cache,
ctx->lock);
return true;
}

bool MapData::elevationCb(VectorTile *tile, void *context)
{
ElevationCTX *ctx = (ElevationCTX*)context;
tile->elevations(ctx->rect, ctx->zoom, ctx->elevations, ctx->cache, ctx->lock);
tile->elevations(ctx->file, ctx->rect, ctx->zoom, ctx->elevations,
ctx->cache, ctx->lock);
return true;
}

Expand All @@ -50,10 +52,10 @@ MapData::~MapData()
delete _style;
}

void MapData::polys(const RectC &rect, int bits, QList<Poly> *polygons,
QList<Poly> *lines)
void MapData::polys(QFile *file, const RectC &rect, int bits,
QList<Poly> *polygons, QList<Poly> *lines)
{
PolyCTX ctx(rect, zoom(bits), polygons, lines, &_polyCache, &_lock);
PolyCTX ctx(file, rect, zoom(bits), polygons, lines, &_polyCache, &_lock);
double min[2], max[2];

min[0] = rect.left();
Expand All @@ -64,9 +66,10 @@ void MapData::polys(const RectC &rect, int bits, QList<Poly> *polygons,
_tileTree.Search(min, max, polyCb, &ctx);
}

void MapData::points(const RectC &rect, int bits, QList<Point> *points)
void MapData::points(QFile *file, const RectC &rect, int bits,
QList<Point> *points)
{
PointCTX ctx(rect, zoom(bits), points, &_pointCache, &_lock);
PointCTX ctx(file, rect, zoom(bits), points, &_pointCache, &_lock);
double min[2], max[2];

min[0] = rect.left();
Expand All @@ -77,9 +80,10 @@ void MapData::points(const RectC &rect, int bits, QList<Point> *points)
_tileTree.Search(min, max, pointCb, &ctx);
}

void MapData::elevations(const RectC &rect, int bits, QList<Elevation> *elevations)
void MapData::elevations(QFile *file, const RectC &rect, int bits,
QList<Elevation> *elevations)
{
ElevationCTX ctx(rect, zoom(bits), elevations, &_demCache, &_demLock);
ElevationCTX ctx(file, rect, zoom(bits), elevations, &_demCache, &_demLock);
double min[2], max[2];

min[0] = rect.left();
Expand All @@ -95,14 +99,14 @@ void MapData::load(qreal ratio)
Q_ASSERT(!_style);

if (_typ)
_style = new Style(ratio, _typ);
_style = new Style(0, ratio, _typ);
else {
QString typFile(ProgramPaths::typFile());
if (QFileInfo::exists(typFile)) {
SubFile typ(&typFile);
_style = new Style(ratio, &typ);
_style = new Style(0, ratio, &typ);
} else
_style = new Style(ratio);
_style = new Style(0, ratio);
}
}

Expand Down
28 changes: 17 additions & 11 deletions src/map/IMG/mapdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <QPointF>
#include <QCache>
#include <QMutex>
#include <QFile>
#include <QDebug>
#include "common/rectc.h"
#include "common/rtree.h"
Expand Down Expand Up @@ -77,10 +78,11 @@ class MapData
const RectC &bounds() const {return _bounds;}
const Range &zooms() const {return _zoomLevels;}
const Style *style() const {return _style;}
void polys(const RectC &rect, int bits, QList<Poly> *polygons,
void polys(QFile *file, const RectC &rect, int bits, QList<Poly> *polygons,
QList<Poly> *lines);
void points(const RectC &rect, int bits, QList<Point> *points);
void elevations(const RectC &rect, int bits, QList<Elevation> *elevations);
void points(QFile *file, const RectC &rect, int bits, QList<Point> *points);
void elevations(QFile *file, const RectC &rect, int bits,
QList<Elevation> *elevations);

void load(qreal ratio);
void clear();
Expand Down Expand Up @@ -122,12 +124,13 @@ class MapData

struct PolyCTX
{
PolyCTX(const RectC &rect, const Zoom &zoom,
PolyCTX(QFile *file, const RectC &rect, const Zoom &zoom,
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
PolyCache *cache, QMutex *lock)
: rect(rect), zoom(zoom), polygons(polygons), lines(lines),
cache(cache), lock(lock) {}
: file(file), rect(rect), zoom(zoom), polygons(polygons),
lines(lines), cache(cache), lock(lock) {}

QFile *file;
const RectC &rect;
const Zoom &zoom;
QList<MapData::Poly> *polygons;
Expand All @@ -138,10 +141,12 @@ class MapData

struct PointCTX
{
PointCTX(const RectC &rect, const Zoom &zoom,
PointCTX(QFile *file, const RectC &rect, const Zoom &zoom,
QList<MapData::Point> *points, PointCache *cache, QMutex *lock)
: rect(rect), zoom(zoom), points(points), cache(cache), lock(lock) {}
: file(file), rect(rect), zoom(zoom), points(points), cache(cache),
lock(lock) {}

QFile *file;
const RectC &rect;
const Zoom &zoom;
QList<MapData::Point> *points;
Expand All @@ -151,11 +156,12 @@ class MapData

struct ElevationCTX
{
ElevationCTX(const RectC &rect, const Zoom &zoom,
ElevationCTX(QFile *file, const RectC &rect, const Zoom &zoom,
QList<Elevation> *elevations, ElevationCache *cache, QMutex *lock)
: rect(rect), zoom(zoom), elevations(elevations), cache(cache),
lock(lock) {}
: file(file), rect(rect), zoom(zoom), elevations(elevations),
cache(cache), lock(lock) {}

QFile *file;
const RectC &rect;
const Zoom &zoom;
QList<Elevation> *elevations;
Expand Down
13 changes: 9 additions & 4 deletions src/map/IMG/rastertile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ void RasterTile::drawPolygons(QPainter *painter,
bool insert = false;
SubFile::Handle *hdl = hc.object(poly.raster.lbl());
if (!hdl) {
hdl = new SubFile::Handle(poly.raster.lbl());
hdl = new SubFile::Handle(_file, poly.raster.lbl());
insert = true;
}
QPixmap pm(poly.raster.lbl()->image(*hdl, poly.raster.id()));
Expand Down Expand Up @@ -443,11 +443,16 @@ void RasterTile::fetchData(QList<MapData::Poly> &polygons,
{
QPoint ttl(_rect.topLeft());

if (dynamic_cast<IMGData*>(_data)) {
_file = new QFile(_data->fileName());
_file->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
}

QRectF polyRect(ttl, QPointF(ttl.x() + _rect.width(), ttl.y()
+ _rect.height()));
RectD polyRectD(_transform.img2proj(polyRect.topLeft()),
_transform.img2proj(polyRect.bottomRight()));
_data->polys(polyRectD.toRectC(_proj, 20), _zoom,
_data->polys(_file, polyRectD.toRectC(_proj, 20), _zoom,
&polygons, _vectors ? &lines : 0);

if (_vectors) {
Expand All @@ -456,7 +461,7 @@ void RasterTile::fetchData(QList<MapData::Poly> &polygons,
+ TEXT_EXTENT));
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
_transform.img2proj(pointRect.bottomRight()));
_data->points(pointRectD.toRectC(_proj, 20), _zoom, &points);
_data->points(_file, pointRectD.toRectC(_proj, 20), _zoom, &points);
}
}

Expand All @@ -481,7 +486,7 @@ MatrixD RasterTile::elevation(int extend) const
// Extra margin for always including the next DEM tile on the map tile
// edges (the DEM tile resolution is usally 0.5-15% of the map tile)
double factor = 6 - (_zoom - 24) * 1.7;
_data->elevations(rect.adjusted(0, 0, rect.width() / factor,
_data->elevations(_file, rect.adjusted(0, 0, rect.width() / factor,
-rect.height() / factor), _zoom, &tiles);

DEMTree tree(tiles);
Expand Down
4 changes: 3 additions & 1 deletion src/map/IMG/rastertile.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ class RasterTile
bool hillShading, bool rasters, bool vectors)
: _proj(proj), _transform(transform), _data(data), _zoom(zoom),
_rect(rect), _ratio(ratio), _key(key), _hillShading(hillShading),
_rasters(rasters), _vectors(vectors) {}
_rasters(rasters), _vectors(vectors), _file(0) {}
~RasterTile() {delete _file;}

const QString &key() const {return _key;}
QPoint xy() const {return _rect.topLeft();}
Expand Down Expand Up @@ -88,6 +89,7 @@ class RasterTile
QPixmap _pixmap;
bool _hillShading;
bool _rasters, _vectors;
QFile *_file;
};

}
Expand Down
Loading

0 comments on commit f620bbc

Please sign in to comment.