1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 11:45:53 +01:00

Improved IMG map memory management

This commit is contained in:
Martin Tůma 2019-07-04 18:18:03 +02:00
parent b4cc88446a
commit 53e960fabe
7 changed files with 103 additions and 57 deletions

View File

@ -5,6 +5,8 @@
#include "img.h"
#define CACHE_SIZE 8388608 /* 8MB */
#define CHECK(condition) \
if (!(condition)) { \
_errorString = "Invalid/corrupted IMG file"; \
@ -25,7 +27,8 @@ struct CTX
QList<IMG::Point> *points;
};
IMG::IMG(const QString &fileName) : _file(fileName), _valid(false)
IMG::IMG(const QString &fileName)
: _file(fileName), _typ(0), _style(0), _valid(false)
{
if (!_file.open(QFile::ReadOnly)) {
_errorString = _file.errorString();
@ -50,6 +53,7 @@ IMG::IMG(const QString &fileName) : _file(fileName), _valid(false)
QByteArray nba(QByteArray(d1, sizeof(d1)) + QByteArray(d2, sizeof(d2)));
_name = QString(nba).trimmed();
_blockSize = 1 << (e1 + e2);
_blockCache.setMaxCost(CACHE_SIZE / _blockSize);
// Read the FAT table
quint8 flag;
@ -72,7 +76,7 @@ IMG::IMG(const QString &fileName) : _file(fileName), _valid(false)
QMap<QString, VectorTile*> tileMap;
QMap<QString, SubFile*> TYPMap;
QString typFile;
// Read FAT blocks describing the IMG sub-files
for (int i = 0; i < cnt; i++) {
@ -108,14 +112,15 @@ IMG::IMG(const QString &fileName) : _file(fileName), _valid(false)
file->addBlock(block);
}
} else if (tt == SubFile::TYP) {
SubFile *typ;
QMap<QString, SubFile*>::iterator it = TYPMap.find(fn);
if (it == TYPMap.end()) {
typ = new SubFile(this, size);
TYPMap.insert(fn, typ);
} else
typ = *it;
SubFile *typ = 0;
if (typFile.isNull()) {
_typ = new SubFile(this, size);
typ = _typ;
typFile = fn;
} else if (fn == typFile)
typ = _typ;
if (typ) {
_file.seek(offset + 0x20);
for (int i = 0; i < 240; i++) {
CHECK(readValue(block));
@ -124,6 +129,7 @@ IMG::IMG(const QString &fileName) : _file(fileName), _valid(false)
typ->addBlock(block);
}
}
}
offset += 512;
}
@ -143,22 +149,6 @@ IMG::IMG(const QString &fileName) : _file(fileName), _valid(false)
_bounds |= (*it)->bounds();
}
// Read TYP file if any
if (!TYPMap.isEmpty()) {
if (TYPMap.size() > 1)
qWarning("%s: Multiple TYP files, using %s",
qPrintable(_file.fileName()), qPrintable(TYPMap.keys().first()));
SubFile *typ = TYPMap.values().first();
_style = Style(typ);
qDeleteAll(TYPMap);
} else {
QFile typFile(ProgramPaths::typFile());
if (typFile.exists()) {
SubFile typ(&typFile);
_style = Style(&typ);
}
}
_valid = true;
}
@ -167,6 +157,37 @@ IMG::~IMG()
TileTree::Iterator it;
for (_tileTree.GetFirst(it); !_tileTree.IsNull(it); _tileTree.GetNext(it))
delete _tileTree.GetAt(it);
delete _typ;
delete _style;
}
void IMG::load()
{
Q_ASSERT(!_style);
if (_typ && _typ->isValid())
_style = new Style(_typ);
else {
QFile typFile(ProgramPaths::typFile());
if (typFile.exists()) {
SubFile typ(&typFile);
_style = new Style(&typ);
} else
_style = new Style();
}
}
void IMG::clear()
{
TileTree::Iterator it;
for (_tileTree.GetFirst(it); !_tileTree.IsNull(it); _tileTree.GetNext(it))
_tileTree.GetAt(it)->clear();
delete _style;
_style = 0;
_blockCache.clear();
}
static bool cb(VectorTile *tile, void *context)

View File

@ -48,13 +48,16 @@ public:
IMG(const QString &fileName);
~IMG();
void load();
void clear();
QString fileName() const {return _file.fileName();}
const QString &name() const {return _name;}
const RectC &bounds() const {return _bounds;}
void objects(const RectC &rect, int bits, QList<Poly> *polygons,
QList<Poly> *lines, QList<Point> *points);
const Style &style() const {return _style;}
const Style *style() const {return _style;}
bool isValid() const {return _valid;}
const QString &errorString() const {return _errorString;}
@ -75,11 +78,11 @@ private:
int _blockSize;
QCache<int, QByteArray> _blockCache;
TileTree _tileTree;
QString _name;
RectC _bounds;
Style _style;
TileTree _tileTree;
SubFile *_typ;
Style *_style;
bool _valid;
QString _errorString;

View File

