Browse Source

add RAGEPHOTO_BENCHMARK for parser benchmarks

1.10.x
Syping 1 year ago
parent
commit
b747f7cda5
  1. 163
      RagePhoto.cpp
  2. 10
      RagePhoto.h

163
RagePhoto.cpp

@ -23,6 +23,10 @@
#if QT_VERSION < 0x060000
#include <QTextCodec>
#endif
#ifdef RAGEPHOTO_BENCHMARK
#include <QFileInfo>
#include <chrono>
#endif
RagePhoto::RagePhoto()
{
@ -83,6 +87,10 @@ bool RagePhoto::load()
QBuffer dataBuffer(&p_fileData);
dataBuffer.open(QIODevice::ReadOnly);
#ifdef RAGEPHOTO_BENCHMARK
auto benchmark_parse_start = std::chrono::high_resolution_clock::now();
#endif
char uInt32Buffer[4];
qint64 size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
@ -90,12 +98,9 @@ bool RagePhoto::load()
quint32 format = charToUInt32LE(uInt32Buffer);
if (format == static_cast<quint32>(PhotoFormat::GTA5)) {
char *photoHeader = static_cast<char*>(malloc(256));
if (!photoHeader)
return false;
char photoHeader[256];
size = dataBuffer.read(photoHeader, 256);
if (size != 256) {
free(photoHeader);
return false;
}
for (const QChar &photoChar : utf16LEToString(photoHeader, 256)) {
@ -103,7 +108,6 @@ bool RagePhoto::load()
break;
p_photoString += photoChar;
}
free(photoHeader);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
@ -209,11 +213,12 @@ bool RagePhoto::load()
free(titlBytes);
return false;
}
for (const QChar &titlChar : QString::fromUtf8(titlBytes, p_titlBuffer)) {
if (titlChar.isNull())
quint32 i;
for (i = 0; i != p_titlBuffer; i++) {
if (titlBytes[i] == '\x00')
break;
p_titleString += titlChar;
}
p_titleString = QString::fromUtf8(titlBytes, i);
free(titlBytes);
dataBuffer.seek(p_descOffset + 264);
@ -236,11 +241,11 @@ bool RagePhoto::load()
free(descBytes);
return false;
}
for (const QChar &descChar : QString::fromUtf8(descBytes, p_descBuffer)) {
if (descChar.isNull())
for (i = 0; i != p_descBuffer; i++) {
if (descBytes[i] == '\x00')
break;
p_descriptionString += descChar;
}
p_descriptionString = QString::fromUtf8(descBytes, i);
free(descBytes);
dataBuffer.seek(p_endOfFile + 260);
@ -250,6 +255,17 @@ bool RagePhoto::load()
if (strncmp(markerBuffer, "JEND", 4) != 0)
return false;
#ifdef RAGEPHOTO_BENCHMARK
auto benchmark_parse_end = std::chrono::high_resolution_clock::now();
auto benchmark_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(benchmark_parse_end - benchmark_parse_start);
if (p_inputMode == 1) {
QTextStream(stdout) << QFileInfo(p_filePath).fileName() << ": " << static_cast<int>(benchmark_ns.count()) << "ns" << Qt::endl;
}
else {
QTextStream(stdout) << "PGTA5" << p_jsonObject.value("uid").toInt() << ": " << static_cast<int>(benchmark_ns.count()) << "ns" << Qt::endl;
}
#endif
if (p_photoFormat != PhotoFormat::G5EX)
p_photoFormat = PhotoFormat::GTA5;
@ -404,6 +420,17 @@ bool RagePhoto::load()
return false;
p_endOfFile = charToUInt32LE(uInt32Buffer);
#ifdef RAGEPHOTO_BENCHMARK
auto benchmark_parse_end = std::chrono::high_resolution_clock::now();
auto benchmark_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(benchmark_parse_end - benchmark_parse_start);
if (p_inputMode == 1) {
QTextStream(stdout) << QFileInfo(p_filePath).fileName() << ": " << static_cast<int>(benchmark_ns.count()) << "ns" << Qt::endl;
}
else {
QTextStream(stdout) << "PGTA5" << p_jsonObject.value("uid").toInt() << ": " << static_cast<int>(benchmark_ns.count()) << "ns" << Qt::endl;
}
#endif
p_photoFormat = PhotoFormat::G5EX;
p_fileData.clear();
@ -421,12 +448,12 @@ bool RagePhoto::load()
else if (format == static_cast<quint32>(ExportFormat::G5E1P)) {
#if QT_VERSION >= 0x050A00
size = dataBuffer.skip(1);
#else
QByteArray skipData = dataBuffer.read(1);
size = skipData.size();
#endif
if (size != 1)
return false;
#else
if (!dataBuffer.seek(dataBuffer.pos() + 1))
return false;
#endif
char length[1];
size = dataBuffer.read(length, 1);
@ -436,12 +463,12 @@ bool RagePhoto::load()
#if QT_VERSION >= 0x050A00
size = dataBuffer.skip(i_length);
#else
skipData = dataBuffer.read(i_length);
size = skipData.size();
#endif
if (size != i_length)
return false;
#else
if (!dataBuffer.seek(dataBuffer.pos() + i_length))
return false;
#endif
p_photoFormat = PhotoFormat::G5EX;
p_fileData = qUncompress(dataBuffer.readAll());
@ -613,67 +640,67 @@ void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
if (photoFormat == PhotoFormat::G5EX) {
char uInt32Buffer[4];
quint32 format = static_cast<quint32>(PhotoFormat::G5EX);
uInt32ToCharLE(&format, uInt32Buffer);
uInt32ToCharLE(format, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
format = static_cast<quint32>(ExportFormat::G5E3P);
uInt32ToCharLE(&format, uInt32Buffer);
uInt32ToCharLE(format, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
QByteArray compressedData = qCompress(p_photoString.toUtf8(), 9);
quint32 compressedSize = compressedData.size();
uInt32ToCharLE(&compressedSize, uInt32Buffer);
uInt32ToCharLE(compressedSize, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
ioDevice->write(compressedData);
uInt32ToCharLE(&p_headerSum, uInt32Buffer);
uInt32ToCharLE(p_headerSum, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(&p_photoBuffer, uInt32Buffer);
uInt32ToCharLE(p_photoBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
compressedData = qCompress(p_photoData, 9);
compressedSize = compressedData.size();
uInt32ToCharLE(&compressedSize, uInt32Buffer);
uInt32ToCharLE(compressedSize, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
ioDevice->write(compressedData);
uInt32ToCharLE(&p_jsonOffset, uInt32Buffer);
uInt32ToCharLE(p_jsonOffset, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(&p_jsonBuffer, uInt32Buffer);
uInt32ToCharLE(p_jsonBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
compressedData = qCompress(p_jsonData, 9);
compressedSize = compressedData.size();
uInt32ToCharLE(&compressedSize, uInt32Buffer);
uInt32ToCharLE(compressedSize, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
ioDevice->write(compressedData);
uInt32ToCharLE(&p_titlOffset, uInt32Buffer);
uInt32ToCharLE(p_titlOffset, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(&p_titlBuffer, uInt32Buffer);
uInt32ToCharLE(p_titlBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
compressedData = qCompress(p_titleString.toUtf8(), 9);
compressedSize = compressedData.size();
uInt32ToCharLE(&compressedSize, uInt32Buffer);
uInt32ToCharLE(compressedSize, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
ioDevice->write(compressedData);
uInt32ToCharLE(&p_descOffset, uInt32Buffer);
uInt32ToCharLE(p_descOffset, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(&p_descBuffer, uInt32Buffer);
uInt32ToCharLE(p_descBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
compressedData = qCompress(p_descriptionString.toUtf8(), 9);
compressedSize = compressedData.size();
uInt32ToCharLE(&compressedSize, uInt32Buffer);
uInt32ToCharLE(compressedSize, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
ioDevice->write(compressedData);
uInt32ToCharLE(&p_endOfFile, uInt32Buffer);
uInt32ToCharLE(p_endOfFile, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
#if QT_VERSION >= 0x050000
@ -683,11 +710,11 @@ void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
else if (photoFormat == PhotoFormat::GTA5) {
char uInt32Buffer[4];
quint32 format = static_cast<quint32>(PhotoFormat::GTA5);
uInt32ToCharLE(&format, uInt32Buffer);
uInt32ToCharLE(format, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
QByteArray photoHeader = stringToUtf16LE(p_photoString);
if (photoHeader.left(2) == "\xFF\xFE") {
if (photoHeader.startsWith("\xFF\xFE")) {
photoHeader.remove(0, 2);
}
qint64 photoHeaderSize = photoHeader.size();
@ -700,28 +727,28 @@ void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
ioDevice->write("\x00", 1);
}
uInt32ToCharLE(&p_headerSum, uInt32Buffer);
uInt32ToCharLE(p_headerSum, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(&p_endOfFile, uInt32Buffer);
uInt32ToCharLE(p_endOfFile, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(&p_jsonOffset, uInt32Buffer);
uInt32ToCharLE(p_jsonOffset, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(&p_titlOffset, uInt32Buffer);
uInt32ToCharLE(p_titlOffset, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(&p_descOffset, uInt32Buffer);
uInt32ToCharLE(p_descOffset, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
ioDevice->write("JPEG", 4);
uInt32ToCharLE(&p_photoBuffer, uInt32Buffer);
uInt32ToCharLE(p_photoBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
quint32 t_photoSize = p_photoData.size();
uInt32ToCharLE(&t_photoSize, uInt32Buffer);
uInt32ToCharLE(t_photoSize, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
ioDevice->write(p_photoData);
@ -732,7 +759,7 @@ void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
ioDevice->seek(p_jsonOffset + 264);
ioDevice->write("JSON", 4);
uInt32ToCharLE(&p_jsonBuffer, uInt32Buffer);
uInt32ToCharLE(p_jsonBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
qint64 dataSize = p_jsonData.size();
@ -744,7 +771,7 @@ void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
ioDevice->seek(p_titlOffset + 264);
ioDevice->write("TITL", 4);
uInt32ToCharLE(&p_titlBuffer, uInt32Buffer);
uInt32ToCharLE(p_titlBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
QByteArray data = p_titleString.toUtf8();
@ -757,7 +784,7 @@ void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
ioDevice->seek(p_descOffset + 264);
ioDevice->write("DESC", 4);
uInt32ToCharLE(&p_descBuffer, uInt32Buffer);
uInt32ToCharLE(p_descBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
data = p_descriptionString.toUtf8();
@ -769,10 +796,6 @@ void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
ioDevice->seek(p_endOfFile + 260);
ioDevice->write("JEND", 4);
#if QT_VERSION >= 0x050000
ioDevice->aboutToClose();
#endif
}
}
@ -786,36 +809,36 @@ RagePhoto* RagePhoto::loadFile(const QString &filePath)
quint32 RagePhoto::charToUInt32BE(char *x)
{
return (static_cast<unsigned char>(x[0]) << 24 |
static_cast<unsigned char>(x[1]) << 16 |
static_cast<unsigned char>(x[2]) << 8 |
static_cast<unsigned char>(x[3]));
static_cast<unsigned char>(x[1]) << 16 |
static_cast<unsigned char>(x[2]) << 8 |
static_cast<unsigned char>(x[3]));
}
quint32 RagePhoto::charToUInt32LE(char *x)
{
return (static_cast<unsigned char>(x[3]) << 24 |
static_cast<unsigned char>(x[2]) << 16 |
static_cast<unsigned char>(x[1]) << 8 |
static_cast<unsigned char>(x[0]));
static_cast<unsigned char>(x[2]) << 16 |
static_cast<unsigned char>(x[1]) << 8 |
static_cast<unsigned char>(x[0]));
}
void RagePhoto::uInt32ToCharBE(quint32 *x, char *y)
void RagePhoto::uInt32ToCharBE(quint32 x, char *y)
{
y[0] = (*x >> 24) & 0xFF;
y[1] = (*x >> 16) & 0xFF;
y[2] = (*x >> 8) & 0xFF;
y[3] = (*x) & 0xFF;
y[0] = x >> 24;
y[1] = x >> 16;
y[2] = x >> 8;
y[3] = x;
}
void RagePhoto::uInt32ToCharLE(quint32 *x, char *y)
void RagePhoto::uInt32ToCharLE(quint32 x, char *y)
{
y[0] = (*x) & 0xFF;
y[1] = (*x >> 8) & 0xFF;
y[2] = (*x >> 16) & 0xFF;
y[3] = (*x >> 24) & 0xFF;
y[0] = x;
y[1] = x >> 8;
y[2] = x >> 16;
y[3] = x >> 24;
}
QByteArray RagePhoto::stringToUtf16LE(const QString &string)
const QByteArray RagePhoto::stringToUtf16LE(const QString &string)
{
#if QT_VERSION >= 0x060000
QStringEncoder stringEncoder = QStringEncoder(QStringEncoder::Utf16LE);
@ -825,7 +848,7 @@ QByteArray RagePhoto::stringToUtf16LE(const QString &string)
#endif
}
QString RagePhoto::utf16LEToString(const QByteArray &data)
const QString RagePhoto::utf16LEToString(const QByteArray &data)
{
#if QT_VERSION >= 0x060000
QStringDecoder stringDecoder = QStringDecoder(QStringDecoder::Utf16LE);
@ -835,7 +858,7 @@ QString RagePhoto::utf16LEToString(const QByteArray &data)
#endif
}
QString RagePhoto::utf16LEToString(const char *data, int size)
const QString RagePhoto::utf16LEToString(const char *data, int size)
{
#if QT_VERSION >= 0x060000
QStringDecoder stringDecoder = QStringDecoder(QStringDecoder::Utf16LE);

10
RagePhoto.h

@ -79,11 +79,11 @@ public:
private:
inline quint32 charToUInt32BE(char *x);
inline quint32 charToUInt32LE(char *x);
inline void uInt32ToCharBE(quint32 *x, char *y);
inline void uInt32ToCharLE(quint32 *x, char *y);
inline QByteArray stringToUtf16LE(const QString &string);
inline QString utf16LEToString(const QByteArray &data);
inline QString utf16LEToString(const char *data, int size);
inline void uInt32ToCharBE(quint32 x, char *y);
inline void uInt32ToCharLE(quint32 x, char *y);
inline const QByteArray stringToUtf16LE(const QString &string);
inline const QString utf16LEToString(const QByteArray &data);
inline const QString utf16LEToString(const char *data, int size);
PhotoFormat p_photoFormat;
QJsonObject p_jsonObject;
QByteArray p_fileData;

Loading…
Cancel
Save