diff --git a/Codecs/CodecJPG/CMakeLists.txt b/Codecs/CodecJPG/CMakeLists.txt index 744bae1..d9750a6 100644 --- a/Codecs/CodecJPG/CMakeLists.txt +++ b/Codecs/CodecJPG/CMakeLists.txt @@ -149,7 +149,3 @@ set(TargetName CodecJPG) add_library (${TargetName} ${sourceFiles} ) target_link_libraries(${TargetName} PRIVATE libjpeg-turbo::libjpeg-turbo) # adjust to match built target name - -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_options(${TargetName} PUBLIC "/DELAYLOAD:turbojpeg.dll") -endif() \ No newline at end of file diff --git a/Codecs/CodecPNG/CMakeLists.txt b/Codecs/CodecPNG/CMakeLists.txt index d35b375..70fd797 100644 --- a/Codecs/CodecPNG/CMakeLists.txt +++ b/Codecs/CodecPNG/CMakeLists.txt @@ -61,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/CodecTiff/CMakeLists.txt b/Codecs/CodecTiff/CMakeLists.txt index cb1dec7..6a6a5ba 100644 --- a/Codecs/CodecTiff/CMakeLists.txt +++ b/Codecs/CodecTiff/CMakeLists.txt @@ -83,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 (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") 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 a888cfd..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 @@ -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) { @@ -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 @@ -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/ImageCodec/CMakeLists.txt b/ImageCodec/CMakeLists.txt index b2a3867..df2e40c 100644 --- a/ImageCodec/CMakeLists.txt +++ b/ImageCodec/CMakeLists.txt @@ -47,6 +47,19 @@ if ( ${IMCODEC_BUILD_CODEC_FREEIMAGE}) endif() target_link_libraries(${TargetName} PRIVATE TinyEXIFstatic) -target_link_libraries(${TargetName} PUBLIC delayimp) - - +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()