Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add experimental HTJ2K TransferSyntax for reading to GDCM #5020

Merged
merged 7 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion Modules/IO/GDCM/include/itkGDCMImageIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ class GDCMImageIOEnums
JPEG = 0,
JPEG2000,
JPEGLS,
RLE
RLE,
HTJ2K
};
};

Expand Down Expand Up @@ -210,6 +211,16 @@ class ITKIOGDCM_EXPORT GDCMImageIO : public ImageIOBase
static constexpr CompressionEnum RLE = CompressionEnum::RLE;
#endif

/** Set the compression type to use for writing.
*
* Currently only JPEG2000 and JPEG are supported.
* These map to the following DICOM standards:
* JPEG2000: JPEG 2000 Image Compression (Lossless Only)
* JPEG: JPEG Lossless, Non-Hierarchical, First-Order Prediction
*
*
* @param _arg
*/
itkSetEnumMacro(CompressionType, CompressionEnum);
itkGetEnumMacro(CompressionType, CompressionEnum);

Expand Down
2 changes: 2 additions & 0 deletions Modules/IO/GDCM/src/itkGDCMImageIO.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,8 @@ operator<<(std::ostream & out, const GDCMImageIOEnums::Compression value)
return "itk::GDCMImageIOEnums::Compression::JPEGLS";
case GDCMImageIOEnums::Compression::RLE:
return "itk::GDCMImageIOEnums::Compression::RLE";
case GDCMImageIOEnums::Compression::HTJ2K:
return "itk::GDCMImageIOEnums::Compression::HTJ2K";
default:
return "INVALID VALUE FOR itk::GDCMImageIOEnums::Compression";
}
Expand Down
1 change: 1 addition & 0 deletions Modules/IO/GDCM/test/Baseline/Lily_full.mha.cid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bafybeig7pgo3x55bfh47ymckelybsug7rv2nqwjic2gzurvng6o3vqoux4
9 changes: 8 additions & 1 deletion Modules/IO/GDCM/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,12 @@ itk_add_test(
${ITK_TEST_OUTPUT_DIR}/no_preamble.mha
scalar)


