mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-28 13:41:16 +01:00
Added support for OZF zoom levels
This commit is contained in:
parent
c708fa35fd
commit
73f06e61f0
@ -20,6 +20,7 @@
|
|||||||
#include "lambertconic.h"
|
#include "lambertconic.h"
|
||||||
#include "albersequal.h"
|
#include "albersequal.h"
|
||||||
#include "ozf.h"
|
#include "ozf.h"
|
||||||
|
#include "rectc.h"
|
||||||
#include "offlinemap.h"
|
#include "offlinemap.h"
|
||||||
|
|
||||||
|
|
||||||
@ -343,16 +344,19 @@ bool OfflineMap::getImageInfo(const QString &path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (OZF::isOZF(_imgPath)) {
|
if (OZF::isOZF(_imgPath)) {
|
||||||
_ozf.load(_imgPath);
|
if (!_ozf.load(_imgPath)) {
|
||||||
_size = _ozf.size();
|
_errorString = QString("%1: Error loading OZF file")
|
||||||
|
.arg(QFileInfo(_imgPath).fileName());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
QImageReader img(_imgPath);
|
QImageReader img(_imgPath);
|
||||||
_size = img.size();
|
_size = img.size();
|
||||||
}
|
if (!_size.isValid()) {
|
||||||
if (!_size.isValid()) {
|
_errorString = QString("%1: Error reading map image")
|
||||||
_errorString = QString("%1: Error reading map image")
|
.arg(QFileInfo(_imgPath).fileName());
|
||||||
.arg(QFileInfo(_imgPath).fileName());
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -410,6 +414,8 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
|||||||
_img = 0;
|
_img = 0;
|
||||||
_projection = 0;
|
_projection = 0;
|
||||||
_resolution = 0.0;
|
_resolution = 0.0;
|
||||||
|
_zoom = 0;
|
||||||
|
_scale = QPointF(1.0, 1.0);
|
||||||
|
|
||||||
if (suffix == "tar") {
|
if (suffix == "tar") {
|
||||||
if (!_tar.load(fileName)) {
|
if (!_tar.load(fileName)) {
|
||||||
@ -476,6 +482,8 @@ OfflineMap::OfflineMap(const QString &fileName, Tar &tar, QObject *parent)
|
|||||||
_img = 0;
|
_img = 0;
|
||||||
_projection = 0;
|
_projection = 0;
|
||||||
_resolution = 0.0;
|
_resolution = 0.0;
|
||||||
|
_zoom = 0;
|
||||||
|
_scale = QPointF(1.0, 1.0);
|
||||||
|
|
||||||
QFileInfo map(fi.absolutePath());
|
QFileInfo map(fi.absolutePath());
|
||||||
QFileInfo layer(map.absolutePath());
|
QFileInfo layer(map.absolutePath());
|
||||||
@ -551,7 +559,7 @@ void OfflineMap::drawTiled(QPainter *painter, const QRectF &rect)
|
|||||||
int x = tl.x() + i * _tileSize.width();
|
int x = tl.x() + i * _tileSize.width();
|
||||||
int y = tl.y() + j * _tileSize.height();
|
int y = tl.y() + j * _tileSize.height();
|
||||||
|
|
||||||
if (!QRectF(QPointF(x, y), _ozf.tileSize()).intersects(bounds())) {
|
if (!QRectF(QPointF(x, y), _tileSize).intersects(bounds())) {
|
||||||
painter->fillRect(QRectF(QPoint(x, y), _tileSize), Qt::white);
|
painter->fillRect(QRectF(QPoint(x, y), _tileSize), Qt::white);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -594,22 +602,24 @@ void OfflineMap::drawOZF(QPainter *painter, const QRectF &rect)
|
|||||||
int y = tl.y() + j * _ozf.tileSize().height();
|
int y = tl.y() + j * _ozf.tileSize().height();
|
||||||
|
|
||||||
if (!QRectF(QPointF(x, y), _ozf.tileSize()).intersects(bounds())) {
|
if (!QRectF(QPointF(x, y), _ozf.tileSize()).intersects(bounds())) {
|
||||||
painter->fillRect(QRectF(QPoint(x, y), _tileSize), Qt::white);
|
painter->fillRect(QRectF(QPoint(x, y), _ozf.tileSize()),
|
||||||
|
Qt::white);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap pixmap;
|
QPixmap pixmap;
|
||||||
QString key = _ozf.fileName() + "/" + QString::number(x)
|
QString key = _ozf.fileName() + "/" + QString::number(_zoom) + "_"
|
||||||
+ "_" + QString::number(y);
|
+ QString::number(x) + "_" + QString::number(y);
|
||||||
if (!QPixmapCache::find(key, &pixmap)) {
|
if (!QPixmapCache::find(key, &pixmap)) {
|
||||||
pixmap = _ozf.tile(x, y);
|
pixmap = _ozf.tile(_zoom, x, y);
|
||||||
if (!pixmap.isNull())
|
if (!pixmap.isNull())
|
||||||
QPixmapCache::insert(key, pixmap);
|
QPixmapCache::insert(key, pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pixmap.isNull()) {
|
if (pixmap.isNull()) {
|
||||||
qWarning("%s: error loading tile image", qPrintable(key));
|
qWarning("%s: error loading tile image", qPrintable(key));
|
||||||
painter->fillRect(QRectF(QPoint(x, y), _tileSize), Qt::white);
|
painter->fillRect(QRectF(QPoint(x, y), _ozf.tileSize()),
|
||||||
|
Qt::white);
|
||||||
} else
|
} else
|
||||||
painter->drawPixmap(QPoint(x, y), pixmap);
|
painter->drawPixmap(QPoint(x, y), pixmap);
|
||||||
}
|
}
|
||||||
@ -636,3 +646,101 @@ void OfflineMap::draw(QPainter *painter, const QRectF &rect)
|
|||||||
else
|
else
|
||||||
drawImage(painter, rect);
|
drawImage(painter, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPointF OfflineMap::ll2xy(const Coordinates &c)
|
||||||
|
{
|
||||||
|
if (_ozf.isOpen()) {
|
||||||
|
QPointF p(_transform.map(_projection->ll2xy(c)));
|
||||||
|
return QPointF(p.x() * _scale.x(), p.y() * _scale.y());
|
||||||
|
} else
|
||||||
|
return _transform.map(_projection->ll2xy(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
Coordinates OfflineMap::xy2ll(const QPointF &p)
|
||||||
|
{
|
||||||
|
if (_ozf.isOpen()) {
|
||||||
|
return _projection->xy2ll(_inverted.map(QPointF(p.x() / _scale.x(),
|
||||||
|
p.y() / _scale.y())));
|
||||||
|
} else
|
||||||
|
return _projection->xy2ll(_inverted.map(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF OfflineMap::bounds() const
|
||||||
|
{
|
||||||
|
if (_ozf.isOpen())
|
||||||
|
return QRectF(QPointF(0, 0), _ozf.size(_zoom));
|
||||||
|
else
|
||||||
|
return QRectF(QPointF(0, 0), _size);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal OfflineMap::resolution(const QPointF &p) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(p);
|
||||||
|
|
||||||
|
if (_ozf.isOpen())
|
||||||
|
return _resolution / ((_scale.x() + _scale.y()) / 2.0);
|
||||||
|
else
|
||||||
|
return _resolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal OfflineMap::zoomFit(const QSize &size, const RectC &br)
|
||||||
|
{
|
||||||
|
if (_ozf.isOpen()) {
|
||||||
|
if (!br.isValid())
|
||||||
|
rescale(0);
|
||||||
|
else {
|
||||||
|
QRect sbr(QRectF(_transform.map(_projection->ll2xy(br.topLeft())),
|
||||||
|
_transform.map(_projection->ll2xy(br.bottomRight())))
|
||||||
|
.toRect().normalized());
|
||||||
|
|
||||||
|
for (int i = 0; i < _ozf.zooms(); i++) {
|
||||||
|
rescale(i);
|
||||||
|
if (sbr.size().width() * _scale.x() <= size.width()
|
||||||
|
&& sbr.size().height() * _scale.y() <= size.height())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _zoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal OfflineMap::zoomFit(qreal resolution, const Coordinates &c)
|
||||||
|
{
|
||||||
|
Q_UNUSED(c);
|
||||||
|
|
||||||
|
if (_ozf.isOpen()) {
|
||||||
|
for (int i = 0; i < _ozf.zooms(); i++) {
|
||||||
|
rescale(i);
|
||||||
|
qreal sr = _resolution / ((_scale.x() + _scale.y()) / 2.0);
|
||||||
|
if (sr >= resolution)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _zoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal OfflineMap::zoomIn()
|
||||||
|
{
|
||||||
|
if (_ozf.isOpen())
|
||||||
|
rescale(qMax(_zoom - 1, 0));
|
||||||
|
|
||||||
|
return _zoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal OfflineMap::zoomOut()
|
||||||
|
{
|
||||||
|
if (_ozf.isOpen())
|
||||||
|
rescale(qMin(_zoom + 1, _ozf.zooms() - 1));
|
||||||
|
|
||||||
|
return _zoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OfflineMap::rescale(int zoom)
|
||||||
|
{
|
||||||
|
_zoom = zoom;
|
||||||
|
_scale = QPointF(
|
||||||
|
(qreal)_ozf.size(_zoom).width() / (qreal)_ozf.size(0).width(),
|
||||||
|
(qreal)_ozf.size(_zoom).height() / (qreal)_ozf.size(0).height());
|
||||||
|
}
|
||||||
|
@ -23,19 +23,17 @@ public:
|
|||||||
|
|
||||||
const QString &name() const {return _name;}
|
const QString &name() const {return _name;}
|
||||||
|
|
||||||
QRectF bounds() const {return QRectF(QPointF(0, 0), _size);}
|
QRectF bounds() const;
|
||||||
qreal resolution(const QPointF &) const {return _resolution;}
|
qreal resolution(const QPointF &p) const;
|
||||||
|
|
||||||
qreal zoom() const {return 0;}
|
qreal zoom() const {return _zoom;}
|
||||||
qreal zoomFit(const QSize &, const RectC &) {return 0;}
|
qreal zoomFit(const QSize &size, const RectC &br);
|
||||||
qreal zoomFit(qreal, const Coordinates &) {return 0;}
|
qreal zoomFit(qreal resolution, const Coordinates &c);
|
||||||
qreal zoomIn() {return 0;}
|
qreal zoomIn();
|
||||||
qreal zoomOut() {return 0;}
|
qreal zoomOut();
|
||||||
|
|
||||||
QPointF ll2xy(const Coordinates &c)
|
QPointF ll2xy(const Coordinates &c);
|
||||||
{return _transform.map(_projection->ll2xy(c));}
|
Coordinates xy2ll(const QPointF &p);
|
||||||
Coordinates xy2ll(const QPointF &p)
|
|
||||||
{return _projection->xy2ll(_inverted.map(p));}
|
|
||||||
|
|
||||||
void draw(QPainter *painter, const QRectF &rect);
|
void draw(QPainter *painter, const QRectF &rect);
|
||||||
|
|
||||||
@ -86,6 +84,8 @@ private:
|
|||||||
void drawOZF(QPainter *painter, const QRectF &rect);
|
void drawOZF(QPainter *painter, const QRectF &rect);
|
||||||
void drawImage(QPainter *painter, const QRectF &rect);
|
void drawImage(QPainter *painter, const QRectF &rect);
|
||||||
|
|
||||||
|
void rescale(int zoom);
|
||||||
|
|
||||||
QString _name;
|
QString _name;
|
||||||
bool _valid;
|
bool _valid;
|
||||||
QString _errorString;
|
QString _errorString;
|
||||||
@ -102,6 +102,9 @@ private:
|
|||||||
QString _imgPath;
|
QString _imgPath;
|
||||||
QSize _tileSize;
|
QSize _tileSize;
|
||||||
QString _tileName;
|
QString _tileName;
|
||||||
|
|
||||||
|
int _zoom;
|
||||||
|
QPointF _scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // OFFLINEMAP_H
|
#endif // OFFLINEMAP_H
|
||||||
|
147
src/ozf.cpp
147
src/ozf.cpp
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
#define OZF2_MAGIC 0x7778
|
#define OZF2_MAGIC 0x7778
|
||||||
#define OZF3_MAGIC 0x7780
|
#define OZF3_MAGIC 0x7780
|
||||||
#define SEPARATOR 0x77777777
|
|
||||||
|
|
||||||
static const quint8 XKEY[] =
|
static const quint8 XKEY[] =
|
||||||
{
|
{
|
||||||
@ -39,21 +38,22 @@ template<class T> bool OZF::readValue(T &val)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OZF::read(void *data, size_t size)
|
bool OZF::read(void *data, size_t size, size_t decryptSize)
|
||||||
{
|
{
|
||||||
if (_file.read((char*)data, size) < (qint64)size)
|
if (_file.read((char*)data, size) < (qint64)size)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (_decrypt)
|
if (_decrypt)
|
||||||
decrypt(data, size, _key);
|
decrypt(data, decryptSize ? qMin(decryptSize, size) : size, _key);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OZF::readKey()
|
bool OZF::initOZF3()
|
||||||
{
|
{
|
||||||
quint8 randomNumber, initial;
|
quint8 randomNumber, initial;
|
||||||
quint32 keyblock;
|
quint32 keyblock;
|
||||||
|
quint8 h1[8];
|
||||||
|
|
||||||
|
|
||||||
if (!_file.seek(14))
|
if (!_file.seek(14))
|
||||||
@ -66,7 +66,15 @@ bool OZF::readKey()
|
|||||||
if (!readValue(initial))
|
if (!readValue(initial))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_decrypt = true; _key = initial;
|
_decrypt = true;
|
||||||
|
_key = initial;
|
||||||
|
|
||||||
|
if (!_file.seek(0))
|
||||||
|
return false;
|
||||||
|
if (!read(h1, sizeof(h1)))
|
||||||
|
return false;
|
||||||
|
_tileSize = *(h1 + 6);
|
||||||
|
|
||||||
if (!_file.seek(15 + randomNumber))
|
if (!_file.seek(15 + randomNumber))
|
||||||
return false;
|
return false;
|
||||||
if (!readValue(keyblock))
|
if (!readValue(keyblock))
|
||||||
@ -104,21 +112,28 @@ bool OZF::readKey()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OZF::initOZF2()
|
||||||
|
{
|
||||||
|
if (!_file.seek(6))
|
||||||
|
return false;
|
||||||
|
if (!readValue(_tileSize))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool OZF::readHeaders()
|
bool OZF::readHeaders()
|
||||||
{
|
{
|
||||||
quint16 magic;
|
quint16 magic;
|
||||||
quint32 separator;
|
|
||||||
|
|
||||||
if (!readValue(magic))
|
if (!readValue(magic))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (magic == OZF2_MAGIC) {
|
if (magic == OZF2_MAGIC) {
|
||||||
if (!_file.seek(_file.pos() + 52))
|
if (!initOZF2())
|
||||||
return false;
|
|
||||||
if (!readValue(separator) || separator != SEPARATOR)
|
|
||||||
return false;
|
return false;
|
||||||
} else if (magic == OZF3_MAGIC) {
|
} else if (magic == OZF3_MAGIC) {
|
||||||
if (!readKey())
|
if (!initOZF3())
|
||||||
return false;
|
return false;
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
@ -128,52 +143,58 @@ bool OZF::readHeaders()
|
|||||||
|
|
||||||
bool OZF::readTileTable()
|
bool OZF::readTileTable()
|
||||||
{
|
{
|
||||||
quint32 offset, bgr0, w, h;
|
quint32 tableOffset, headerOffset, bgr0, w, h;
|
||||||
quint16 x, y;
|
quint16 x, y;
|
||||||
|
int zooms;
|
||||||
|
|
||||||
|
|
||||||
if (!_file.seek(_file.size() - sizeof(offset)))
|
if (!_file.seek(_file.size() - sizeof(tableOffset)))
|
||||||
return false;
|
return false;
|
||||||
// table offset
|
if (!readValue(tableOffset))
|
||||||
if (!readValue(offset))
|
|
||||||
return false;
|
|
||||||
if (!_file.seek(offset))
|
|
||||||
return false;
|
|
||||||
// tiles offset (zoom level 0)
|
|
||||||
if (!readValue(offset))
|
|
||||||
return false;
|
|
||||||
if (!_file.seek(offset))
|
|
||||||
return false;
|
return false;
|
||||||
|
zooms = (_file.size() - tableOffset - sizeof(quint32)) / sizeof(quint32);
|
||||||
|
|
||||||
if (!readValue(w))
|
for (int i = 0; i < zooms - 2; i++) {
|
||||||
return false;
|
if (!_file.seek(tableOffset + i * sizeof(quint32)))
|
||||||
if (!readValue(h))
|
|
||||||
return false;
|
|
||||||
if (!readValue(x))
|
|
||||||
return false;
|
|
||||||
if (!readValue(y))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_size = QSize(w, h);
|
|
||||||
_dim = QSize(x, y);
|
|
||||||
|
|
||||||
_palette = QVector<quint32>(256);
|
|
||||||
if (!read(&(_palette[0]), sizeof(quint32) * 256))
|
|
||||||
return false;
|
|
||||||
for (int i = 0; i < _palette.size(); i++) {
|
|
||||||
bgr0 = qFromLittleEndian(_palette.at(i));
|
|
||||||
|
|
||||||
quint32 b = (bgr0 & 0x000000FF);
|
|
||||||
quint32 g = (bgr0 & 0x0000FF00) >> 8;
|
|
||||||
quint32 r = (bgr0 & 0x00FF0000) >> 16;
|
|
||||||
|
|
||||||
_palette[i] = 0xFF000000 | r << 16 | g << 8 | b;
|
|
||||||
}
|
|
||||||
|
|
||||||
_tiles = QVector<quint32>(_dim.width() * _dim.height() + 1);
|
|
||||||
for (int i = 0; i < _tiles.size(); i++)
|
|
||||||
if (!readValue(_tiles[i]))
|
|
||||||
return false;
|
return false;
|
||||||
|
if (!readValue(headerOffset))
|
||||||
|
return false;
|
||||||
|
if (!_file.seek(headerOffset))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!readValue(w))
|
||||||
|
return false;
|
||||||
|
if (!readValue(h))
|
||||||
|
return false;
|
||||||
|
if (!readValue(x))
|
||||||
|
return false;
|
||||||
|
if (!readValue(y))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Zoom zoom;
|
||||||
|
zoom.size = QSize(w, h);
|
||||||
|
zoom.dim = QSize(x, y);
|
||||||
|
|
||||||
|
zoom.palette = QVector<quint32>(256);
|
||||||
|
if (!read(&(zoom.palette[0]), sizeof(quint32) * 256))
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < zoom.palette.size(); i++) {
|
||||||
|
bgr0 = qFromLittleEndian(zoom.palette.at(i));
|
||||||
|
|
||||||
|
quint32 b = (bgr0 & 0x000000FF);
|
||||||
|
quint32 g = (bgr0 & 0x0000FF00) >> 8;
|
||||||
|
quint32 r = (bgr0 & 0x00FF0000) >> 16;
|
||||||
|
|
||||||
|
zoom.palette[i] = 0xFF000000 | r << 16 | g << 8 | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
zoom.tiles = QVector<quint32>(zoom.dim.width() * zoom.dim.height() + 1);
|
||||||
|
for (int i = 0; i < zoom.tiles.size(); i++)
|
||||||
|
if (!readValue(zoom.tiles[i]))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_zooms.append(zoom);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -196,23 +217,25 @@ bool OZF::load(const QString &path)
|
|||||||
if (!readTileTable()) {
|
if (!readTileTable()) {
|
||||||
qWarning("%s: file format error", qPrintable(_file.fileName()));
|
qWarning("%s: file format error", qPrintable(_file.fileName()));
|
||||||
_file.close();
|
_file.close();
|
||||||
_size = QSize();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap OZF::tile(int x, int y)
|
QPixmap OZF::tile(int zoom, int x, int y)
|
||||||
{
|
{
|
||||||
Q_ASSERT(_file.isOpen());
|
Q_ASSERT(_file.isOpen());
|
||||||
|
Q_ASSERT(0 <= zoom && zoom < _zooms.count());
|
||||||
|
|
||||||
int i = (y/tileSize().height()) * _dim.width() + (x/tileSize().width());
|
const Zoom &z = _zooms.at(zoom);
|
||||||
if (i >= _tiles.size() - 1 || i < 0)
|
|
||||||
|
int i = (y/tileSize().height()) * z.dim.width() + (x/tileSize().width());
|
||||||
|
if (i >= z.tiles.size() - 1 || i < 0)
|
||||||
return QPixmap();
|
return QPixmap();
|
||||||
|
|
||||||
int size = _tiles.at(i+1) - _tiles.at(i);
|
int size = z.tiles.at(i+1) - z.tiles.at(i);
|
||||||
if (!_file.seek(_tiles.at(i)))
|
if (!_file.seek(z.tiles.at(i)))
|
||||||
return QPixmap();
|
return QPixmap();
|
||||||
|
|
||||||
quint32 bes = qToBigEndian(tileSize().width() * tileSize().height());
|
quint32 bes = qToBigEndian(tileSize().width() * tileSize().height());
|
||||||
@ -220,21 +243,27 @@ QPixmap OZF::tile(int x, int y)
|
|||||||
ba.resize(sizeof(bes) + size);
|
ba.resize(sizeof(bes) + size);
|
||||||
*(ba.data()) = bes;
|
*(ba.data()) = bes;
|
||||||
|
|
||||||
if (_file.read(ba.data() + sizeof(bes), size) != size)
|
if (!read(ba.data() + sizeof(bes), size, 16))
|
||||||
return QPixmap();
|
return QPixmap();
|
||||||
if (_decrypt)
|
|
||||||
decrypt(ba.data() + sizeof(bes), qMin(16, size), _key);
|
|
||||||
QByteArray uba = qUncompress(ba);
|
QByteArray uba = qUncompress(ba);
|
||||||
if (uba.size() != tileSize().width() * tileSize().height())
|
if (uba.size() != tileSize().width() * tileSize().height())
|
||||||
return QPixmap();
|
return QPixmap();
|
||||||
|
|
||||||
QImage img((const uchar*)uba.constData(), tileSize().width(),
|
QImage img((const uchar*)uba.constData(), tileSize().width(),
|
||||||
tileSize().height(), QImage::Format_Indexed8);
|
tileSize().height(), QImage::Format_Indexed8);
|
||||||
img.setColorTable(_palette);
|
img.setColorTable(z.palette);
|
||||||
|
|
||||||
return QPixmap::fromImage(img.mirrored());
|
return QPixmap::fromImage(img.mirrored());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSize OZF::size(int zoom) const
|
||||||
|
{
|
||||||
|
Q_ASSERT(_file.isOpen());
|
||||||
|
Q_ASSERT(0 <= zoom && zoom < _zooms.count());
|
||||||
|
|
||||||
|
return _zooms.at(zoom).size;
|
||||||
|
}
|
||||||
|
|
||||||
bool OZF::isOZF(const QString &path)
|
bool OZF::isOZF(const QString &path)
|
||||||
{
|
{
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
|
28
src/ozf.h
28
src/ozf.h
@ -4,6 +4,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
#include <QList>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
@ -18,27 +19,32 @@ public:
|
|||||||
QString fileName() const {return _file.fileName();}
|
QString fileName() const {return _file.fileName();}
|
||||||
bool isOpen() const {return _file.isOpen();}
|
bool isOpen() const {return _file.isOpen();}
|
||||||
|
|
||||||
QSize size() const {return _size;}
|
int zooms() const {return _zooms.size();}
|
||||||
QSize tileSize() const {return QSize(64, 64);}
|
QSize size(int zoom) const;
|
||||||
QPixmap tile(int x, int y);
|
QSize tileSize() const {return QSize(_tileSize, _tileSize);}
|
||||||
|
QPixmap tile(int zoom, int x, int y);
|
||||||
|
|
||||||
static bool isOZF(const QString &path);
|
static bool isOZF(const QString &path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct Zoom {
|
||||||
|
QSize size;
|
||||||
|
QSize dim;
|
||||||
|
QVector<QRgb> palette;
|
||||||
|
QVector<quint32> tiles;
|
||||||
|
};
|
||||||
|
|
||||||
template<class T> bool readValue(T &val);
|
template<class T> bool readValue(T &val);
|
||||||
bool read(void *data, size_t size);
|
bool read(void *data, size_t size, size_t decryptSize = 0);
|
||||||
bool readKey();
|
bool initOZF3();
|
||||||
|
bool initOZF2();
|
||||||
bool readHeaders();
|
bool readHeaders();
|
||||||
bool readTileTable();
|
bool readTileTable();
|
||||||
|
|
||||||
|
quint16 _tileSize;
|
||||||
bool _decrypt;
|
bool _decrypt;
|
||||||
quint8 _key;
|
quint8 _key;
|
||||||
|
QList<Zoom> _zooms;
|
||||||
QSize _size;
|
|
||||||
QSize _dim;
|
|
||||||
QVector<QRgb> _palette;
|
|
||||||
QVector<quint32> _tiles;
|
|
||||||
|
|
||||||
QFile _file;
|
QFile _file;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user