add RAGEPHOTO_BENCHMARK for parser benchmarks
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		
							parent
							
								
									23e9c48248
								
							
						
					
					
						commit
						b747f7cda5
					
				
					 2 changed files with 98 additions and 75 deletions
				
			
		
							
								
								
									
										163
									
								
								RagePhoto.cpp
									
										
									
									
									
								
							
							
						
						
									
										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
									
										
									
									
									
								
							
							
						
						
									
										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…
	
	Add table
		Add a link
		
	
		Reference in a new issue