From d13c22dc05c2c097e757370be2e328312133ccfc Mon Sep 17 00:00:00 2001 From: Syping Date: Mon, 20 Feb 2023 11:56:23 +0100 Subject: [PATCH] RagePhoto: add clear() and load() as static functions --- src/RagePhoto.cpp | 298 ++++++++++++++++++++++++---------------------- src/RagePhoto.h | 4 +- 2 files changed, 157 insertions(+), 145 deletions(-) diff --git a/src/RagePhoto.cpp b/src/RagePhoto.cpp index d38da1f..b248f4f 100644 --- a/src/RagePhoto.cpp +++ b/src/RagePhoto.cpp @@ -164,15 +164,20 @@ void RagePhoto::addParser(RagePhotoFormatParser *rp_parser) } } +void RagePhoto::clear(RagePhotoData *rp_data) +{ + std::free(rp_data->jpeg); + std::free(rp_data->description); + std::free(rp_data->json); + std::free(rp_data->header); + std::free(rp_data->title); + std::memset(rp_data, 0, sizeof(RagePhotoData)); + setBufferDefault(rp_data); +} + void RagePhoto::clear() { - std::free(m_data->jpeg); - std::free(m_data->description); - std::free(m_data->json); - std::free(m_data->header); - std::free(m_data->title); - std::memset(m_data, 0, sizeof(RagePhotoData)); - setBufferDefault(); + clear(m_data); } RagePhotoData* RagePhoto::data() @@ -180,34 +185,34 @@ RagePhotoData* RagePhoto::data() return m_data; } -bool RagePhoto::load(const char *data, size_t length) +bool RagePhoto::load(RagePhotoData *rp_data, RagePhotoFormatParser *rp_parser, const char *data, size_t length) { #ifdef RAGEPHOTO_BENCHMARK auto benchmark_parse_start = std::chrono::high_resolution_clock::now(); #endif // Avoid data conflicts - clear(); + clear(rp_data); size_t pos = 0; char uInt32Buffer[4]; size_t size = readBuffer(data, uInt32Buffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::NoFormatIdentifier; // 1 + rp_data->error = Error::NoFormatIdentifier; // 1 return false; } #if __BYTE_ORDER == __LITTLE_ENDIAN - std::memcpy(&m_data->photoFormat, uInt32Buffer, 4); + std::memcpy(&rp_data->photoFormat, uInt32Buffer, 4); #else - m_data->photoFormat = charToUInt32LE(uInt32Buffer); + rp_data->photoFormat = charToUInt32LE(uInt32Buffer); #endif - if (m_data->photoFormat == PhotoFormat::GTA5 || m_data->photoFormat == PhotoFormat::RDR2) { + if (rp_data->photoFormat == PhotoFormat::GTA5 || rp_data->photoFormat == PhotoFormat::RDR2) { #if defined UNICODE_ICONV || defined UNICODE_CODECVT || defined UNICODE_WINCVT char photoHeader[256]; size = readBuffer(data, photoHeader, &pos, 256, length); if (size != 256) { - m_data->error = Error::IncompleteHeader; // 3 + rp_data->error = Error::IncompleteHeader; // 3 return false; } @@ -215,291 +220,291 @@ bool RagePhoto::load(const char *data, size_t length) std::wstring_convert,char16_t> convert; const std::string photoHeader_string = convert.to_bytes(reinterpret_cast(photoHeader)); if (convert.converted() == 0) { - m_data->error = Error::UnicodeHeaderError; // 6 + rp_data->error = Error::UnicodeHeaderError; // 6 return false; } const size_t photoHeader_size = photoHeader_string.size() + 1; - m_data->header = static_cast(std::malloc(photoHeader_size)); - if (!m_data->header) { - m_data->error = Error::HeaderMallocError; // 4 + rp_data->header = static_cast(std::malloc(photoHeader_size)); + if (!rp_data->header) { + rp_data->error = Error::HeaderMallocError; // 4 return false; } - std::memcpy(m_data->header, photoHeader_string.c_str(), photoHeader_size); + std::memcpy(rp_data->header, photoHeader_string.c_str(), photoHeader_size); #elif defined UNICODE_ICONV iconv_t iconv_in = iconv_open("UTF-8", "UTF-16LE"); if (iconv_in == (iconv_t)-1) { - m_data->error = Error::UnicodeInitError; // 4 + rp_data->error = Error::UnicodeInitError; // 4 return false; } - m_data->header = static_cast(std::malloc(256)); - if (!m_data->header) { - m_data->error = Error::HeaderMallocError; // 4 + rp_data->header = static_cast(std::malloc(256)); + if (!rp_data->header) { + rp_data->error = Error::HeaderMallocError; // 4 iconv_close(iconv_in); return false; } size_t src_s = sizeof(photoHeader); size_t dst_s = 256; char *src = photoHeader; - char *dst = m_data->header; + char *dst = rp_data->header; const size_t ret = iconv(iconv_in, &src, &src_s, &dst, &dst_s); iconv_close(iconv_in); if (ret == static_cast(-1)) { - m_data->error = Error::UnicodeHeaderError; // 6 + rp_data->error = Error::UnicodeHeaderError; // 6 return false; } #elif defined UNICODE_WINCVT - m_data->header = static_cast(std::malloc(256)); - if (!m_data->header) { - m_data->error = Error::HeaderMallocError; // 4 + rp_data->header = static_cast(std::malloc(256)); + if (!rp_data->header) { + rp_data->error = Error::HeaderMallocError; // 4 return false; } - const int converted = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast(photoHeader), -1, m_data->header, 256, NULL, NULL); + const int converted = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast(photoHeader), -1, rp_data->header, 256, NULL, NULL); if (converted == 0) { - std::free(m_data->header); - m_data->header = nullptr; - m_data->error = Error::UnicodeHeaderError; // 6 + std::free(rp_data->header); + rp_data->header = nullptr; + rp_data->error = Error::UnicodeHeaderError; // 6 return false; } #endif size = readBuffer(data, uInt32Buffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteChecksum; // 7 + rp_data->error = Error::IncompleteChecksum; // 7 return false; } #if __BYTE_ORDER == __LITTLE_ENDIAN - std::memcpy(&m_data->headerSum, uInt32Buffer, 4); + std::memcpy(&rp_data->headerSum, uInt32Buffer, 4); #else - m_data->headerSum = charToUInt32LE(uInt32Buffer); + rp_data->headerSum = charToUInt32LE(uInt32Buffer); #endif - if (m_data->photoFormat == PhotoFormat::RDR2) { + if (rp_data->photoFormat == PhotoFormat::RDR2) { size = readBuffer(data, uInt32Buffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteChecksum; // 7 + rp_data->error = Error::IncompleteChecksum; // 7 return false; } #if __BYTE_ORDER == __LITTLE_ENDIAN - std::memcpy(&m_data->unnamedSum1, uInt32Buffer, 4); + std::memcpy(&rp_data->unnamedSum1, uInt32Buffer, 4); #else - m_data->unnamedSum1 = charToUInt32LE(uInt32Buffer); + rp_data->unnamedSum1 = charToUInt32LE(uInt32Buffer); #endif size = readBuffer(data, uInt32Buffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteChecksum; // 7 + rp_data->error = Error::IncompleteChecksum; // 7 return false; } #if __BYTE_ORDER == __LITTLE_ENDIAN - std::memcpy(&m_data->unnamedSum2, uInt32Buffer, 4); + std::memcpy(&rp_data->unnamedSum2, uInt32Buffer, 4); #else - m_data->unnamedSum2 = charToUInt32LE(uInt32Buffer); + rp_data->unnamedSum2 = charToUInt32LE(uInt32Buffer); #endif } const size_t headerSize = pos; size = readBuffer(data, uInt32Buffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteEOF; // 8 + rp_data->error = Error::IncompleteEOF; // 8 return false; } #if __BYTE_ORDER == __LITTLE_ENDIAN - std::memcpy(&m_data->endOfFile, uInt32Buffer, 4); + std::memcpy(&rp_data->endOfFile, uInt32Buffer, 4); #else - m_data->endOfFile = charToUInt32LE(uInt32Buffer); + rp_data->endOfFile = charToUInt32LE(uInt32Buffer); #endif size = readBuffer(data, uInt32Buffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteJsonOffset; // 9 + rp_data->error = Error::IncompleteJsonOffset; // 9 return false; } #if __BYTE_ORDER == __LITTLE_ENDIAN - std::memcpy(&m_data->jsonOffset, uInt32Buffer, 4); + std::memcpy(&rp_data->jsonOffset, uInt32Buffer, 4); #else - m_data->jsonOffset = charToUInt32LE(uInt32Buffer); + rp_data->jsonOffset = charToUInt32LE(uInt32Buffer); #endif size = readBuffer(data, uInt32Buffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteTitleOffset; // 10 + rp_data->error = Error::IncompleteTitleOffset; // 10 return false; } #if __BYTE_ORDER == __LITTLE_ENDIAN - std::memcpy(&m_data->titlOffset, uInt32Buffer, 4); + std::memcpy(&rp_data->titlOffset, uInt32Buffer, 4); #else - m_data->titlOffset = charToUInt32LE(uInt32Buffer); + rp_data->titlOffset = charToUInt32LE(uInt32Buffer); #endif size = readBuffer(data, uInt32Buffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteDescOffset; // 11 + rp_data->error = Error::IncompleteDescOffset; // 11 return false; } #if __BYTE_ORDER == __LITTLE_ENDIAN - std::memcpy(&m_data->descOffset, uInt32Buffer, 4); + std::memcpy(&rp_data->descOffset, uInt32Buffer, 4); #else - m_data->descOffset = charToUInt32LE(uInt32Buffer); + rp_data->descOffset = charToUInt32LE(uInt32Buffer); #endif char markerBuffer[4]; size = readBuffer(data, markerBuffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteJpegMarker; // 12 + rp_data->error = Error::IncompleteJpegMarker; // 12 return false; } if (strncmp(markerBuffer, "JPEG", 4) != 0) { - m_data->error = Error::IncorrectJpegMarker; // 13 + rp_data->error = Error::IncorrectJpegMarker; // 13 return false; } size = readBuffer(data, uInt32Buffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompletePhotoBuffer; // 14 + rp_data->error = Error::IncompletePhotoBuffer; // 14 return false; } #if __BYTE_ORDER == __LITTLE_ENDIAN - std::memcpy(&m_data->jpegBuffer, uInt32Buffer, 4); + std::memcpy(&rp_data->jpegBuffer, uInt32Buffer, 4); #else - m_data->jpegBuffer = charToUInt32LE(uInt32Buffer); + rp_data->jpegBuffer = charToUInt32LE(uInt32Buffer); #endif size = readBuffer(data, uInt32Buffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompletePhotoSize; // 15 + rp_data->error = Error::IncompletePhotoSize; // 15 return false; } #if __BYTE_ORDER == __LITTLE_ENDIAN - std::memcpy(&m_data->jpegSize, uInt32Buffer, 4); + std::memcpy(&rp_data->jpegSize, uInt32Buffer, 4); #else - m_data->jpegSize = charToUInt32LE(uInt32Buffer); + rp_data->jpegSize = charToUInt32LE(uInt32Buffer); #endif - m_data->jpeg = static_cast(std::malloc(m_data->jpegSize)); - if (!m_data->jpeg) { - m_data->error = Error::PhotoMallocError; // 16 + rp_data->jpeg = static_cast(std::malloc(rp_data->jpegSize)); + if (!rp_data->jpeg) { + rp_data->error = Error::PhotoMallocError; // 16 return false; } - size = readBuffer(data, m_data->jpeg, &pos, m_data->jpegSize, length); - if (size != m_data->jpegSize) { - std::free(m_data->jpeg); - m_data->jpeg = nullptr; - m_data->error = Error::PhotoReadError; // 17 + size = readBuffer(data, rp_data->jpeg, &pos, rp_data->jpegSize, length); + if (size != rp_data->jpegSize) { + std::free(rp_data->jpeg); + rp_data->jpeg = nullptr; + rp_data->error = Error::PhotoReadError; // 17 return false; } - pos = m_data->jsonOffset + headerSize; + pos = rp_data->jsonOffset + headerSize; size = readBuffer(data, markerBuffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteJsonMarker; // 18 + rp_data->error = Error::IncompleteJsonMarker; // 18 return false; } if (strncmp(markerBuffer, "JSON", 4) != 0) { - m_data->error = Error::IncorrectJsonMarker; // 19 + rp_data->error = Error::IncorrectJsonMarker; // 19 return false; } size = readBuffer(data, uInt32Buffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteJsonBuffer; // 20 + rp_data->error = Error::IncompleteJsonBuffer; // 20 return false; } #if __BYTE_ORDER == __LITTLE_ENDIAN - std::memcpy(&m_data->jsonBuffer, uInt32Buffer, 4); + std::memcpy(&rp_data->jsonBuffer, uInt32Buffer, 4); #else - m_data->jsonBuffer = charToUInt32LE(uInt32Buffer); + rp_data->jsonBuffer = charToUInt32LE(uInt32Buffer); #endif - m_data->json = static_cast(std::malloc(m_data->jsonBuffer)); - if (!m_data->json) { - m_data->error = Error::JsonMallocError; // 21 + rp_data->json = static_cast(std::malloc(rp_data->jsonBuffer)); + if (!rp_data->json) { + rp_data->error = Error::JsonMallocError; // 21 return false; } - size = readBuffer(data, m_data->json, &pos, m_data->jsonBuffer, length); - if (size != m_data->jsonBuffer) { - std::free(m_data->json); - m_data->json = nullptr; - m_data->error = Error::JsonReadError; // 22 + size = readBuffer(data, rp_data->json, &pos, rp_data->jsonBuffer, length); + if (size != rp_data->jsonBuffer) { + std::free(rp_data->json); + rp_data->json = nullptr; + rp_data->error = Error::JsonReadError; // 22 return false; } - pos = m_data->titlOffset + headerSize; + pos = rp_data->titlOffset + headerSize; size = readBuffer(data, markerBuffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteTitleMarker; // 23 + rp_data->error = Error::IncompleteTitleMarker; // 23 return false; } if (strncmp(markerBuffer, "TITL", 4) != 0) { - m_data->error = Error::IncorrectTitleMarker; // 24 + rp_data->error = Error::IncorrectTitleMarker; // 24 return false; } size = readBuffer(data, uInt32Buffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteTitleBuffer; // 25 + rp_data->error = Error::IncompleteTitleBuffer; // 25 return false; } #if __BYTE_ORDER == __LITTLE_ENDIAN - std::memcpy(&m_data->titlBuffer, uInt32Buffer, 4); + std::memcpy(&rp_data->titlBuffer, uInt32Buffer, 4); #else - m_data->titlBuffer = charToUInt32LE(uInt32Buffer); + rp_data->titlBuffer = charToUInt32LE(uInt32Buffer); #endif - m_data->title = static_cast(std::malloc(m_data->titlBuffer)); - if (!m_data->title) { - m_data->error = Error::TitleMallocError; // 26 + rp_data->title = static_cast(std::malloc(rp_data->titlBuffer)); + if (!rp_data->title) { + rp_data->error = Error::TitleMallocError; // 26 return false; } - size = readBuffer(data, m_data->title, &pos, m_data->titlBuffer, length); - if (size != m_data->titlBuffer) { - std::free(m_data->title); - m_data->title = nullptr; - m_data->error = Error::TitleReadError; // 27 + size = readBuffer(data, rp_data->title, &pos, rp_data->titlBuffer, length); + if (size != rp_data->titlBuffer) { + std::free(rp_data->title); + rp_data->title = nullptr; + rp_data->error = Error::TitleReadError; // 27 return false; } - pos = m_data->descOffset + headerSize; + pos = rp_data->descOffset + headerSize; size = readBuffer(data, markerBuffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteDescMarker; // 28 + rp_data->error = Error::IncompleteDescMarker; // 28 return false; } if (strncmp(markerBuffer, "DESC", 4) != 0) { - m_data->error = Error::IncorrectDescMarker; // 29 + rp_data->error = Error::IncorrectDescMarker; // 29 return false; } size = readBuffer(data, uInt32Buffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteDescBuffer; // 30 + rp_data->error = Error::IncompleteDescBuffer; // 30 return false; } #if __BYTE_ORDER == __LITTLE_ENDIAN - std::memcpy(&m_data->descBuffer, uInt32Buffer, 4); + std::memcpy(&rp_data->descBuffer, uInt32Buffer, 4); #else - m_data->descBuffer = charToUInt32LE(uInt32Buffer); + rp_data->descBuffer = charToUInt32LE(uInt32Buffer); #endif - m_data->description = static_cast(std::malloc(m_data->descBuffer)); - if (!m_data->description) { - m_data->error = Error::DescMallocError; // 31 + rp_data->description = static_cast(std::malloc(rp_data->descBuffer)); + if (!rp_data->description) { + rp_data->error = Error::DescMallocError; // 31 return false; } - size = readBuffer(data, m_data->description, &pos, m_data->descBuffer, length); - if (size != m_data->descBuffer) { - std::free(m_data->description); - m_data->description = nullptr; - m_data->error = Error::DescReadError; // 32 + size = readBuffer(data, rp_data->description, &pos, rp_data->descBuffer, length); + if (size != rp_data->descBuffer) { + std::free(rp_data->description); + rp_data->description = nullptr; + rp_data->error = Error::DescReadError; // 32 return false; } - pos = m_data->endOfFile + headerSize - 4; + pos = rp_data->endOfFile + headerSize - 4; size = readBuffer(data, markerBuffer, &pos, 4, length); if (size != 4) { - m_data->error = Error::IncompleteJendMarker; // 33 + rp_data->error = Error::IncompleteJendMarker; // 33 return false; } if (strncmp(markerBuffer, "JEND", 4) != 0) { - m_data->error = Error::IncorrectJendMarker; // 34 + rp_data->error = Error::IncorrectJendMarker; // 34 return false; } @@ -510,51 +515,56 @@ bool RagePhoto::load(const char *data, size_t length) #endif #ifdef RAGEPHOTO_DEBUG - std::cout << "header: " << m_data->header << std::endl; - std::cout << "headerSum: " << m_data->headerSum << std::endl; - std::cout << "unnamedSum1: " << m_data->unnamedSum1 << std::endl; - std::cout << "unnamedSum2: " << m_data->unnamedSum2 << std::endl; - std::cout << "photoBuffer: " << m_data->jpegBuffer << std::endl; - std::cout << "descBuffer: " << m_data->descBuffer << std::endl; - std::cout << "descOffset: " << m_data->descOffset << std::endl; - std::cout << "description: " << m_data->description << std::endl; - std::cout << "jsonBuffer: " << m_data->jsonBuffer << std::endl; - std::cout << "jsonOffset: " << m_data->jsonOffset << std::endl; - std::cout << "json: " << m_data->json << std::endl; - std::cout << "titlBuffer: " << m_data->titlBuffer << std::endl; - std::cout << "titlOffset: " << m_data->titlOffset << std::endl; - std::cout << "title: " << m_data->title << std::endl; - std::cout << "eofOffset: " << m_data->endOfFile << std::endl; + std::cout << "header: " << rp_data->header << std::endl; + std::cout << "headerSum: " << rp_data->headerSum << std::endl; + std::cout << "unnamedSum1: " << rp_data->unnamedSum1 << std::endl; + std::cout << "unnamedSum2: " << rp_data->unnamedSum2 << std::endl; + std::cout << "photoBuffer: " << rp_data->jpegBuffer << std::endl; + std::cout << "descBuffer: " << rp_data->descBuffer << std::endl; + std::cout << "descOffset: " << rp_data->descOffset << std::endl; + std::cout << "description: " << rp_data->description << std::endl; + std::cout << "jsonBuffer: " << rp_data->jsonBuffer << std::endl; + std::cout << "jsonOffset: " << rp_data->jsonOffset << std::endl; + std::cout << "json: " << rp_data->json << std::endl; + std::cout << "titlBuffer: " << rp_data->titlBuffer << std::endl; + std::cout << "titlOffset: " << rp_data->titlOffset << std::endl; + std::cout << "title: " << rp_data->title << std::endl; + std::cout << "eofOffset: " << rp_data->endOfFile << std::endl; std::cout << "setBufferOffsets()" << std::endl; - setBufferOffsets(); - std::cout << "descOffset: " << m_data->descOffset << std::endl; - std::cout << "jsonOffset: " << m_data->jsonOffset << std::endl; - std::cout << "titlOffset: " << m_data->titlOffset << std::endl; - std::cout << "eofOffset: " << m_data->endOfFile << std::endl; - std::cout << "calc size: " << saveSize() << std::endl; + setBufferOffsets(rp_data); + std::cout << "descOffset: " << rp_data->descOffset << std::endl; + std::cout << "jsonOffset: " << rp_data->jsonOffset << std::endl; + std::cout << "titlOffset: " << rp_data->titlOffset << std::endl; + std::cout << "eofOffset: " << rp_data->endOfFile << std::endl; + std::cout << "calc size: " << saveSize(rp_data, rp_parser) << std::endl; std::cout << "real size: " << length << std::endl; #endif - m_data->error = Error::NoError; // 255 + rp_data->error = Error::NoError; // 255 return true; #else std::cout << "UTF-16LE decoding support missing" << std::endl; - m_data->error = Error::UnicodeInitError; // 4 + rp_data->error = Error::UnicodeInitError; // 4 return false; #endif } - else if (m_parser) { + else if (rp_parser) { RagePhotoFormatParser n_parser[1]{}; - for (size_t i = 0; std::memcmp(&n_parser[0], &m_parser[i], sizeof(RagePhotoFormatParser)); i++) { - if (m_data->photoFormat == m_parser[i].photoFormat) - if (m_parser[i].funcLoad) - return (m_parser[i].funcLoad)(m_data, data, length); + for (size_t i = 0; std::memcmp(&n_parser[0], &rp_parser[i], sizeof(RagePhotoFormatParser)); i++) { + if (rp_data->photoFormat == rp_parser[i].photoFormat) + if (rp_parser[i].funcLoad) + return (rp_parser[i].funcLoad)(rp_data, data, length); } } - m_data->error = Error::IncompatibleFormat; // 2 + rp_data->error = Error::IncompatibleFormat; // 2 return false; } +bool RagePhoto::load(const char *data, size_t length) +{ + return load(m_data, m_parser, data, length); +} + bool RagePhoto::load(const std::string &data) { return load(data.data(), data.size()); diff --git a/src/RagePhoto.h b/src/RagePhoto.h index cf01346..1a0ca28 100644 --- a/src/RagePhoto.h +++ b/src/RagePhoto.h @@ -95,8 +95,10 @@ public: RagePhoto(); ~RagePhoto(); void addParser(RagePhotoFormatParser *rp_parser); /**< Add a custom defined RagePhotoFormatParser. */ - void clear(); /**< Resets the RagePhoto instance to default values. */ + static void clear(RagePhotoData *rp_data); /**< Resets the RagePhotoData object to default values. */ + void clear(); /**< Resets the RagePhotoData object to default values. */ RagePhotoData* data(); /**< Returns the internal RagePhotoData object. */ + static bool load(RagePhotoData *rp_data, RagePhotoFormatParser *rp_parser, const char *data, size_t size); /**< Loads a Photo from a const char*. */ /** Loads a Photo from a const char*. * \param data Photo data * \param size Photo data size