2018-10-29 00:11:23 +01:00
|
|
|
#include <QImage>
|
|
|
|
#include <QIODevice>
|
|
|
|
#include <QtEndian>
|
|
|
|
#include "gzip.h"
|
|
|
|
#include "pbf.h"
|
|
|
|
#include "pbfhandler.h"
|
|
|
|
|
|
|
|
|
2018-11-04 09:38:41 +01:00
|
|
|
#define TILE_SIZE 256
|
2018-11-03 00:38:53 +01:00
|
|
|
|
2018-11-10 00:14:36 +01:00
|
|
|
#define GZIP_MAGIC 0x1F8B0800
|
|
|
|
#define GZIP_MAGIC_MASK 0xFFFFFF00
|
|
|
|
#define PBF_MAGIC 0x1A000000
|
|
|
|
#define PBF_MAGIC_MASK 0xFF000000
|
2018-10-29 00:11:23 +01:00
|
|
|
|
2018-11-10 08:09:42 +01:00
|
|
|
static bool isMagic(quint32 magic, quint32 mask, quint32 value)
|
|
|
|
{
|
|
|
|
return ((qFromBigEndian(value) & mask) == magic);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool isGZIPPBF(quint32 magic)
|
|
|
|
{
|
|
|
|
return isMagic(GZIP_MAGIC, GZIP_MAGIC_MASK, magic);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool isPlainPBF(quint32 magic)
|
|
|
|
{
|
|
|
|
return isMagic(PBF_MAGIC, PBF_MAGIC_MASK, magic);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-10-29 00:11:23 +01:00
|
|
|
bool PBFHandler::canRead() const
|
|
|
|
{
|
|
|
|
return canRead(device());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PBFHandler::canRead(QIODevice *device)
|
|
|
|
{
|
|
|
|
quint32 magic;
|
|
|
|
qint64 size = device->peek((char*)&magic, sizeof(magic));
|
2018-11-10 00:14:36 +01:00
|
|
|
if (size != sizeof(magic))
|
|
|
|
return false;
|
|
|
|
|
2018-11-10 08:09:42 +01:00
|
|
|
return (isGZIPPBF(magic) || isPlainPBF(magic));
|
2018-10-29 00:11:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool PBFHandler::read(QImage *image)
|
|
|
|
{
|
2018-11-10 00:14:36 +01:00
|
|
|
quint32 magic;
|
|
|
|
qint64 size = device()->peek((char*)&magic, sizeof(magic));
|
|
|
|
if (size != sizeof(magic))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
QByteArray ba;
|
|
|
|
|
2018-11-10 08:09:42 +01:00
|
|
|
if (isGZIPPBF(magic))
|
2018-11-10 00:14:36 +01:00
|
|
|
ba = Gzip::uncompress(device()->readAll());
|
2018-11-10 08:09:42 +01:00
|
|
|
else if (isPlainPBF(magic))
|
2018-11-10 00:14:36 +01:00
|
|
|
ba = device()->readAll();
|
2018-10-29 00:11:23 +01:00
|
|
|
if (ba.isNull())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bool ok;
|
|
|
|
int zoom = format().toInt(&ok);
|
2018-11-03 00:38:53 +01:00
|
|
|
*image = PBF::image(ba, ok ? zoom : -1, _style, TILE_SIZE);
|
2018-10-29 00:11:23 +01:00
|
|
|
|
|
|
|
return !image->isNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PBFHandler::supportsOption(ImageOption option) const
|
|
|
|
{
|
|
|
|
return (option == Size);
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant PBFHandler::option(ImageOption option) const
|
|
|
|
{
|
2018-11-03 00:38:53 +01:00
|
|
|
return (option == Size) ? QSize(TILE_SIZE, TILE_SIZE) : QVariant();
|
2018-10-29 00:11:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QByteArray PBFHandler::name() const
|
|
|
|
{
|
|
|
|
return "pbf";
|
|
|
|
}
|