From c9b33b324d1376bd4789bd92ee9380c8df023cc6 Mon Sep 17 00:00:00 2001 From: Syping Date: Fri, 27 Aug 2021 01:47:09 +0200 Subject: [PATCH] add codecvt support --- CMakeLists.txt | 63 +++++++++++++++++++++++++---------------- src/RagePhoto.cpp | 33 ++++++++-------------- src/RagePhoto.h | 1 - tests/CodecvtTest.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++ tests/IconvTest.cpp | 66 +++++++++++++++++++++++++++++++++---------- 5 files changed, 167 insertions(+), 62 deletions(-) create mode 100644 tests/CodecvtTest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ba6196..caa554b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,53 +5,68 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) -if (WIN32) +message("-- Testing codecvt") +try_run(CODECVT_RUN CODECVT_COMPILE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/tests/CodecvtTest.cpp) +if (CODECVT_COMPILE) list(APPEND LIBRAGEPHOTO_DEFINES - USE_WINAPI + CODECVT_COMPATIBLE ) + message("-- Testing codecvt - yes") +else() + message("-- Testing codecvt - no") endif() message("-- Testing iconv") try_run(ICONV_RUN ICONV_COMPILE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/tests/IconvTest.cpp) if (ICONV_COMPILE) list(APPEND LIBRAGEPHOTO_DEFINES - USE_ICONV + ICONV_COMPATIBLE ) message("-- Testing iconv - yes") else() message("-- Testing iconv - no") endif() -option(WITH_BENCHMARK "Benchmark RagePhoto Parsing Engine" OFF) +project(ragephoto LANGUAGES CXX) + +set(RAGEPHOTO_SOURCES + src/RagePhoto.cpp + src/RagePhoto.h +) +set(RAGEPHOTO_HEADERS + src/libragephoto_global.h + src/RagePhoto.h +) + +option(BUILD_SHARED "Build libragephoto as shared library" ON) +if (BUILD_SHARED) + add_library(ragephoto SHARED ${RAGEPHOTO_HEADERS} ${RAGEPHOTO_SOURCES}) + set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) +else() + add_library(ragephoto STATIC ${RAGEPHOTO_HEADERS} ${RAGEPHOTO_SOURCES}) +endif() + +option(WITH_BENCHMARK "Build with libragephoto benchmark" OFF) if (WITH_BENCHMARK) list(APPEND LIBRAGEPHOTO_DEFINES RAGEPHOTO_BENCHMARK ) endif() -project(ragephoto LANGUAGES CXX) -add_library(ragephoto SHARED - src/libragephoto_global.h - src/RagePhoto.cpp - src/RagePhoto.h -) target_compile_definitions(ragephoto PRIVATE LIBRAGEPHOTO_LIBRARY ${LIBRAGEPHOTO_DEFINES} ) install(TARGETS ragephoto DESTINATION lib) -install(FILES - src/RagePhoto.h - src/libragephoto_global.h - DESTINATION include -) -set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) +install(FILES ${RAGEPHOTO_HEADERS} DESTINATION include) -project(ragephoto-extract LANGUAGES CXX) -add_executable(ragephoto-extract - src/libragephoto_global.h - src/RagePhoto-Extract.cpp - src/RagePhoto.h -) -target_link_libraries(ragephoto-extract ragephoto) -install(TARGETS ragephoto-extract DESTINATION bin) +option(WITH_EXTRACT "Build ragephoto-extract" ON) +if (WITH_EXTRACT) + project(ragephoto-extract LANGUAGES CXX) + set(EXTRACT_SOURCES + src/RagePhoto-Extract.cpp + ) + add_executable(ragephoto-extract ${RAGEPHOTO_HEADERS} ${EXTRACT_SOURCES}) + target_link_libraries(ragephoto-extract ragephoto) + install(TARGETS ragephoto-extract DESTINATION bin) +endif() diff --git a/src/RagePhoto.cpp b/src/RagePhoto.cpp index 2624479..16a468e 100644 --- a/src/RagePhoto.cpp +++ b/src/RagePhoto.cpp @@ -25,8 +25,11 @@ #include #endif -#ifdef USE_ICONV -#include "iconv.h" +#ifdef CODECVT_COMPATIBLE +#include +#include +#elif defined ICONV_COMPATIBLE +#include #endif RagePhoto::RagePhoto() @@ -81,7 +84,12 @@ bool RagePhoto::load(const char *data, size_t length) return false; } -#ifdef USE_ICONV +#ifdef CODECVT_COMPATIBLE + char16_t photoHeader16[128]; + memcpy(photoHeader16, photoHeader, sizeof(char) * 256); + std::wstring_convert,char16_t> convert; + p_photoString = convert.to_bytes(photoHeader16); +#elif defined ICONV_COMPATIBLE iconv_t iconv_in = iconv_open("UTF-8", "UTF-16LE"); if (iconv_in == (iconv_t)-1) { p_error = Error::UnicodeInitError; // 4 @@ -336,19 +344,6 @@ const std::string RagePhoto::title() return p_titleString; } -size_t RagePhoto::readBuffer(const char *input, char *output, size_t *pos, size_t len) -{ -#ifdef READ_USE_FOR - for (size_t i = 0; i < len; i++) { - output[i] = input[*pos+i]; - } -#else - memcpy(output, &input[*pos], sizeof(char) * len); -#endif - *pos = *pos + len; - return len; -} - size_t RagePhoto::readBuffer(const char *input, char *output, size_t *pos, size_t len, size_t inputLen) { size_t readLen = 0; @@ -357,13 +352,7 @@ size_t RagePhoto::readBuffer(const char *input, char *output, size_t *pos, size_ readLen = inputLen - *pos; if (readLen > len) readLen = len; -#ifdef READ_USE_FOR - for (size_t i = 0; i < readLen; i++) { - output[i] = input[*pos+i]; - } -#else memcpy(output, &input[*pos], sizeof(char) * readLen); -#endif *pos = *pos + readLen; return readLen; } diff --git a/src/RagePhoto.h b/src/RagePhoto.h index 51e29ea..92c75d9 100644 --- a/src/RagePhoto.h +++ b/src/RagePhoto.h @@ -81,7 +81,6 @@ public: const std::string title(); private: - inline size_t readBuffer(const char *input, char *output, size_t *pos, size_t len); inline size_t readBuffer(const char *input, char *output, size_t *pos, size_t len, size_t inputLen); inline uint32_t charToUInt32BE(char *x); inline uint32_t charToUInt32LE(char *x); diff --git a/tests/CodecvtTest.cpp b/tests/CodecvtTest.cpp new file mode 100644 index 0000000..5e7750e --- /dev/null +++ b/tests/CodecvtTest.cpp @@ -0,0 +1,66 @@ +/***************************************************************************** +* libragephoto RAGE Photo Parser +* Copyright (C) 2021 Syping +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* This software is provided as-is, no warranties are given to you, we are not +* responsible for anything with use of the software, you are self responsible. +*****************************************************************************/ + +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + const char photoHeader[256] = { + 0x50, 0x00, 0x48, 0x00, 0x4f, 0x00, 0x54, 0x00, + 0x4f, 0x00, 0x20, 0x00, 0x2d, 0x00, 0x20, 0x00, + 0x30, 0x00, 0x32, 0x00, 0x2f, 0x00, 0x30, 0x00, + 0x31, 0x00, 0x2f, 0x00, 0x31, 0x00, 0x37, 0x00, + 0x20, 0x00, 0x30, 0x00, 0x38, 0x00, 0x3a, 0x00, + 0x34, 0x00, 0x32, 0x00, 0x3a, 0x00, 0x34, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + char16_t photoHeader16[128]; + memcpy(photoHeader16, photoHeader, sizeof(char) * 256); + std::wstring_convert,char16_t> convert; + std::string photoString = convert.to_bytes(photoHeader16); + std::cout << photoString << std::endl; + return strcmp(photoString.c_str(), "PHOTO - 02/01/17 08:42:44"); +} diff --git a/tests/IconvTest.cpp b/tests/IconvTest.cpp index 0357d8a..98549e4 100644 --- a/tests/IconvTest.cpp +++ b/tests/IconvTest.cpp @@ -16,22 +16,58 @@ * responsible for anything with use of the software, you are self responsible. *****************************************************************************/ -#include "iconv.h" -#include "stdio.h" +#include +#include +#include int main(int argc, char *argv[]) { - iconv_t instance = iconv_open("UTF-16LE", "UTF-8"); - if (instance == (iconv_t)-1) - return 1; - char src[] = "Test"; - char dst[256]; - size_t src_s = sizeof(src); - size_t dst_s = sizeof(dst); - char *isrc = src; - char *idst = dst; - iconv(instance, &isrc, &src_s, &idst, &dst_s); - iconv_close(instance); - printf("%s\n", dst); - return 0; + char photoHeader[256] = { + 0x50, 0x00, 0x48, 0x00, 0x4f, 0x00, 0x54, 0x00, + 0x4f, 0x00, 0x20, 0x00, 0x2d, 0x00, 0x20, 0x00, + 0x30, 0x00, 0x32, 0x00, 0x2f, 0x00, 0x30, 0x00, + 0x31, 0x00, 0x2f, 0x00, 0x31, 0x00, 0x37, 0x00, + 0x20, 0x00, 0x30, 0x00, 0x38, 0x00, 0x3a, 0x00, + 0x34, 0x00, 0x32, 0x00, 0x3a, 0x00, 0x34, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + char photoString[256]; + iconv_t iconv_in = iconv_open("UTF-8", "UTF-16LE"); + if (iconv_in == (iconv_t)-1) + return -1; + size_t src_s = sizeof(photoHeader); + size_t dst_s = sizeof(photoString); + char *src = photoHeader; + char *dst = photoString; + size_t ret = iconv(iconv_in, &src, &src_s, &dst, &dst_s); + iconv_close(iconv_in); + if (ret == static_cast(-1)) { + return -1; + } + return strcmp(photoString, "PHOTO - 02/01/17 08:42:44"); }