function(AddComplianceTest fileName)
set(arg_baseline_fileName "Lily.mha")
if (ARGV1)
set(arg_baseline_fileName ${ARGV1})
endif()
itk_add_test(
NAME
itkGDCM_ComplianceTestRGB_${fileName}
Expand All @@ -403,7 +408,7 @@ function(AddComplianceTest fileName)
--compareCoordinateTolerance
0.001
--compare
DATA{Baseline/Lily.mha}
DATA{Baseline/${arg_baseline_fileName}}
${ITK_TEST_OUTPUT_DIR}/itkGDCM_ComplianceTestRGB_${fileName}.mha
itkGDCMImageReadWriteTest
DATA{Input/Lily/${fileName}.dcm}
Expand All @@ -419,3 +424,5 @@ addcompliancetest(raw-RGB)
addcompliancetest(raw-YBR_FULL)
addcompliancetest(raw-YBR_FULL_422)
addcompliancetest(RLE-RGB)
addcompliancetest(HTJ2K-YBR_ICT Lily_full.mha)
addcompliancetest(HTJ2K-YBR_RCT Lily_full.mha)
1 change: 1 addition & 0 deletions Modules/IO/GDCM/test/Input/Lily/HTJ2K-YBR_ICT.dcm.cid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bafkreib5e6kni2tdbtaxpz2i77k7hp5gzkztppiuws3ov4yx4dswlna6p4
1 change: 1 addition & 0 deletions Modules/IO/GDCM/test/Input/Lily/HTJ2K-YBR_RCT.dcm.cid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bafybeifxqqmljz3yrqhrdv7vzrqrfkvs7aq2mx7mo3g3mjykqq3onlgh6i
3 changes: 1 addition & 2 deletions Modules/ThirdParty/GDCM/UpdateFromUpstream.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ readonly name="GDCM"
readonly ownership="GDCM Upstream <[email protected]>"
readonly subtree="Modules/ThirdParty/GDCM/src/gdcm"
readonly repo="https://github.com/malaterre/GDCM.git"
readonly tag="release"
readonly tag="v3.0.25"
readonly shortlog=false
readonly paths="
.gitattributes
Expand All @@ -31,7 +31,6 @@ readonly paths="
Utilities/gdcmmd5
Utilities/gdcm_md5.h
Utilities/gdcm_openjpeg.h
Utilities/gdcmopenjpeg
Utilities/gdcmrle
Utilities/gdcmutfcpp
Utilities/gdcmuuid
Expand Down
7 changes: 6 additions & 1 deletion Modules/ThirdParty/GDCM/src/gdcm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ endif()
#----------------------------------------------------------------------------

project(GDCM
VERSION 3.0.24
VERSION 3.0.25
LANGUAGES CXX C
)
## NOTE: the "DESCRIPTION" feature of project() was introduced in cmake 3.10.0
Expand Down Expand Up @@ -180,6 +180,10 @@ macro(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE)
endif()
endmacro()

if(UNIX)
include(GNUInstallDirs)
endif()

#include(${GDCM_SOURCE_DIR}/CMake/gdcmPlatformCxxTests.cmake)
#
#GDCM_PLATFORM_CXX_TEST(GDCM_CXX_HAS_FUNCTION
Expand Down Expand Up @@ -696,6 +700,7 @@ if(GDCM_STANDALONE)
HEADERS_DESTINATION "${GDCM_INSTALL_INCLUDE_DIR}/vtk${vtk_version_suffix}"
CMAKE_DESTINATION "${GDCM_INSTALL_PACKAGE_DIR}"
LICENSE_DESTINATION "${GDCM_INSTALL_DATA_DIR}/vtkgdcm-${GDCM_SHORT_VERSION}"
SPDX_DESTINATION "${GDCM_INSTALL_DATA_DIR}/vtkgdcm-${GDCM_SHORT_VERSION}"
HIERARCHY_DESTINATION "${GDCM_INSTALL_LIB_DIR}/vtk${vtk_version_suffix}/hierarchy/vtkgdcm"
LIBRARY_NAME_SUFFIX "${vtkgdcm_library_suffix}"
VERSION "${GDCM_VERSION}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
#include <cstdlib> // realpath
#include <cstring>

#if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__))
#include <windows.h>
#endif

namespace gdcm
{

Expand Down Expand Up @@ -97,7 +101,6 @@ const char *Filename::ToUnixSlashes()
}

#if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__))
#include <windows.h>

inline void Realpath(const char *path, std::string & resolved_path)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ using DICT_ENTRY = struct
};