@ -40,18 +40,7 @@ static void unlock(quint8 *dst, const quint8 *src, quint32 size, quint32 key)
TREFile::~TREFile()
{
SubDivTree::Iterator jt;
for (QMap<int, SubDivTree*>::iterator it = _subdivs.begin();
it != _subdivs.end(); ++it) {
SubDivTree *tree = *it;
for (tree->GetFirst(jt); !tree->IsNull(jt); tree->GetNext(jt))
delete tree->GetAt(jt);
}
for (QMap<int, SubDivTree*>::iterator it = _subdivs.begin();
it != _subdivs.end(); ++it)
delete *it;
clear();
}
bool TREFile::init()
@ -69,7 +58,7 @@ bool TREFile::init()
return true;
}
bool TREFile::init2()
bool TREFile::load()
{
Handle hdl;
quint8 locked;
@ -202,9 +191,26 @@ bool TREFile::init2()
return true;
}
void TREFile::clear()
{
SubDivTree::Iterator jt;
for (QMap<int, SubDivTree*>::iterator it = _subdivs.begin();
it != _subdivs.end(); ++it) {
SubDivTree *tree = *it;
for (tree->GetFirst(jt); !tree->IsNull(jt); tree->GetNext(jt))
delete tree->GetAt(jt);
}
qDeleteAll(_subdivs);
_subdivs.clear();
_levels.clear();
}
int TREFile::level(int bits)
{
if (_levels.isEmpty() && !init2())
if (_levels.isEmpty() && !load())
return -1;
int l = _levels.first();

View File

@ -17,6 +17,7 @@ public:
~TREFile();
bool init();
void clear();
const RectC &bounds() const {return _bounds;}
QList<SubDiv*> subdivs(const RectC &rect, int bits);
@ -24,7 +25,7 @@ public:
private:
typedef RTree<SubDiv*, double, 2> SubDivTree;
bool init2();
bool load();
int level(int bits);
bool parsePoly(Handle hdl, quint32 pos, const QMap<int, int> &level2bits,
QMap<quint32, int> &map);

View File

@ -14,6 +14,7 @@ public:
~VectorTile() {delete _tre; delete _rgn; delete _lbl; delete _net;}
bool init();
void clear() {_tre->clear();}
const RectC &bounds() const {return _tre->bounds();}

View File

@ -174,6 +174,16 @@ IMGMap::IMGMap(const QString &fileName, QObject *parent)
_valid = true;
}
void IMGMap::load()
{
_img.load();
}
void IMGMap::unload()
{
_img.clear();
}
QRectF IMGMap::bounds()
{
RectD prect(_img.bounds(), _projection);
@ -248,12 +258,12 @@ Coordinates IMGMap::xy2ll(const QPointF &p)
void IMGMap::drawPolygons(QPainter *painter, const QList<IMG::Poly> &polygons)
{
for (int n = 0; n < _img.style().drawOrder().size(); n++) {
for (int n = 0; n < _img.style()->drawOrder().size(); n++) {
for (int i = 0; i < polygons.size(); i++) {
const IMG::Poly &poly = polygons.at(i);
if (poly.type != _img.style().drawOrder().at(n))
if (poly.type != _img.style()->drawOrder().at(n))
continue;
const Style::Polygon &style = _img.style().polygon(poly.type);
const Style::Polygon &style = _img.style()->polygon(poly.type);
painter->setPen(style.pen());
painter->setBrush(style.brush());
@ -268,7 +278,7 @@ void IMGMap::drawLines(QPainter *painter, const QList<IMG::Poly> &lines)
for (int i = 0; i < lines.size(); i++) {
const IMG::Poly &poly = lines.at(i);
const Style::Line &style = _img.style().line(poly.type);
const Style::Line &style = _img.style()->line(poly.type);
if (style.background() == Qt::NoPen)
continue;
@ -279,7 +289,7 @@ void IMGMap::drawLines(QPainter *painter, const QList<IMG::Poly> &lines)
for (int i = 0; i < lines.size(); i++) {
const IMG::Poly &poly = lines.at(i);
const Style::Line &style = _img.style().line(poly.type);
const Style::Line &style = _img.style()->line(poly.type);
if (!style.img().isNull())
BitmapLine::draw(painter, poly.points, style.img());
@ -326,7 +336,7 @@ void IMGMap::processLines(QList<IMG::Poly> &lines, const QPoint &tile,
if (_zoom >= LINE_TEXT_MIN_ZOOM) {
for (int i = 0; i < lines.size(); i++) {
IMG::Poly &poly = lines[i];
const Style::Line &style = _img.style().line(poly.type);
const Style::Line &style = _img.style()->line(poly.type);
if (style.img().isNull() && style.foreground() == Qt::NoPen)
continue;
@ -415,7 +425,7 @@ void IMGMap::processPoints(QList<IMG::Point> &points,
for (int i = 0; i < points.size(); i++) {
IMG::Point &point = points[i];
const Style::Point &style = _img.style().point(point.type);
const Style::Point &style = _img.style()->point(point.type);
if (point.poi && _zoom < minPOIZoom(Style::poiClass(point.type)))
continue;

View File

@ -34,6 +34,9 @@ public:
void setProjection(const Projection &projection);
void load();
void unload();
bool isValid() const {return _valid;}
QString errorString() const {return _errorString;}
@ -56,6 +59,7 @@ private:
Range _zooms;
Projection _projection;
Transform _transform;
bool _valid;
QString _errorString;
};