mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-30 22:51:16 +01:00
Do not cache the raster data
This commit is contained in:
parent
02c3682758
commit
33f2002a52
@ -12,7 +12,7 @@ public:
|
||||
GMAP(const QString &fileName);
|
||||
~GMAP();
|
||||
|
||||
QString fileName() const {return _fileName;}
|
||||
const QString &fileName() const {return _fileName;}
|
||||
|
||||
static bool isGMAP(const QString &path);
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <QMap>
|
||||
#include <QtEndian>
|
||||
#include <QFile>
|
||||
#include "vectortile.h"
|
||||
#include "img.h"
|
||||
|
||||
@ -24,7 +25,7 @@ static SubFile::Type tileType(const char str[3])
|
||||
return SubFile::Unknown;
|
||||
}
|
||||
|
||||
IMG::IMG(const QString &fileName) : _file(fileName)
|
||||
IMG::IMG(const QString &fileName) : _fileName(fileName)
|
||||
{
|
||||
#define CHECK(condition) \
|
||||
if (!(condition)) { \
|
||||
@ -33,19 +34,20 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
||||
return; \
|
||||
}
|
||||
|
||||
QFile file(fileName);
|
||||
TileMap tileMap;
|
||||
QByteArray typFile;
|
||||
|
||||
if (!_file.open(QFile::ReadOnly)) {
|
||||
_errorString = _file.errorString();
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
_errorString = file.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
// Read IMG header
|
||||
char signature[7], identifier[7];
|
||||
_file.read((char*)&_key, 1) && _file.seek(0x10)
|
||||
&& read(signature, sizeof(signature)) && _file.seek(0x41)
|
||||
&& read(identifier, sizeof(identifier));
|
||||
file.read((char*)&_key, 1) && file.seek(0x10)
|
||||
&& read(file, signature, sizeof(signature)) && file.seek(0x41)
|
||||
&& read(file, identifier, sizeof(identifier));
|
||||
if (memcmp(signature, "DSKIMG", sizeof(signature))
|
||||
|| memcmp(identifier, "GARMIN", sizeof(identifier))) {
|
||||
_errorString = "Not a Garmin IMG file";
|
||||
@ -53,9 +55,9 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
||||
}
|
||||
char d1[20], d2[31];
|
||||
quint8 e1, e2;
|
||||
CHECK(_file.seek(0x49) && read(d1, sizeof(d1)) && _file.seek(0x61)
|
||||
&& readValue(e1) && readValue(e2) && _file.seek(0x65)
|
||||
&& read(d2, sizeof(d2)));
|
||||
CHECK(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)));
|
||||
|
||||
QByteArray nba(QByteArray(d1, sizeof(d1)) + QByteArray(d2, sizeof(d2)));
|
||||
_name = QString::fromLatin1(nba.constData(), nba.size()-1).trimmed();
|
||||
@ -66,7 +68,7 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
||||
quint64 offset = 0x200;
|
||||
// Skip unused FAT blocks if any
|
||||
while (true) {
|
||||
CHECK(_file.seek(offset) && readValue(flag));
|
||||
CHECK(file.seek(offset) && readValue(file, flag));
|
||||
if (flag)
|
||||
break;
|
||||
offset += 512;
|
||||
@ -76,15 +78,17 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
||||
char name[8], type[3];
|
||||
quint32 size;
|
||||
quint16 part;
|
||||
CHECK(_file.seek(offset + 12) && readValue(size));
|
||||
CHECK(file.seek(offset + 12) && readValue(file, size));
|
||||
offset += 512;
|
||||
int cnt = (size - offset) / 512;
|
||||
|
||||
// Read FAT blocks describing the IMG sub-files
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
quint16 block;
|
||||
CHECK(_file.seek(offset) && readValue(flag) && read(name, sizeof(name))
|
||||
&& read(type, sizeof(type)) && readValue(size) && readValue(part));
|
||||
CHECK(file.seek(offset) && readValue(file, flag)
|
||||
&& read(file, name, sizeof(name))
|
||||
&& read(file, type, sizeof(type)) && readValue(file, size)
|
||||
&& readValue(file, part));
|
||||
SubFile::Type tt = tileType(type);
|
||||
|
||||
QByteArray fn(name, sizeof(name));
|
||||
@ -97,16 +101,16 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
||||
} else
|
||||
tile = *it;
|
||||
|
||||
SubFile *file = part ? tile->file(tt)
|
||||
SubFile *subFile = part ? tile->file(tt)
|
||||
: tile->addFile(this, tt);
|
||||
CHECK(file);
|
||||
CHECK(subFile);
|
||||
|
||||
_file.seek(offset + 0x20);
|
||||
file.seek(offset + 0x20);
|
||||
for (int i = 0; i < 240; i++) {
|
||||
CHECK(readValue(block));
|
||||
CHECK(readValue(file, block));
|
||||
if (block == 0xFFFF)
|
||||
break;
|
||||
file->addBlock(block);
|
||||
subFile->addBlock(block);
|
||||
}
|
||||
} else if (tt == SubFile::TYP) {
|
||||
SubFile *typ = 0;
|
||||
@ -118,9 +122,9 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
||||
typ = _typ;
|
||||
|
||||
if (typ) {
|
||||
_file.seek(offset + 0x20);
|
||||
file.seek(offset + 0x20);
|
||||
for (int i = 0; i < 240; i++) {
|
||||
CHECK(readValue(block));
|
||||
CHECK(readValue(file, block));
|
||||
if (block == 0xFFFF)
|
||||
break;
|
||||
typ->addBlock(block);
|
||||
@ -138,7 +142,7 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
||||
VectorTile *tile = it.value();
|
||||
|
||||
if (!tile->init()) {
|
||||
qWarning("%s: %s: Invalid map tile", qPrintable(_file.fileName()),
|
||||
qWarning("%s: %s: Invalid map tile", qPrintable(file.fileName()),
|
||||
qPrintable(it.key()));
|
||||
delete tile;
|
||||
continue;
|
||||
@ -178,20 +182,20 @@ IMG::IMG(const QString &fileName) : _file(fileName)
|
||||
_valid = true;
|
||||
}
|
||||
|
||||
qint64 IMG::read(char *data, qint64 maxSize)
|
||||
qint64 IMG::read(QFile &file, char *data, qint64 maxSize)
|
||||
{
|
||||
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 IMG::readValue(T &val)
|
||||
template<class T> bool IMG::readValue(QFile &file, T &val)
|
||||
{
|
||||
T data;
|
||||
|
||||
if (read((char*)&data, sizeof(T)) < (qint64)sizeof(T))
|
||||
if (read(file, (char*)&data, sizeof(T)) < (qint64)sizeof(T))
|
||||
return false;
|
||||
|
||||
val = qFromLittleEndian(data);
|
||||
@ -199,11 +203,11 @@ template<class T> bool IMG::readValue(T &val)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IMG::readBlock(int blockNum, char *data)
|
||||
bool IMG::readBlock(QFile &file, int blockNum, char *data)
|
||||
{
|
||||
if (!_file.seek((quint64)blockNum << _blockBits))
|
||||
if (!file.seek((quint64)blockNum << _blockBits))
|
||||
return false;
|
||||
if (read(data, 1ULL<<_blockBits) < (qint64)(1ULL<<_blockBits))
|
||||
if (read(file, data, 1ULL<<_blockBits) < (qint64)(1ULL<<_blockBits))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -1,25 +1,26 @@
|
||||
#ifndef IMG_H
|
||||
#define IMG_H
|
||||
|
||||
#include <QFile>
|
||||
#include "mapdata.h"
|
||||
|
||||
class QFile;
|
||||
|
||||
class IMG : public MapData
|
||||
{
|
||||
public:
|
||||
IMG(const QString &fileName);
|
||||
|
||||
QString fileName() const {return _file.fileName();}
|
||||
const QString &fileName() const {return _fileName;}
|
||||
|
||||
private:
|
||||
friend class SubFile;
|
||||
|
||||
unsigned blockBits() const {return _blockBits;}
|
||||
bool readBlock(int blockNum, char *data);
|
||||
qint64 read(char *data, qint64 maxSize);
|
||||
template<class T> bool readValue(T &val);
|
||||
bool readBlock(QFile &file, int blockNum, char *data);
|
||||
qint64 read(QFile &file, char *data, qint64 maxSize);
|
||||
template<class T> bool readValue(QFile &file, T &val);
|
||||
|
||||
QFile _file;
|
||||
QString _fileName;
|
||||
quint8 _key;
|
||||
unsigned _blockBits;
|
||||
};
|
||||
|
@ -94,20 +94,23 @@ bool LBLFile::load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl)
|
||||
}
|
||||
|
||||
if (hdrLen >= 0x19A) {
|
||||
quint32 size, flags;
|
||||
if (!(seek(hdl, _gmpOffset + 0x184) && readUInt32(hdl, _imgOffsetsOffset)
|
||||
&& readUInt32(hdl, size) && readUInt16(hdl, _imgOffsetsRecordSize)
|
||||
quint32 offset, recordSize, size, flags;
|
||||
if (!(seek(hdl, _gmpOffset + 0x184) && readUInt32(hdl, offset)
|
||||
&& readUInt32(hdl, size) && readUInt16(hdl, recordSize)
|
||||
&& readUInt32(hdl, flags) && readUInt32(hdl, _imgOffset)
|
||||
&& readUInt32(hdl, _imgSize)))
|
||||
return false;
|
||||
_imgOffsetsCount = size ? size / _imgOffsetsRecordSize : 0;
|
||||
quint32 count = size ? size / recordSize : 0;
|
||||
|
||||
quint32 maxId = _imgOffsetsCount - 1;
|
||||
quint32 maxId = count - 1;
|
||||
_imgOffsetIdSize = 0;
|
||||
do {
|
||||
_imgOffsetIdSize++;
|
||||
maxId = maxId >> 8;
|
||||
} while (maxId != 0);
|
||||
|
||||
if (!loadFiles(hdl, count, offset, recordSize))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_encoding == 11) {
|
||||
@ -301,31 +304,43 @@ Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize) con
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray LBLFile::readImage(Handle &hdl, quint32 id) const
|
||||
bool LBLFile::loadFiles(Handle &hdl, quint32 count, quint32 offset,
|
||||
quint32 recordSize)
|
||||
{
|
||||
quint32 offset, nextOffset, size;
|
||||
_rasters.resize(count);
|
||||
|
||||
if (id >= _imgOffsetsCount)
|
||||
return QByteArray();
|
||||
for (quint32 i = 0; i < count; i++) {
|
||||
quint32 currentOffset, nextOffset, size;
|
||||
|
||||
if (!(seek(hdl, _imgOffsetsOffset + id * _imgOffsetsRecordSize)
|
||||
&& readVUInt32(hdl, _imgOffsetsRecordSize, offset)))
|
||||
return QByteArray();
|
||||
if (id == _imgOffsetsCount - 1)
|
||||
if (!(seek(hdl, offset + i * recordSize)
|
||||
&& readVUInt32(hdl, recordSize, currentOffset)))
|
||||
return false;
|
||||
if (i == count - 1)
|
||||
nextOffset = _imgSize;
|
||||
else {
|
||||
if (!readVUInt32(hdl, _imgOffsetsRecordSize, nextOffset))
|
||||
return QByteArray();
|
||||
if (!readVUInt32(hdl, recordSize, nextOffset))
|
||||
return false;
|
||||
}
|
||||
size = nextOffset - offset;
|
||||
size = nextOffset - currentOffset;
|
||||
|
||||
if (!seek(hdl, _imgOffset + offset))
|
||||
return QByteArray();
|
||||
_rasters[i] = File(currentOffset, size);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QImage LBLFile::readImage(Handle &hdl, quint32 id) const
|
||||
{
|
||||
if (id >= (quint32)_rasters.size())
|
||||
return QImage();
|
||||
|
||||
if (!seek(hdl, _imgOffset + _rasters.at(id).offset))
|
||||
return QImage();
|
||||
QByteArray ba;
|
||||
ba.resize(size);
|
||||
for (quint32 i = 0; i < size; i++)
|
||||
ba.resize(_rasters.at(id).size);
|
||||
for (int i = 0; i < ba.size(); i++)
|
||||
if (!readUInt8(hdl, *(ba.data() + i)))
|
||||
return QByteArray();
|
||||
return QImage();
|
||||
|
||||
return ba;
|
||||
return QImage::fromData(ba);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef LBLFILE_H
|
||||
#define LBLFILE_H
|
||||
|
||||
#include <QImage>
|
||||
#include "common/textcodec.h"
|
||||
#include "subfile.h"
|
||||
#include "label.h"
|
||||
@ -13,16 +14,16 @@ class LBLFile : public SubFile
|
||||
public:
|
||||
LBLFile(IMG *img)
|
||||
: SubFile(img), _huffmanText(0), _table(0), _offset(0), _size(0),
|
||||
_poiOffset(0), _poiSize(0), _imgOffsetsCount(0), _imgOffsetIdSize(0),
|
||||
_poiMultiplier(0), _multiplier(0), _encoding(0) {}
|
||||
_poiOffset(0), _poiSize(0), _imgOffsetIdSize(0), _poiMultiplier(0),
|
||||
_multiplier(0), _encoding(0) {}
|
||||
LBLFile(const QString *path)
|
||||
: SubFile(path), _huffmanText(0), _table(0), _offset(0), _size(0),
|
||||
_poiOffset(0), _poiSize(0), _imgOffsetsCount(0), _imgOffsetIdSize(0),
|
||||
_poiMultiplier(0), _multiplier(0), _encoding(0) {}
|
||||
_poiOffset(0), _poiSize(0), _imgOffsetIdSize(0), _poiMultiplier(0),
|
||||
_multiplier(0), _encoding(0) {}
|
||||
LBLFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||
_huffmanText(0), _table(0), _offset(0), _size(0), _poiOffset(0),
|
||||
_poiSize(0), _imgOffsetsCount(0), _imgOffsetIdSize(0), _poiMultiplier(0),
|
||||
_multiplier(0), _encoding(0) {}
|
||||
_poiSize(0), _imgOffsetIdSize(0), _poiMultiplier(0), _multiplier(0),
|
||||
_encoding(0) {}
|
||||
~LBLFile();
|
||||
|
||||
bool load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl);
|
||||
@ -32,13 +33,23 @@ public:
|
||||
bool capitalize = true) const;
|
||||
|
||||
quint8 imageIdSize() const {return _imgOffsetIdSize;}
|
||||
QByteArray readImage(Handle &hdl, quint32 id) const;
|
||||
QImage readImage(Handle &hdl, quint32 id) const;
|
||||
|
||||
private:
|
||||
struct File {
|
||||
File() : offset(0), size(0) {}
|
||||
File(quint32 offset, quint32 size) : offset(offset), size(size) {}
|
||||
|
||||
quint32 offset;
|
||||
quint32 size;
|
||||
};
|
||||
|
||||
Label str2label(const QVector<quint8> &str, bool capitalize) const;
|
||||
Label label6b(Handle &hdl, quint32 offset, bool capitalize) const;
|
||||
Label label8b(Handle &hdl, quint32 offset, bool capitalize) const;
|
||||
Label labelHuffman(Handle &hdl, quint32 offset, bool capitalize) const;
|
||||
bool loadFiles(Handle &hdl, quint32 count, quint32 offset,
|
||||
quint32 recordSize);
|
||||
|
||||
HuffmanText *_huffmanText;
|
||||
quint32 *_table;
|
||||
@ -47,15 +58,14 @@ private:
|
||||
quint32 _size;
|
||||
quint32 _poiOffset;
|
||||
quint32 _poiSize;
|
||||
quint32 _imgOffsetsOffset;
|
||||
quint32 _imgOffsetsCount;
|
||||
quint32 _imgOffsetsRecordSize;
|
||||
quint32 _imgOffset;
|
||||
quint32 _imgSize;
|
||||
quint8 _imgOffsetIdSize;
|
||||
quint8 _poiMultiplier;
|
||||
quint8 _multiplier;
|
||||
quint8 _encoding;
|
||||
|
||||
QVector<File> _rasters;
|
||||
};
|
||||
|
||||
#endif // LBLFILE_H
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
void load();
|
||||
void clear();
|
||||
|
||||
virtual QString fileName() const = 0;
|
||||
virtual const QString &fileName() const = 0;
|
||||
|
||||
bool isValid() const {return _valid;}
|
||||
QString errorString() const {return _errorString;}
|
||||
|
@ -2,34 +2,37 @@
|
||||
#define RASTER_H
|
||||
|
||||
#include <QRect>
|
||||
#include <QByteArray>
|
||||
#include <QDebug>
|
||||
#include "common/rectc.h"
|
||||
#include "common/garmin.h"
|
||||
|
||||
class LBLFile;
|
||||
|
||||
class Raster {
|
||||
public:
|
||||
Raster() {}
|
||||
Raster(const QByteArray &img, const QRect &rect) : _img(img), _rect(rect) {}
|
||||
Raster() : _lbl(0) {}
|
||||
Raster(const LBLFile *lbl, quint32 id, const QRect &rect)
|
||||
: _lbl(lbl), _id(id), _rect(rect) {}
|
||||
|
||||
const QByteArray &img() const {return _img;}
|
||||
const LBLFile *lbl() const {return _lbl;}
|
||||
quint32 id() const {return _id;}
|
||||
const RectC rect() const
|
||||
{
|
||||
return RectC(Coordinates(toWGS32(_rect.left()), toWGS32(_rect.top())),
|
||||
Coordinates(toWGS32(_rect.right()), toWGS32(_rect.bottom())));
|
||||
}
|
||||
bool isValid() const {return !_img.isNull();}
|
||||
bool isValid() const {return (_lbl != 0);}
|
||||
|
||||
private:
|
||||
QByteArray _img;
|
||||
const LBLFile *_lbl;
|
||||
quint32 _id;
|
||||
QRect _rect;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
inline QDebug operator<<(QDebug dbg, const Raster &raster)
|
||||
{
|
||||
dbg.nospace() << "Raster(" << raster.img().size() << ", " << raster.rect()
|
||||
<< ")";
|
||||
dbg.nospace() << "Raster(" << raster.rect() << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "textpointitem.h"
|
||||
#include "bitmapline.h"
|
||||
#include "style.h"
|
||||
#include "lblfile.h"
|
||||
#include "rastertile.h"
|
||||
|
||||
|
||||
@ -224,8 +225,11 @@ void RasterTile::drawPolygons(QPainter *painter)
|
||||
QPointF br(_map->ll2xy(r.bottomRight()));
|
||||
QSize size(QRectF(tl, br).toRect().size());
|
||||
|
||||
painter->drawImage(tl, QImage::fromData(poly.raster.img()).
|
||||
scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
SubFile::Handle hdl(poly.raster.lbl());
|
||||
QImage img(poly.raster.lbl()->readImage(hdl, poly.raster.id()));
|
||||
|
||||
painter->drawImage(tl, img.scaled(size, Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation));
|
||||
|
||||
//painter->setPen(Qt::blue);
|
||||
//painter->setBrush(Qt::NoBrush);
|
||||
|
@ -30,7 +30,7 @@ RGNFile::~RGNFile()
|
||||
}
|
||||
|
||||
bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
|
||||
MapData::Poly *poly, const LBLFile *lbl, Handle *lblHdl) const
|
||||
MapData::Poly *poly, const LBLFile *lbl) const
|
||||
{
|
||||
quint8 flags;
|
||||
quint32 rs;
|
||||
@ -67,8 +67,8 @@ bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
|
||||
&& readUInt32(hdl, bottom) && readUInt32(hdl, left)))
|
||||
return false;
|
||||
|
||||
poly->raster = Raster(lbl->readImage(*lblHdl, id),
|
||||
QRect(QPoint(left, top), QPoint(right, bottom)));
|
||||
poly->raster = Raster(lbl, id, QRect(QPoint(left, top), QPoint(right,
|
||||
bottom)));
|
||||
|
||||
rs -= lbl->imageIdSize() + 16;
|
||||
}
|
||||
@ -336,8 +336,7 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
|
||||
if (subtype & 0x20 && !readUInt24(hdl, labelPtr))
|
||||
return false;
|
||||
if (subtype & 0x80 && !readClassFields(hdl, segmentType, &poly, lbl,
|
||||
&lblHdl))
|
||||
if (subtype & 0x80 && !readClassFields(hdl, segmentType, &poly, lbl))
|
||||
return false;
|
||||
if (subtype & 0x40 && !skipLclFields(hdl, segmentType == Line
|
||||
? _linesLclFlags : _polygonsLclFlags))
|
||||
|
@ -61,7 +61,7 @@ private:
|
||||
QMap<SegmentType, SubDiv::Segment> segments(Handle &hdl, SubDiv *subdiv)
|
||||
const;
|
||||
bool readClassFields(Handle &hdl, SegmentType segmentType,
|
||||
MapData::Poly *poly = 0, const LBLFile *lbl = 0, Handle *lblHdl = 0) const;
|
||||
MapData::Poly *poly = 0, const LBLFile *lbl = 0) const;
|
||||
bool skipLclFields(Handle &hdl, const quint32 flags[3]) const;
|
||||
bool skipGblFields(Handle &hdl, quint32 flags) const;
|
||||
|
||||
|
@ -7,39 +7,38 @@
|
||||
|
||||
bool SubFile::seek(Handle &handle, quint32 pos) const
|
||||
{
|
||||
if (handle._file) {
|
||||
int blockNum = pos >> BLOCK_BITS;
|
||||
|
||||
if (handle._blockNum != blockNum) {
|
||||
if (!handle._file->seek((quint64)blockNum << BLOCK_BITS))
|
||||
return false;
|
||||
if (handle._file->read(handle._data.data(), (1<<BLOCK_BITS)) < 0)
|
||||
return false;
|
||||
handle._blockNum = blockNum;
|
||||
}
|
||||
|
||||
handle._blockPos = mod2n(pos, 1U<<BLOCK_BITS);
|
||||
handle._pos = pos;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
if (_img) {
|
||||
quint32 blockBits = _img->blockBits();
|
||||
int blockNum = pos >> blockBits;
|
||||
|
||||
if (handle._blockNum != blockNum) {
|
||||
if (blockNum >= _blocks->size())
|
||||
return false;
|
||||
if (!_img->readBlock(_blocks->at(blockNum), handle._data.data()))
|
||||
if (!_img->readBlock(handle._file, _blocks->at(blockNum),
|
||||
handle._data.data()))
|
||||
return false;
|
||||
handle._blockNum = blockNum;
|
||||
}
|
||||
|
||||
handle._blockPos = mod2n(pos, 1U<<blockBits);
|
||||
handle._pos = pos;
|
||||
} else {
|
||||
int blockNum = pos >> BLOCK_BITS;
|
||||
|
||||
if (handle._blockNum != blockNum) {
|
||||
if (!handle._file.seek((quint64)blockNum << BLOCK_BITS))
|
||||
return false;
|
||||
if (handle._file.read(handle._data.data(), (1<<BLOCK_BITS)) < 0)
|
||||
return false;
|
||||
handle._blockNum = blockNum;
|
||||
}
|
||||
|
||||
handle._blockPos = mod2n(pos, 1U<<BLOCK_BITS);
|
||||
handle._pos = pos;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool SubFile::readVUInt32(Handle &hdl, quint32 &val) const
|
||||
{
|
||||
|
@ -17,21 +17,26 @@ public:
|
||||
{
|
||||
public:
|
||||
Handle(const SubFile *subFile)
|
||||
: _file(0), _blockNum(-1), _blockPos(-1), _pos(-1)
|
||||
: _blockNum(-1), _blockPos(-1), _pos(-1)
|
||||
{
|
||||
if (subFile && subFile->_path) {
|
||||
_file = new QFile(*(subFile->_path));
|
||||
_file->open(QIODevice::ReadOnly);
|
||||
if (!subFile)
|
||||
return;
|
||||
|
||||
if (subFile->_path) {
|
||||
_file.setFileName(*(subFile->_path));
|
||||
_data.resize(1U<<BLOCK_BITS);
|
||||
} else if (subFile)
|
||||
} else {
|
||||
_file.setFileName(subFile->_img->fileName());
|
||||
_data.resize(1U<<subFile->_img->blockBits());
|
||||
}
|
||||
~Handle() {delete _file;}
|
||||
|
||||
_file.open(QIODevice::ReadOnly);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class SubFile;
|
||||
|
||||
QFile *_file;
|
||||
QFile _file;
|
||||
QByteArray _data;
|
||||
int _blockNum;
|
||||
int _blockPos;
|
||||
|
Loading…
Reference in New Issue
Block a user