static const DICT_ENTRY DICOMV3DataDict [] = {
{0x0049,0x0010,"AIR",VR::LO,VM::VM1,"?Possibly PHI?",false },
{0x0049,0x0011,"AIR",VR::LO,VM::VM1,"?number?",false },
{0x0049,0x0013,"AIR",VR::LT,VM::VM1,"?Long desc possibly PHI?",false },
{0x0021,0x0010,"SIEMENS MR FMRI",VR::SQ,VM::VM1,"?",false },
{0x0021,0x0011,"SIEMENS MR FMRI",VR::LO,VM::VM1,"?",false },
{0x0021,0x0012,"SIEMENS MR FMRI",VR::SQ,VM::VM1,"?",false },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ bool ByteSwapFilter::ByteSwap()
de.SetTag(
Tag( SwapperDoOp::Swap( tag.GetGroup() ), SwapperDoOp::Swap( tag.GetElement() ) ) );
copy.Insert( de );
DS.Remove( de.GetTag() );
}
DS = copy;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ static void x16printf(char *buf, int size, Float f) {
strcpy(buf, mant);
return;
}
strncpy(buf, mant, iexp + 1);
memcpy(buf, mant, iexp + 1);
buf[iexp + 1] = '.';
strncpy(buf + iexp + 2, mant + iexp + 1, size - iexp - 1);
buf[size] = 0;
Expand All @@ -409,7 +409,7 @@ static void x16printf(char *buf, int size, Float f) {
for(j=0; j< -1 - iexp; j++) {
buf[j+1] = '0';
}
strncpy(buf - iexp, mant, size + 1 + iexp);
memcpy(buf - iexp, mant, size + 1 + iexp);
buf[size] = 0;
clean(buf);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,15 @@ static const char *TSStrings[] = {
"1.2.840.10008.1.2.4.102",
// MPEG-4 AVC/H.264 BD-compatible High Profile / Level 4.1
"1.2.840.10008.1.2.4.103",
// High-Throughput JPEG 2000 Image Compression (Lossless Only)
"1.2.840.10008.1.2.4.201",
// High-Throughput JPEG 2000 with RPCL Options Image Compression (Lossless Only)
"1.2.840.10008.1.2.4.202",
// High-Throughput JPEG 2000 Image Compression
"1.2.840.10008.1.2.4.203",
// Unknown
"Unknown Transfer Syntax", // Pretty sure we never use this case...
nullptr // Compilers have no obligation to finish by NULL, do it ourself
"Unknown Transfer Syntax", // Pretty sure we never use this case... until a new transfer syntax is added
nullptr // Compilers have no obligation to finish by NULL, do it ourselves
};

TransferSyntax::TSType TransferSyntax::GetTSType(const char *cstr)
Expand Down Expand Up @@ -162,7 +168,8 @@ bool TransferSyntax::IsLossy() const
TSField == MPEG2MainProfile ||
TSField == MPEG2MainProfileHighLevel ||
TSField == MPEG4AVCH264HighProfileLevel4_1 ||
TSField == MPEG4AVCH264BDcompatibleHighProfileLevel4_1
TSField == MPEG4AVCH264BDcompatibleHighProfileLevel4_1 ||
TSField == HTJ2K
)
{
return true;
Expand Down Expand Up @@ -211,7 +218,8 @@ bool TransferSyntax::IsLossless() const
TSField == MPEG2MainProfile ||
TSField == MPEG2MainProfileHighLevel ||
TSField == MPEG4AVCH264HighProfileLevel4_1 ||
TSField == MPEG4AVCH264BDcompatibleHighProfileLevel4_1
TSField == MPEG4AVCH264BDcompatibleHighProfileLevel4_1 ||
TSField == HTJ2K
)
{
return false;
Expand Down Expand Up @@ -300,6 +308,10 @@ bool TransferSyntax::IsEncapsulated() const
case MPEG4AVCH264BDcompatibleHighProfileLevel4_1:
//case ImplicitVRBigEndianACRNEMA:
//case WeirdPapryus:
case HTJ2KLossless:
case HTJ2KRPCLLossless:
case HTJ2K:

ret = true;
break;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ class GDCM_EXPORT TransferSyntax
MPEG2MainProfileHighLevel,
MPEG4AVCH264HighProfileLevel4_1,
MPEG4AVCH264BDcompatibleHighProfileLevel4_1,
HTJ2KLossless,
HTJ2KRPCLLossless,
HTJ2K,
TS_END
} TSType;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ VR DataSetHelper::ComputeVR(File const &file, DataSet const &ds, const Tag& tag)
{
// For Pixel Data:
// if( !ds.FindDataElement( bitsallocated ) ) return VR::UN;
Attribute<0x0028,0x0100> at;
// Attribute<0x0028,0x0100> at;
// at.SetFromDataElement( ds.GetDataElement( bitsallocated ) );
}
(void)v;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,7 @@ bool FileChangeTransferSyntax::InitializeCopy()
ISO_14495_1 = JPEG-LS Near-lossless Compression
ISO_15444_1 = JPEG 2000 Irreversible Compression
ISO_13818_2 = MPEG2 Compression
ISO_15444_15 = High-Throughput JPEG 2000 Irreversible Compression
*/
Attribute<0x0028,0x2114> at3;
const TransferSyntax ts_orig = Internals->TS;
Expand All @@ -467,6 +468,14 @@ bool FileChangeTransferSyntax::InitializeCopy()
static const CSComp newvalues2[] = {"ISO_14495_1"};
at3.SetValues( newvalues2, 1 );
}
else if (
ts_orig == TransferSyntax::HTJ2KLossless ||
ts_orig == TransferSyntax::HTJ2KRPCLLossless ||
ts_orig == TransferSyntax::HTJ2K )
{
static const CSComp newvalues2[] = {"ISO_15444_15"};
at3.SetValues( newvalues2, 1 );
}
else if (
ts_orig == TransferSyntax::JPEGBaselineProcess1 ||
ts_orig == TransferSyntax::JPEGExtendedProcess2_4 ||
Expand Down
Loading