diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml index a69d4f8..573768a 100644 --- a/.github/workflows/cmake-multi-platform.yml +++ b/.github/workflows/cmake-multi-platform.yml @@ -1,85 +1,88 @@ -# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform. -# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml name: CMake on multiple platforms on: push: - branches: [ "master"] + branches: [ "master" ] pull_request: - branches: [ "master"] + branches: [ "master" ] jobs: build: runs-on: ${{ matrix.os }} strategy: - # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable. fail-fast: true - - # Set up a matrix to run the following 3 configurations: - # 1. - # 2. - # 3. - # - # To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list. matrix: - os: [windows-latest, ubuntu-latest] + os: [ubuntu-latest, windows-latest] build_type: [Release] - c_compiler: [gcc, clang, cl] + c_compiler: [gcc, clang, cl, x86_64-w64-mingw32-gcc] + include: - os: windows-latest c_compiler: cl cpp_compiler: cl + exe_suffix: .exe + mingw: false + - os: ubuntu-latest c_compiler: gcc cpp_compiler: g++ + exe_suffix: "" + mingw: false + - os: ubuntu-latest c_compiler: clang cpp_compiler: clang++ + exe_suffix: "" + mingw: false + + - os: ubuntu-latest + c_compiler: x86_64-w64-mingw32-gcc + cpp_compiler: x86_64-w64-mingw32-g++ + exe_suffix: .exe + mingw: true + exclude: - - os: windows-latest + - os: windows-2025-vs2026 c_compiler: gcc - os: windows-latest c_compiler: clang + - os: windows-latest + c_compiler: x86_64-w64-mingw32-gcc - os: ubuntu-latest c_compiler: cl steps: - - uses: actions/checkout@v3 - - - name: Git update submodules - run: | - git submodule update --init --recursive --depth 1 + - uses: actions/checkout@v3 + + - name: Install MinGW (only if mingw is true) + if: matrix.mingw == true + run: | + sudo apt-get update + sudo apt-get install -y mingw-w64 - - name: Set reusable strings - # Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file. - id: strings - shell: bash - run: | - echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" + - name: Update submodules + run: git submodule update --init --recursive --depth 1 - - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: > - cmake -B ${{ steps.strings.outputs.build-output-dir }} - -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} - -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} - -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} - -S ${{ github.workspace }} + - name: Set build directory + id: vars + run: echo "dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" - - name: Build - # Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). - run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }} + - name: Configure CMake + run: > + cmake -S . -B ${{ github.workspace }}/build + -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} + -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} + ${{ matrix.mingw && '-DCMAKE_TOOLCHAIN_FILE=mingw-w64-x86_64.cmake' || '' }} - - name: Test windows - working-directory: ${{ steps.strings.outputs.build-output-dir }}/Example/Release - if: matrix.os == 'windows-latest' - run: | - ./ImageLoaderExample.exe + - name: Build + run: cmake --build ${{ github.workspace }}/build --config ${{ matrix.build_type }} - - name: Test Ubuntu - working-directory: ${{ steps.strings.outputs.build-output-dir }}/Example - if: matrix.os == 'ubuntu-latest' - run: | - ./ImageLoaderExample + - name: Run tests + if: matrix.mingw == false + working-directory: >- + ${{ github.workspace }}/build/Example${{ + matrix.os == 'windows-latest' && format('/{0}', matrix.build_type) || '' + }} + run: ./ImageLoaderExample${{ matrix.exe_suffix }} diff --git a/.gitmodules b/.gitmodules index c9ce7b5..95d478c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,19 +9,19 @@ url = https://github.com/TheNicker/libpsd.git [submodule "External/libpng"] path = External/libpng - url = https://github.com/OpenImageViewer/libpng.git + url = https://github.com/lib-apng/libapng.git [submodule "External/zlib"] path = External/zlib - url = https://github.com/OpenImageViewer/zlib.git + url = https://github.com/madler/zlib.git [submodule "External/libgif"] path = External/libgif url = https://github.com/OpenImageViewer/libgif.git [submodule "External/libtiff"] path = External/libtiff - url = https://github.com/OpenImageViewer/libtiff.git + url = https://gitlab.com/libtiff/libtiff.git [submodule "External/libjpeg-turbo"] path = External/libjpeg-turbo - url = https://github.com/OpenImageViewer/libjpeg-turbo.git + url = https://github.com/libjpeg-turbo/libjpeg-turbo.git [submodule "External/bintools"] path = External/bintools url = https://github.com/OpenImageViewer/bintools.git @@ -34,3 +34,6 @@ [submodule "External/ExoticNumbers"] path = External/ExoticNumbers url = https://github.com/OpenImageViewer/ExoticNumbers.git +[submodule "External/FreeImageRe"] + path = External/FreeImageRe + url = https://github.com/agruzdev/FreeImageRe.git diff --git a/CMakeLists.txt b/CMakeLists.txt index ca84a8d..91b7f4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.8) +cmake_minimum_required (VERSION 3.10) project(ImageCodec) #Image Codec @@ -31,7 +31,7 @@ option(IMCODEC_BUILD_CODEC_GIF "Build Codec GIF" TRUE) option(IMCODEC_BUILD_CODEC_ICON "Build Codec Icon" TRUE) option(IMCODEC_BUILD_CODEC_TIFF "Build Codec TIFF" TRUE) option(IMCODEC_BUILD_CODEC_WEBP "Build Codec WEBP" TRUE) -option(IMCODEC_BUILD_CODEC_FREEIMAGE "Build Codec FREEIMAGE" FALSE) +option(IMCODEC_BUILD_CODEC_FREEIMAGE "Build Codec FREEIMAGE" TRUE) option(IMCODEC_BUILD_EXAMPLES "Build Examples" TRUE) @@ -92,4 +92,4 @@ endif() if (IMCODEC_BUILD_EXAMPLES AND IMCODEC_BUILD_CODEC_JPG AND IMCODEC_BUILD_CODEC_PNG) add_subdirectory(Example) -endif() \ No newline at end of file +endif() diff --git a/Codecs/CMakeLists.txt b/Codecs/CMakeLists.txt index 2d4371c..ded72da 100644 --- a/Codecs/CMakeLists.txt +++ b/Codecs/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION 3.10) if ( ${IMCODEC_BUILD_CODEC_BMP}) add_subdirectory(CodecBMP) diff --git a/Codecs/CodecBMP/CMakeLists.txt b/Codecs/CodecBMP/CMakeLists.txt index caa7a54..4a40e82 100644 --- a/Codecs/CodecBMP/CMakeLists.txt +++ b/Codecs/CodecBMP/CMakeLists.txt @@ -1,5 +1,5 @@ #Codec Icon -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION 3.10) project(CodecBMP) diff --git a/Codecs/CodecDDS/CMakeLists.txt b/Codecs/CodecDDS/CMakeLists.txt index c67d9b3..0284c9a 100644 --- a/Codecs/CodecDDS/CMakeLists.txt +++ b/Codecs/CodecDDS/CMakeLists.txt @@ -1,5 +1,5 @@ #Codec DDS -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION 3.10) project(CodecDDS) diff --git a/Codecs/CodecFreeImage/CMakeLists.txt b/Codecs/CodecFreeImage/CMakeLists.txt index cfbceb4..635ab18 100644 --- a/Codecs/CodecFreeImage/CMakeLists.txt +++ b/Codecs/CodecFreeImage/CMakeLists.txt @@ -1,6 +1,6 @@ #CodecFreeImage -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION 3.10) # Add source to this project's executable. file(GLOB_RECURSE sourceFiles @@ -10,11 +10,17 @@ file(GLOB_RECURSE sourceFiles set(TargetName CodecFreeImage) add_library (${TargetName} STATIC ${sourceFiles}) -target_link_libraries(${TargetName} d:/DevelopmentExternal/FreeImage3180Win32Win64/FreeImage/Dist/x64/FreeImage.lib) -include_directories(D:/DevelopmentExternal/FreeImage3180Win32Win64/FreeImage/Dist/x64) -#FreeImage from source -#set(FreeImageFolder ../../External/FreeImage) -#add_subdirectory(${FreeImageFolder} ./External/FreeImage) -#target_include_directories(${TargetName} PRIVATE ${FreeImageFolder}/Source) -#target_link_libraries(${TargetName} PRIVATE FreeImage) \ No newline at end of file +set(FreeImageReFolder ${CMAKE_CURRENT_LIST_DIR}/../../External/FreeImageRe) +set(EXTERNALPROJECT_SOURCE_ROOT ${CMAKE_CURRENT_BINARY_DIR}/External/FreeImageRe/dependencies/source CACHE PATH "FreeImageRe dependency source directory") +set(EXTERNALPROJECT_BINARY_ROOT ${CMAKE_CURRENT_BINARY_DIR}/External/FreeImageRe/dependencies/build CACHE PATH "FreeImageRe dependency build directory") +foreach(FreeImageReBackend LIBJPEG LIBOPENJPEG LIBOPENEXR LIBPNG LIBTIFF LIBWEBP LIBRAW LIBHEIF LIBJPEGXL) + set(FREEIMAGE_WITH_${FreeImageReBackend} OFF CACHE BOOL "Compile FreeImageRe with the ${FreeImageReBackend} backend" FORCE) +endforeach() + +if(NOT TARGET FreeImage) + add_subdirectory(${FreeImageReFolder} ${CMAKE_CURRENT_BINARY_DIR}/External/FreeImageRe) +endif() + +target_include_directories(${TargetName} PRIVATE ${FreeImageReFolder}/Source) +target_link_libraries(${TargetName} PRIVATE FreeImage) diff --git a/Codecs/CodecFreeImage/Source/CodecFreeImage.h b/Codecs/CodecFreeImage/Source/CodecFreeImage.h index 63ae70c..b4f0ba2 100644 --- a/Codecs/CodecFreeImage/Source/CodecFreeImage.h +++ b/Codecs/CodecFreeImage/Source/CodecFreeImage.h @@ -17,15 +17,15 @@ namespace IMCodec // {0CA17E19-92E7-4926-A8FC-34E7086BA27F} { 0xca17e19, 0x92e7, 0x4926, { 0xa8, 0xfc, 0x34, 0xe7, 0x8, 0x6b, 0xa2, 0x7f } } ,CodecCapabilities::Decode | CodecCapabilities::BulkCodec - , L"Free image codec" + , LLUTILS_TEXT("Free image codec") , { { - { L"Image formats collection"} + { LLUTILS_TEXT("Image formats collection")} - ,{ L"BMP",L"ICO",L"JPEG",L"JNG",L"KOALA",L"LBM",L"IFF",L"MNG",L"PBM",L"PBMRAW",L"PCD",L"PGM",L"PGMRAW",L"PNG" - ,L"PPM",L"PPMRAW",L"RAS",L"TGA",L"TIFF",L"TIF",L"WBMP",L"PSD",L"CUT",L"XBM",L"XPM",L"DDS",L"GIF",L"HDR",L"FAXG3" - ,L"SGI",L"EXR",L"J2K",L"JP2",L"PFM",L"PICT",L"RAW",L"WEBP",L"JXR",L"CUR" + ,{ LLUTILS_TEXT("BMP"),LLUTILS_TEXT("ICO"),LLUTILS_TEXT("JNG"),LLUTILS_TEXT("KOALA"),LLUTILS_TEXT("LBM"),LLUTILS_TEXT("IFF"),LLUTILS_TEXT("MNG"),LLUTILS_TEXT("PBM"),LLUTILS_TEXT("PBMRAW"),LLUTILS_TEXT("PCD"),LLUTILS_TEXT("PGM"),LLUTILS_TEXT("PGMRAW") + ,LLUTILS_TEXT("PPM"),LLUTILS_TEXT("PPMRAW"),LLUTILS_TEXT("RAS"),LLUTILS_TEXT("TGA"),LLUTILS_TEXT("WBMP"),LLUTILS_TEXT("PSD"),LLUTILS_TEXT("CUT"),LLUTILS_TEXT("XBM"),LLUTILS_TEXT("XPM"),LLUTILS_TEXT("DDS"),LLUTILS_TEXT("GIF") + ,LLUTILS_TEXT("HDR"),LLUTILS_TEXT("FAXG3"),LLUTILS_TEXT("SGI"),LLUTILS_TEXT("PFM"),LLUTILS_TEXT("PICT"),LLUTILS_TEXT("JXR"),LLUTILS_TEXT("CUR") } } } @@ -49,10 +49,10 @@ namespace IMCodec if (freeImageHandle && FreeImage_FlipVertical(freeImageHandle)) { - BITMAPINFO* imageInfo = FreeImage_GetInfo(freeImageHandle); - FREE_IMAGE_TYPE TexelFormat = FreeImage_GetImageType(freeImageHandle); + FIBITMAPINFO* imageInfo = FreeImage_GetInfo(freeImageHandle); + FREE_IMAGE_TYPE freeImageType = FreeImage_GetImageType(freeImageHandle); - const BITMAPINFOHEADER& header = imageInfo->bmiHeader; + const FIBITMAPINFOHEADER& header = imageInfo->bmiHeader; auto imageItem = std::make_shared(); imageItem->itemType = ImageItemType::Image; @@ -67,7 +67,7 @@ namespace IMCodec imageItem->data.Write(reinterpret_cast(FreeImage_GetBits(freeImageHandle)), 0, imageSizeInMemory); - switch (TexelFormat) + switch (freeImageType) { case FIT_BITMAP: { @@ -120,4 +120,4 @@ namespace IMCodec return result; } }; -} \ No newline at end of file +} diff --git a/Codecs/CodecGif/CMakeLists.txt b/Codecs/CodecGif/CMakeLists.txt index 648cea1..426034d 100644 --- a/Codecs/CodecGif/CMakeLists.txt +++ b/Codecs/CodecGif/CMakeLists.txt @@ -1,6 +1,6 @@ #CodecGif -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION 3.10) file(GLOB_RECURSE sourceFiles diff --git a/Codecs/CodecGif/Source/CodecGif.h b/Codecs/CodecGif/Source/CodecGif.h index 8290eca..6c09271 100644 --- a/Codecs/CodecGif/Source/CodecGif.h +++ b/Codecs/CodecGif/Source/CodecGif.h @@ -247,8 +247,7 @@ namespace IMCodec imageItem->descriptor.rowPitchInBytes = IMCodec::GetTexelFormatSize(imageItem->descriptor.texelFormatDecompressed) * imageItem->descriptor.width / CHAR_BIT; imageItem->data = std::move(frameBuffers.at(imageIndex)); imageItem->animationData.delayMilliseconds = currentFrameData.gcb.DelayTime * 10; // multiply by 10 to convert centiseconds to milliseconds. - imageItem->processData.pluginUsed = GetPluginProperties().id; - + //Estimation on frame loading time, since frame are loaded together is a bit cumbersome to precisly time the 'load time' if (loadTIme == -1) @@ -256,8 +255,6 @@ namespace IMCodec using namespace LLUtils; loadTIme = static_cast(stopWatch.GetElapsedTimeReal(StopWatch::TimeUnit::Milliseconds)); } - - imageItem->processData.processTime = loadTIme; if (isMultiImage) out_image->SetSubImage(imageIndex, std::make_shared(imageItem, ImageItemType::Unknown)); diff --git a/Codecs/CodecIcon/CMakeLists.txt b/Codecs/CodecIcon/CMakeLists.txt index a0ad9ce..aa71c9f 100644 --- a/Codecs/CodecIcon/CMakeLists.txt +++ b/Codecs/CodecIcon/CMakeLists.txt @@ -1,5 +1,5 @@ #Codec Icon -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION 3.10) project(CodecIcon) diff --git a/Codecs/CodecJPG/CMakeLists.txt b/Codecs/CodecJPG/CMakeLists.txt index 405fa43..d9750a6 100644 --- a/Codecs/CodecJPG/CMakeLists.txt +++ b/Codecs/CodecJPG/CMakeLists.txt @@ -1,38 +1,151 @@ #Codec JPG -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION 3.10) -file(GLOB_RECURSE sourceFiles - "./Source/*.h" - "./Source/*.cpp" -) +include(ExternalProject) -set(TargetName CodecJPG) -add_library (${TargetName} ${sourceFiles} ) +set(LibJpegTurboFolder ${CMAKE_CURRENT_SOURCE_DIR}/../../External/libjpeg-turbo) +get_filename_component(LibJpegTurboFolder "${LibJpegTurboFolder}" ABSOLUTE) +set(NASMPATH ${CMAKE_CURRENT_SOURCE_DIR}/../../External/bintools/nasm-2.15.05/nasm.exe) +get_filename_component(NASMPATH "${NASMPATH}" ABSOLUTE) -set(libjpeg-turboFolder ../../External/libjpeg-turbo) -#Enable ASM provided by NASM +# ========================= +# ========================= -if (${CMAKE_SYSTEM_NAME} MATCHES "Windows" AND NOT ${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Linux") - set(CMAKE_ASM_NASM_COMPILER ${CMAKE_CURRENT_SOURCE_DIR}/../../External/bintools/nasm-2.15.05/nasm.exe) +# ======== Detect Multi-config vs Single-config ======== +if(CMAKE_CONFIGURATION_TYPES) + set(IS_MULTI_CONFIG TRUE) +else() + set(IS_MULTI_CONFIG FALSE) endif() -#set(ENV{ASM_NASM} ${CMAKE_CURRENT_SOURCE_DIR}/../../External/bintools/nasm-2.15.05/nasm.exe) -#set(CMAKE_ASM_COMPILE_OBJECT "-I/../../External/libjpeg-turbo/simd/nasm -# -I/../../External/libjpeg-turbo/simd/x86_64 ") +# ======== Platform-specific file extensions ======== +if(WIN32) + if (MINGW) + set(JPG_RUNTIME_NAME "libturbojpeg.dll") + set(JPG_IMPLIB_NAME "libturbojpeg.dll.a") + else() + set(JPG_RUNTIME_NAME "turbojpeg.dll") + set(JPG_IMPLIB_NAME "turbojpeg.lib") + endif() +elseif(APPLE) + set(JPG_RUNTIME_NAME "libturbojpeg.dylib") + set(JPG_IMPLIB_NAME "") # No import libs on macOS +else() + set(JPG_RUNTIME_NAME "libturbojpeg.so") + set(JPG_IMPLIB_NAME "") # No import libs on Linux +endif() +# ======== External build directory ======== +set(TurboJpegBinBaseDir "${CMAKE_BINARY_DIR}/libjpeg-turbo") +# ======== CMake arguments for libjpeg-turbo ======== +set(LibJpegTurboArgs + -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_MT=${CMAKE_MT} + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} + -DCMAKE_RC_COMPILER=${CMAKE_RC_COMPILER} + -DENABLE_STATIC=FALSE + -DWITH_FUZZ=FALSE + -DWITH_JPEG=FALSE + -DCMAKE_INSTALL_PREFIX=${TurboJpegBinBaseDir}/install +) -option(ENABLE_STATIC "Build static libraries" FALSE) -set(WITH_FUZZ FALSE) +if (CMAKE_TOOLCHAIN_FILE) + get_filename_component(CMAKE_TOOLCHAIN_FILE_ABSOLUTE "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE) + list(APPEND LibJpegTurboArgs -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE_ABSOLUTE}) +endif() +# Enable NASM on Windows if needed +if(WIN32 AND NOT ${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Linux") + list(APPEND LibJpegTurboArgs -DCMAKE_ASM_NASM_COMPILER=${NASMPATH}) +endif() +# Support Custom runtime and library output directories +if (CMAKE_RUNTIME_OUTPUT_DIRECTORY) + set(JPG_RUNTIME_OUTPUT_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) +else() + set(JPG_RUNTIME_OUTPUT_DIR ${TurboJpegBinBaseDir}) +endif() + + +if (CMAKE_LIBRARY_OUTPUT_DIRECTORY) + set(JPG_LIB_OUTPUT_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) +else() + set(JPG_LIB_OUTPUT_DIR ${TurboJpegBinBaseDir}) +endif() -add_subdirectory(${libjpeg-turboFolder} ./external/libjpeg-turbo) +# ======== Declare Imported Library ======== +add_library(libjpeg-turbo::libjpeg-turbo SHARED IMPORTED GLOBAL) -target_include_directories(${TargetName} PRIVATE ${libjpeg-turboFolder}) +set(JPG_IMPORTED_LOCATION "") +set(JPG_IMPORTED_IMPLIB "") -target_link_libraries(${TargetName} turbojpeg) -if (${CMAKE_SYSTEM_NAME} MATCHES "Windows" AND NOT MINGW) - target_link_options(${TargetName} PUBLIC "/DELAYLOAD:$.dll") + +if(IS_MULTI_CONFIG) + # Multi-config: set per-config imported locations + foreach(cfg ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER "${cfg}" cfg_upper) + list(APPEND JPG_IMPORTED_LOCATION "IMPORTED_LOCATION_${cfg_upper}" "${JPG_RUNTIME_OUTPUT_DIR}/${cfg}/${JPG_RUNTIME_NAME}") + set_target_properties(libjpeg-turbo::libjpeg-turbo PROPERTIES + "IMPORTED_LOCATION_${cfg_upper}" "${JPG_RUNTIME_OUTPUT_DIR}/${cfg}/${JPG_RUNTIME_NAME}") + # Set import library on Windows + if(WIN32) + list(APPEND JPG_IMPORTED_IMPLIB "IMPORTED_IMPLIB_${cfg_upper}" "${JPG_LIB_OUTPUT_DIR}/${cfg}/${JPG_IMPLIB_NAME}") + set_target_properties(libjpeg-turbo::libjpeg-turbo PROPERTIES + "IMPORTED_IMPLIB_${cfg_upper}" "${JPG_LIB_OUTPUT_DIR}/${cfg}/${JPG_IMPLIB_NAME}") + endif() + endforeach() else() -endif() \ No newline at end of file + + set(JPG_IMPORTED_LOCATION "${JPG_RUNTIME_OUTPUT_DIR}/${JPG_RUNTIME_NAME}") + # Single-config: flat directory + set_target_properties(libjpeg-turbo::libjpeg-turbo PROPERTIES IMPORTED_LOCATION + "${JPG_RUNTIME_OUTPUT_DIR}/${JPG_RUNTIME_NAME}") + + # Set import library on Windows + if(WIN32) + set(JPG_IMPORTED_IMPLIB "${JPG_LIB_OUTPUT_DIR}/${JPG_IMPLIB_NAME}") + set_target_properties(libjpeg-turbo::libjpeg-turbo PROPERTIES IMPORTED_IMPLIB + "${JPG_LIB_OUTPUT_DIR}/${JPG_IMPLIB_NAME}") + endif() +endif() + +# ======== Include directories ======== +set_target_properties(libjpeg-turbo::libjpeg-turbo PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${LibJpegTurboFolder}/src" +) + +list ( APPEND JPG_BYPRODUCTS ${JPG_IMPORTED_LOCATION} ) +if (WIN32) + list (APPEND JPG_BYPRODUCTS ${JPG_IMPORTED_IMPLIB} ) +endif() + +# ======== Add ExternalProject ======== +ExternalProject_Add(libjpeg-turbo + SOURCE_DIR ${LibJpegTurboFolder} + BINARY_DIR ${TurboJpegBinBaseDir} + CMAKE_ARGS ${LibJpegTurboArgs} + INSTALL_COMMAND "" + BUILD_COMMAND ${CMAKE_COMMAND} --build --config $ --target turbojpeg + BYPRODUCTS ${JPG_BYPRODUCTS} +) + +# ======== Depend on ExternalProject ======== +add_dependencies(libjpeg-turbo::libjpeg-turbo libjpeg-turbo) + + +# ========================= + + file(GLOB_RECURSE sourceFiles + "./Source/*.h" + "./Source/*.cpp" + ) + +set(TargetName CodecJPG) +add_library (${TargetName} ${sourceFiles} ) + +target_link_libraries(${TargetName} PRIVATE libjpeg-turbo::libjpeg-turbo) # adjust to match built target name diff --git a/Codecs/CodecJPG/Source/CodecJpeg.h b/Codecs/CodecJPG/Source/CodecJpeg.h index e335be4..1ffa9e8 100644 --- a/Codecs/CodecJPG/Source/CodecJpeg.h +++ b/Codecs/CodecJPG/Source/CodecJpeg.h @@ -63,16 +63,13 @@ namespace IMCodec { static thread_local tjhandle ftjHandle = tjInitDecompress(); ImageResult result = ImageResult::UnknownError; -/* int canvasWidth = 0; - int canvasHeight = 0; - - if (params.contains(L"canvasWidth")) - canvasWidth = std::get(params.at(L"canvasWidth")); + if (const int* width = params.GetCustomAs(LLUTILS_TEXT("canvasWidth"))) + canvasWidth = *width; - if (params.contains(L"canvasHeight")) - canvasHeight = std::get(params.at(L"canvasHeight")); -*/ + int canvasHeight = 0; + if (const int* height = params.GetCustomAs(LLUTILS_TEXT("canvasHeight"))) + canvasHeight = *height; int width = 0; diff --git a/Codecs/CodecPNG/CMakeLists.txt b/Codecs/CodecPNG/CMakeLists.txt index 169d25b..70fd797 100644 --- a/Codecs/CodecPNG/CMakeLists.txt +++ b/Codecs/CodecPNG/CMakeLists.txt @@ -1,6 +1,6 @@ #CodecPNG -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION 3.10) file(GLOB_RECURSE sourceFiles "./Source/*.h" @@ -11,7 +11,9 @@ set(TargetName CodecPNG) add_library (${TargetName} ${sourceFiles} ) #ZLIB -option(ZLIB_BUILD_BINARIES "Build zlib test sample and example" OFF) +option(ZLIB_BUILD_TESTING "Enable Zlib Examples as tests" OFF) +option(ZLIB_BUILD_MINIZIP "Enable building libminizip contrib library" OFF) + set(LibPNGFolder ../../External/libpng) set(zlibFolder ../../External/zlib) cmake_path(ABSOLUTE_PATH zlibFolder NORMALIZE OUTPUT_VARIABLE zlibFolder) @@ -30,14 +32,18 @@ add_subdirectory(${zlibFolder} ./external/zlib) list(APPEND ZLIB_INCLUDE_DIRS "${zlibFolder}") list(APPEND ZLIB_INCLUDE_DIRS "${CMAKE_CURRENT_BINARY_DIR}/external/zlib") +set(ZLIB_INCLUDE_DIR ${zlibFolder}) set(ZLIB_LIBRARIES zlib) +set(ZLIB_FOUND TRUE) +set(ZLIB_ROOT, ${zlibFolder}) +set(ZLIB_LIBRARY ${zlibFolder}) + #LibPNG option(PNG_SHARED "Build shared lib" ON) option(PNG_STATIC "Build static lib" OFF) option(PNG_TESTS "Build libpng tests" OFF) -option(PNG_EXECUTABLES "Build libpng executables" OFF) -option(PNG_BUILD_ZLIB "Custom zlib Location, else find_package is used" ON) +option(PNG_TOOLS "Build libpng tools" OFF) set(SKIP_INSTALL_LIBRARIES TRUE) @@ -55,8 +61,3 @@ target_include_directories(${TargetName} PRIVATE ${LibPNGFolder}) target_include_directories(${TargetName} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/external/libpng) target_link_libraries(${TargetName} png_shared ) target_include_directories(png_shared PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/external/zlib) - -if (${CMAKE_SYSTEM_NAME} MATCHES "Windows" AND (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")) - target_link_options(${TargetName} PUBLIC "/DELAYLOAD:$.dll") - target_link_options(${TargetName} PUBLIC "/DELAYLOAD:$.dll") -endif() \ No newline at end of file diff --git a/Codecs/CodecPSD/CMakeLists.txt b/Codecs/CodecPSD/CMakeLists.txt index 9c6fb42..0bd9c59 100644 --- a/Codecs/CodecPSD/CMakeLists.txt +++ b/Codecs/CodecPSD/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.8 FATAL_ERROR) +cmake_minimum_required(VERSION 3.10) # Add source to this project's executable. file(GLOB_RECURSE sourceFiles diff --git a/Codecs/CodecTiff/CMakeLists.txt b/Codecs/CodecTiff/CMakeLists.txt index d2bc1ab..6a6a5ba 100644 --- a/Codecs/CodecTiff/CMakeLists.txt +++ b/Codecs/CodecTiff/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.8 FATAL_ERROR) +cmake_minimum_required(VERSION 3.10) # Add source to this project's executable. file(GLOB_RECURSE sourceFiles @@ -8,7 +8,14 @@ file(GLOB_RECURSE sourceFiles set(TargetName CodecTiff) add_library (${TargetName} ${sourceFiles} ) -set(TIFF_BUILD_SHARED_LIBS TRUE) + +option(tiff-static "build TIFF static libraries" OFF) +option(tiff-tools "build TIFF tools" OFF) +option(tiff-tests "build TIFF tests" OFF) +option(tiff-contrib "build TIFF contrib" OFF) +option(tiff-docs "build TIFF documentation" OFF) +option(tiff-deprecated "build TIFF deprecated features" OFF) + set(TIFF_BUILD_CXX FALSE) set(LibTiffFolder ../../External/libtiff) add_subdirectory(${LibTiffFolder} ./external/libtiff) @@ -16,6 +23,9 @@ add_subdirectory(${LibTiffFolder} ./external/libtiff) if (IMCODEC_DISABLE_WARNINGS_EXTERNAL_LIBS) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") target_compile_options(tiff PRIVATE + -Wno-extra-semi + -Wno-declaration-after-statement + -Wno-format -Wno-nonportable-system-include-path -Wno-cast-align -Wno-strict-prototypes @@ -44,16 +54,21 @@ if (IMCODEC_DISABLE_WARNINGS_EXTERNAL_LIBS) -Wno-reserved-macro-identifier -Wno-unused-parameter -Wno-unsafe-buffer-usage + -Wno-switch-default ) - target_compile_options(port PRIVATE - -Wno-missing-prototypes - -Wno-strict-prototypes - -Wno-reserved-macro-identifier - -Wno-reserved-identifier - -Wno-missing-variable-declarations - -Wno-unsafe-buffer-usage - ) + if (TARGET tiff_port) + get_target_property(tiff_port_type tiff_port TYPE) + if (NOT tiff_port_type STREQUAL "INTERFACE_LIBRARY") + target_compile_options(tiff_port PRIVATE + -Wno-missing-variable-declarations + -Wno-unsafe-buffer-usage + -Wno-reserved-macro-identifier + -Wno-undef + ) + endif() + endif() + elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") target_compile_options(tiff PRIVATE -Wno-array-parameter -Wno-misleading-indentation) elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") @@ -68,6 +83,3 @@ target_include_directories(${TargetName} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/ext target_link_libraries(${TargetName} tiff) -if (${CMAKE_SYSTEM_NAME} MATCHES "Windows" AND NOT MINGW) - target_link_options(${TargetName} PUBLIC "/DELAYLOAD:$.dll") -endif() diff --git a/Codecs/CodecTiff/Source/CodecTiff.h b/Codecs/CodecTiff/Source/CodecTiff.h index 077becf..2c83eb9 100644 --- a/Codecs/CodecTiff/Source/CodecTiff.h +++ b/Codecs/CodecTiff/Source/CodecTiff.h @@ -9,6 +9,8 @@ #include #include +#include + namespace IMCodec { class CodecTiff : public IImagePlugin @@ -42,7 +44,7 @@ namespace IMCodec return mPluginProperties; } - TexelFormat GetTexelFormat(uint16_t sampleFormat, uint16 bitsPerSample, uint16_t samplesPerPixel, uint16_t photoMetric) const + TexelFormat GetTexelFormat(uint16_t sampleFormat, uint16_t bitsPerSample, uint16_t samplesPerPixel, uint16_t photoMetric) const { TexelFormat texelFormat = TexelFormat::UNKNOWN; @@ -66,20 +68,15 @@ namespace IMCodec case SAMPLEFORMAT_UINT: switch (samplesPerPixel) { - case 1: - switch (bitsPerSample) - { - case 8: - texelFormat = TexelFormat::I_A8; - break; - } - break; case 3: switch (bitsPerSample) { case 8: texelFormat = TexelFormat::I_R8_G8_B8; break; + case 16: + texelFormat = TexelFormat::I_R16_G16_B16; + break; } break; case 4: @@ -88,6 +85,9 @@ namespace IMCodec case 8: texelFormat = TexelFormat::I_R8_G8_B8_A8; break; + case 16: + texelFormat = TexelFormat::I_R16_G16_B16_A16; + break; } break; } @@ -112,6 +112,9 @@ namespace IMCodec case 32: texelFormat = TexelFormat::F_X32; break; + case 64: + texelFormat = TexelFormat::F_X64; + break; default: break; } @@ -127,37 +130,42 @@ namespace IMCodec case 1: texelFormat = TexelFormat::I_X1; break; + case 4: + texelFormat = TexelFormat::I_X4; + break; case 8: texelFormat = TexelFormat::I_X8; break; case 16: texelFormat = TexelFormat::I_X16; break; - case SAMPLEFORMAT_INT: - switch (bitsPerSample) - { - case 8: - texelFormat = TexelFormat::S_X8; - break; - case 16: - texelFormat = TexelFormat::S_X16; - break; - default: - break; - } + } + break; + } + break; + case SAMPLEFORMAT_INT: + switch (samplesPerPixel) + { + case 1: + switch (bitsPerSample) + { + case 8: + texelFormat = TexelFormat::S_X8; + break; + case 16: + texelFormat = TexelFormat::S_X16; + break; + default: break; } break; } + break; } } - - if (texelFormat == TexelFormat::UNKNOWN) - LL_ERROR(LLUtils::Exception::ErrorCode::NotImplemented, "CodecTiff: unsupported floating point format."); - - return texelFormat; - } + return texelFormat; + } std::vector GetImage(TIFF* tiff) { @@ -168,11 +176,11 @@ namespace IMCodec uint16_t sampleFormat{}; - uint32 width, height{}; - uint16 bitsPerSample{}; + uint32_t width, height{}; + uint16_t bitsPerSample{}; //uint16 compression{}; - uint16 photoMetric{}; - uint16 samplesPerPixel{}; + uint16_t photoMetric{}; + uint16_t samplesPerPixel{}; uint16_t orientation{}; uint32_t rowPitch{}; //uint32 rowsPerStrip{}; @@ -201,6 +209,9 @@ namespace IMCodec TIFFGetField(tiff, TIFFTAG_MAXSAMPLEVALUE, &maxSampleValue);*/ TIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extraSamples, &sampleTypes); + if (samplesPerPixel <= extraSamples) + return {}; + const uint32_t bytesPerSample = bitsPerSample / CHAR_BIT; uint32_t numberOfStripts = TIFFNumberOfStrips(tiff); @@ -229,17 +240,38 @@ namespace IMCodec //If there's an alpha channel and it's interleaved in the image data, return as single image with alpha channel imageItem->descriptor.texelFormatDecompressed = imageItem->descriptor.texelFormatStorage = mainChannelTexelFormat; - if (planarConfig == PLANARCONFIG_CONTIG && extraSamples == 1 && sampleTypes[0] > 0) + auto extractExtraSampleImages = [&]() { - imageItem->descriptor.texelFormatStorage = imageItem->descriptor.texelFormatDecompressed = GetTexelFormat(sampleFormat, bitsPerSample, samplesPerPixel, photoMetric); + return ExtactExtraSamples(width, height, rowPitch, samplesPerPixel, extraSamples, planarConfig + , bytesPerSample, imageItem->data, photoMetric, bitsPerSample, sampleFormat); + }; + + if (planarConfig == PLANARCONFIG_CONTIG && extraSamples > 0) + { + const auto interleavedTexelFormat = GetTexelFormat(sampleFormat, bitsPerSample, samplesPerPixel, photoMetric); + + if (interleavedTexelFormat != TexelFormat::UNKNOWN) + { + imageItem->descriptor.texelFormatStorage = imageItem->descriptor.texelFormatDecompressed = interleavedTexelFormat; + } + else + { + auto extraChannelImages = extractExtraSampleImages(); + + if (extraChannelImages.empty() == false) + imageItems = extraChannelImages; + else + return {}; + } } - else + else if (extraSamples > 0) { - auto extraChannelImages = ExtactExtraSamples(width, height, rowPitch, samplesPerPixel, extraSamples, planarConfig - , bytesPerSample, imageItem->data, photoMetric, bitsPerSample, sampleFormat); + auto extraChannelImages = extractExtraSampleImages(); if (extraChannelImages.empty() == false) imageItems = extraChannelImages; + else + return {}; } } else @@ -248,7 +280,7 @@ namespace IMCodec //override target row pitch - always 32bpp imageItem->descriptor.rowPitchInBytes = width * 4; imageItem->data.Allocate(height * imageItem->descriptor.rowPitchInBytes); - TIFFReadRGBAImageOriented(tiff, width, height, reinterpret_cast(imageItem->data.data()), orientation); + TIFFReadRGBAImageOriented(tiff, width, height, reinterpret_cast(imageItem->data.data()), orientation); } @@ -274,9 +306,13 @@ namespace IMCodec { const auto sampleSize = sampleCount * bytesPerSample; + const auto samplePhotometric = sampleOffset == 0 ? photometric : PHOTOMETRIC_MINISBLACK; auto imageItem = std::make_shared(); - imageItem->descriptor.texelFormatStorage = GetTexelFormat(sampleFormat, bitsPerSample , sampleCount, photometric); + imageItem->descriptor.texelFormatStorage = GetTexelFormat(sampleFormat, bitsPerSample , sampleCount, samplePhotometric); + if (imageItem->descriptor.texelFormatStorage == TexelFormat::UNKNOWN) + return {}; + imageItem->descriptor.texelFormatDecompressed = imageItem->descriptor.texelFormatStorage; imageItem->descriptor.height = height; imageItem->descriptor.width = width; @@ -293,7 +329,7 @@ namespace IMCodec { for (size_t x = 0; x < width; x++) { - const size_t sourceRowIndex = sampleOffset * sampleSize + x * samplesPerPixel * bytesPerSample; + const size_t sourceRowIndex = sampleOffset * bytesPerSample + x * samplesPerPixel * bytesPerSample; const size_t destRowIndex = x * sampleSize; memcpy(image.data() + destOffset + destRowIndex, sourceBuffer.data() + sourceOffset + sourceRowIndex, sampleSize); } @@ -318,12 +354,25 @@ namespace IMCodec if (extraSmaples > 0) { + if (bytesPerSample == 0 || bitsPerSample % CHAR_BIT != 0 || samplesPerPixel <= extraSmaples) + return {}; + const auto mainImageSampleCount = samplesPerPixel - extraSmaples; - subChannels.push_back(extractSamples(0, mainImageSampleCount)); + auto mainImage = extractSamples(0, mainImageSampleCount); + if (mainImage == nullptr) + return {}; + + subChannels.push_back(std::move(mainImage)); for (int i = 0; i < extraSmaples; i++) - subChannels.push_back(extractSamples(mainImageSampleCount + i, 1)); + { + auto extraImage = extractSamples(mainImageSampleCount + i, 1); + if (extraImage == nullptr) + return {}; + + subChannels.push_back(std::move(extraImage)); + } } @@ -344,6 +393,9 @@ namespace IMCodec int currentSubImage = 0; auto firstImageItemChannles = GetImage(tiff); + if (firstImageItemChannles.empty()) + return ImageResult::FormatNotSupported; + firstImageItem = firstImageItemChannles.at(0); if (firstImageItemChannles.size() > 1) @@ -365,6 +417,9 @@ namespace IMCodec } auto nextImages = GetImage(tiff); + if (nextImages.empty()) + return ImageResult::FormatNotSupported; + for (size_t i = 0; i < nextImages.size(); i++) { subImages.push_back(std::make_shared(nextImages.at(i), ImageItemType::Pages)); diff --git a/Codecs/CodecWebP/CMakeLists.txt b/Codecs/CodecWebP/CMakeLists.txt index d6489f9..ffaaad7 100644 --- a/Codecs/CodecWebP/CMakeLists.txt +++ b/Codecs/CodecWebP/CMakeLists.txt @@ -1,5 +1,5 @@ #Codec WebP -cmake_minimum_required(VERSION 3.8 FATAL_ERROR) +cmake_minimum_required(VERSION 3.10) # Add source to this project's executable. file(GLOB_RECURSE sourceFiles diff --git a/Example/CMakeLists.txt b/Example/CMakeLists.txt index c215d5e..9bd4374 100644 --- a/Example/CMakeLists.txt +++ b/Example/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.8) +cmake_minimum_required (VERSION 3.10) #Image Codec set(CMAKE_CXX_STANDARD 20) @@ -16,21 +16,26 @@ add_executable(${TargetName} ${sourceFiles}) target_include_directories(${TargetName} PRIVATE ./Imageloader/Include) target_link_libraries(${TargetName} PRIVATE ImageCodec) + if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") - target_link_libraries(${TargetName} PRIVATE delayimp) + target_link_libraries(${TargetName} PRIVATE delayimp dbghelp) endif() +set(OUTPUT_PATH $) + #Copy oiv library resources to the output dir - add_custom_command(TARGET ${TargetName} - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/cat.jpg ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/) - -#Copy needed dependencies to output dir - add_custom_command(TARGET ${TargetName} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/) - - add_custom_command(TARGET ${TargetName} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/) - - add_custom_command(TARGET ${TargetName} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/) \ No newline at end of file +add_custom_command(TARGET ${TargetName} POST_BUILD +COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/cat.jpg ${OUTPUT_PATH}/) + +#copy zlib, libpng and libjpeg-turbo dlls to the output dir +add_custom_command(TARGET ${TargetName} POST_BUILD +COMMAND ${CMAKE_COMMAND} -E copy $ ${OUTPUT_PATH}/) + +add_custom_command(TARGET ${TargetName} POST_BUILD +COMMAND ${CMAKE_COMMAND} -E copy $ ${OUTPUT_PATH}/) + +add_custom_command(TARGET ${TargetName} POST_BUILD +COMMAND ${CMAKE_COMMAND} -E copy $ ${OUTPUT_PATH}/) + + diff --git a/External/FreeImageRe b/External/FreeImageRe new file mode 160000 index 0000000..a515dc4 --- /dev/null +++ b/External/FreeImageRe @@ -0,0 +1 @@ +Subproject commit a515dc489d1b0e33bd4c15edc02335cfcd249f6f diff --git a/External/TinyEXIF b/External/TinyEXIF index 5d451c0..1dc171e 160000 --- a/External/TinyEXIF +++ b/External/TinyEXIF @@ -1 +1 @@ -Subproject commit 5d451c083444769e792fe81ea1a7c4ab4ccf86ca +Subproject commit 1dc171ea067067086b8a5b8172e7368067a45373 diff --git a/External/libgif b/External/libgif index 2e210de..0e67518 160000 --- a/External/libgif +++ b/External/libgif @@ -1 +1 @@ -Subproject commit 2e210de51989efc3f286cb5af78ca0c7e7e31bb4 +Subproject commit 0e67518f090cd16b1f4d45f3207c19e04bddc29e diff --git a/External/libjpeg-turbo b/External/libjpeg-turbo index b165110..81feffa 160000 --- a/External/libjpeg-turbo +++ b/External/libjpeg-turbo @@ -1 +1 @@ -Subproject commit b165110aaab51aeaabad60f6ecc7c5287e8042d4 +Subproject commit 81feffa632bcd928d4cd1c35e5bb6c1eb02ac199 diff --git a/External/libpng b/External/libpng index 5f68c5d..12b57f9 160000 --- a/External/libpng +++ b/External/libpng @@ -1 +1 @@ -Subproject commit 5f68c5d79eb5a6c678a449fcab16f2456a83931c +Subproject commit 12b57f946408c09f04166061ebd3a8d3486e1078 diff --git a/External/libpsd b/External/libpsd index e670ae0..1f4eec5 160000 --- a/External/libpsd +++ b/External/libpsd @@ -1 +1 @@ -Subproject commit e670ae0be0c50a4afb83d3f1703cff1e6ca0c9ec +Subproject commit 1f4eec51838fed33163569ddc432539da1f4c9f2 diff --git a/External/libtiff b/External/libtiff index 046ebc7..c5cccfb 160000 --- a/External/libtiff +++ b/External/libtiff @@ -1 +1 @@ -Subproject commit 046ebc76983ce9b134ffd79572772065938a43fb +Subproject commit c5cccfb4f6a3d6730f658b0fea9aa6a5a6bbd8a6 diff --git a/External/libwebp b/External/libwebp index 5ecee06..0cd0b7a 160000 --- a/External/libwebp +++ b/External/libwebp @@ -1 +1 @@ -Subproject commit 5ecee06f7a11b5b06d846196b362fb9fd39b25b2 +Subproject commit 0cd0b7a7013723985156989f0772e3cb8c4ce49f diff --git a/External/zlib b/External/zlib index 9ea9cf1..5a82f71 160000 --- a/External/zlib +++ b/External/zlib @@ -1 +1 @@ -Subproject commit 9ea9cf1936f19afd444f9af75c8b7bffd572583b +Subproject commit 5a82f71ed1dfc0bec044d9702463dbdf84ea3b71 diff --git a/ImageCodec/CMakeLists.txt b/ImageCodec/CMakeLists.txt index 58007af..df2e40c 100644 --- a/ImageCodec/CMakeLists.txt +++ b/ImageCodec/CMakeLists.txt @@ -1,5 +1,5 @@ #Codec DDS -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION 3.10) file(GLOB_RECURSE sourceFiles "./Source/*.h" @@ -9,40 +9,57 @@ file(GLOB_RECURSE sourceFiles set(TargetName ImageCodec) add_library (${TargetName} ${sourceFiles} ) -target_include_directories(${TargetName} PRIVATE ./Include) +target_include_directories(${TargetName} PUBLIC ./Include) +target_include_directories(${TargetName} PUBLIC /ImageUtil/Include) target_include_directories(${TargetName} PRIVATE ../External/TinyExif) if ( ${IMCODEC_BUILD_CODEC_BMP}) - target_link_libraries(${TargetName} CodecBMP) + target_link_libraries(${TargetName} PRIVATE CodecBMP) endif() if ( ${IMCODEC_BUILD_CODEC_DDS}) - target_link_libraries(${TargetName} CodecDDS) + target_link_libraries(${TargetName} PRIVATE CodecDDS) endif() if ( ${IMCODEC_BUILD_CODEC_ICON}) - target_link_libraries(${TargetName} CodecIcon) + target_link_libraries(${TargetName} PRIVATE CodecIcon) endif() if ( ${IMCODEC_BUILD_CODEC_PSD}) - target_link_libraries(${TargetName} CodecPSD) + target_link_libraries(${TargetName} PRIVATE CodecPSD) endif() if ( ${IMCODEC_BUILD_CODEC_JPG}) - target_link_libraries(${TargetName} CodecJPG) + target_link_libraries(${TargetName} PRIVATE CodecJPG) endif() if ( ${IMCODEC_BUILD_CODEC_PNG}) - target_link_libraries(${TargetName} CodecPNG) + target_link_libraries(${TargetName} PRIVATE CodecPNG) endif() if ( ${IMCODEC_BUILD_CODEC_GIF}) - target_link_libraries(${TargetName} CodecGif) + target_link_libraries(${TargetName} PRIVATE CodecGif) endif() if ( ${IMCODEC_BUILD_CODEC_TIFF}) - target_link_libraries(${TargetName} CodecTiff) + target_link_libraries(${TargetName} PRIVATE CodecTiff) endif() if ( ${IMCODEC_BUILD_CODEC_WEBP}) - target_link_libraries(${TargetName} CodecWebP) + target_link_libraries(${TargetName} PRIVATE CodecWebP) endif() if ( ${IMCODEC_BUILD_CODEC_FREEIMAGE}) - target_link_libraries(${TargetName} CodecFreeImage) + target_link_libraries(${TargetName} PRIVATE CodecFreeImage) endif() -target_link_libraries(${TargetName} TinyEXIFstatic) +target_link_libraries(${TargetName} PRIVATE TinyEXIFstatic) +if (${CMAKE_SYSTEM_NAME} MATCHES "Windows" AND + (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") AND + NOT MINGW) + target_link_libraries(${TargetName} PUBLIC delayimp) + if ( ${IMCODEC_BUILD_CODEC_JPG}) + target_link_options(${TargetName} PUBLIC "/DELAYLOAD:turbojpeg.dll") + endif() + if ( ${IMCODEC_BUILD_CODEC_PNG}) + target_link_options(${TargetName} PUBLIC "/DELAYLOAD:$.dll") + set_property(TARGET png_shared APPEND PROPERTY LINK_LIBRARIES delayimp) + set_property(TARGET png_shared APPEND PROPERTY LINK_OPTIONS "/DELAYLOAD:$.dll") + endif() + if ( ${IMCODEC_BUILD_CODEC_TIFF}) + target_link_options(${TargetName} PUBLIC "/DELAYLOAD:$.dll") + endif() +endif() diff --git a/ImageCodec/Include/IImagePlugin.h b/ImageCodec/Include/IImagePlugin.h index 5e8725c..182c4de 100644 --- a/ImageCodec/Include/IImagePlugin.h +++ b/ImageCodec/Include/IImagePlugin.h @@ -4,8 +4,7 @@ #include #include "ImageCommon.h" #include "ImageItem.h" -#include -#include +#include "ImagePluginParameters.h" namespace IMCodec { @@ -54,9 +53,7 @@ namespace IMCodec }; - using Parameter = std::variant; - using Parameters = std::map; - + struct ParameterDescriptor { string_type name; diff --git a/ImageCodec/Include/ImagePluginParameters.h b/ImageCodec/Include/ImagePluginParameters.h new file mode 100644 index 0000000..2443da9 --- /dev/null +++ b/ImageCodec/Include/ImagePluginParameters.h @@ -0,0 +1,80 @@ +#pragma once + +#include "ImageCommon.h" + +#include +#include +#include +#include + +namespace IMCodec +{ + using SharedParameterValue = std::variant; + + enum class ParametrType + { + None, + DesiredSize + }; + + class Parameters + { + public: + using SharedParametersMap = std::map; + using CustomParametersMap = std::map; + + void SetShared(ParametrType type, SharedParameterValue value) + { + sharedParameters_.insert_or_assign(type, std::move(value)); + } + + const SharedParameterValue* GetShared(ParametrType type) const + { + auto it = sharedParameters_.find(type); + return it != sharedParameters_.end() ? &it->second : nullptr; + } + + bool HasShared(ParametrType type) const + { + return sharedParameters_.find(type) != sharedParameters_.end(); + } + + template + const T* GetSharedAs(ParametrType type) const + { + auto it = sharedParameters_.find(type); + if (it != sharedParameters_.end()) + return std::get_if(&it->second); + return nullptr; + } + + void SetCustom(string_type key, std::any value) + { + customParameters_.insert_or_assign(std::move(key), std::move(value)); + } + + const std::any* GetCustom(const string_type& key) const + { + auto it = customParameters_.find(key); + return it != customParameters_.end() ? &it->second : nullptr; + } + + bool HasCustom(const string_type& key) const + { + return customParameters_.find(key) != customParameters_.end(); + } + + template + const T* GetCustomAs(const string_type& key) const + { + auto it = customParameters_.find(key); + if (it != customParameters_.end()) + return std::any_cast(&it->second); + return nullptr; + } + + private: + SharedParametersMap sharedParameters_; + CustomParametersMap customParameters_; + }; +} diff --git a/ImageUtil/CMakeLists.txt b/ImageUtil/CMakeLists.txt index 726f2d9..7cf0cb5 100644 --- a/ImageUtil/CMakeLists.txt +++ b/ImageUtil/CMakeLists.txt @@ -6,6 +6,6 @@ set(TargetName ImageUtil) add_library (${TargetName} STATIC ${sourceFiles}) -target_include_directories(${TargetName} PRIVATE ./Include) +target_include_directories(${TargetName} PUBLIC ./Include) target_include_directories(${TargetName} PRIVATE ./Source) target_include_directories(${TargetName} PRIVATE ../External/ExoticNumbers/include) \ No newline at end of file diff --git a/ImageUtil/Source/System.cpp b/ImageUtil/Source/System.cpp index 1e55564..821fab6 100644 --- a/ImageUtil/Source/System.cpp +++ b/ImageUtil/Source/System.cpp @@ -15,7 +15,8 @@ namespace IMUtil } else { - LL_EXCEPTION_NOT_IMPLEMENT("Unknown CPU cores layout"); + //TODO: find a better way to decide the ideal number of cores to use + return static_cast(cpuCoresInfo.physicalCores); } } else diff --git a/mingw-w64-x86_64.cmake b/mingw-w64-x86_64.cmake new file mode 100644 index 0000000..563b540 --- /dev/null +++ b/mingw-w64-x86_64.cmake @@ -0,0 +1,43 @@ + +#Usage: cmake -DCMAKE_TOOLCHAIN_FILE=mingw-w64-x86_64.cmake + +set(CMAKE_SYSTEM_NAME Windows) + + +set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) + +# cross compilers to use for C, C++ and Fortran +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) +set(CMAKE_Fortran_COMPILER ${TOOLCHAIN_PREFIX}-gfortran) +set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) + +set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) + +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_SYSTEM_PROCESSOR x86_64) +set(CMAKE_SYSTEM_VERSION 10) + + +function (createSymLink target symlink) + cmake_path(GET symlink PARENT_PATH parentPath) + file(MAKE_DIRECTORY ${parentPath}) + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${target} ${symlink}) +endfunction() + +# MINGW defaults max SDK version to Windows server 2003 (0x0502) +# For supporting newer functionality, overriding is needed, otherwise code won't compile +# override with Windows 10 (0x0A00) SDK version +add_compile_definitions(_WIN32_WINNT=0x0A00) + +set(CASE_SENSITIVE_FIX_FOR_MINGW_PATH ${CMAKE_CURRENT_BINARY_DIR}/mingw-w64) +createSymLink(/usr/x86_64-w64-mingw32/include/windows.h ${CASE_SENSITIVE_FIX_FOR_MINGW_PATH}/Include/Windows.h) +createSymLink(/usr/x86_64-w64-mingw32/include/shlobj.h ${CASE_SENSITIVE_FIX_FOR_MINGW_PATH}/Include/ShlObj.h) +createSymLink(/usr/x86_64-w64-mingw32/include/dbghelp.h ${CASE_SENSITIVE_FIX_FOR_MINGW_PATH}/Include/DbgHelp.h) +createSymLink(/usr/x86_64-w64-mingw32/include/commctrl.h ${CASE_SENSITIVE_FIX_FOR_MINGW_PATH}/Include/CommCtrl.h) +createSymLink(/usr/x86_64-w64-mingw32/include/shellscalingapi.h ${CASE_SENSITIVE_FIX_FOR_MINGW_PATH}/Include/ShellScalingApi.h) +createSymLink(/usr/x86_64-w64-mingw32/include/psapi.h ${CASE_SENSITIVE_FIX_FOR_MINGW_PATH}/Include/Psapi.h) + +include_directories(${CASE_SENSITIVE_FIX_FOR_MINGW_PATH}/Include)