Skip to content

Commit

Permalink
Added support for new JPEG XL Transfer Syntaxes.
Browse files Browse the repository at this point in the history
Added basic support for the new JPEG XL Transfer Syntaxes introduced
with Supplement 232: added definition of UIDs and EXS_xxx enum values,
added basic network support (including storescp's and movescu's
--accept-all, echoscu's --propose-ts option as well as the association
negotiation configuration files).

This closes DCMTK Conformance #1138.
  • Loading branch information
jriesmeier committed Oct 23, 2024
1 parent 7ca0e76 commit ec1bb01
Show file tree
Hide file tree
Showing 17 changed files with 154 additions and 69 deletions.
6 changes: 6 additions & 0 deletions dcmdata/include/dcmtk/dcmdata/dcuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,12 @@ DCMTK_DCMDATA_EXPORT unsigned long dcmGuessModalityBytes(const char *sopClassUID
#define UID_HEVCMainProfileLevel5_1TransferSyntax "1.2.840.10008.1.2.4.107"
/// HEVC/H.265 Main 10 Profile / Level 5.1
#define UID_HEVCMain10ProfileLevel5_1TransferSyntax "1.2.840.10008.1.2.4.108"
/// JPEG XL Lossless
#define UID_JPEGXLLosslessTransferSyntax "1.2.840.10008.1.2.4.110"
/// JPEG XL JPEG Recompression
#define UID_JPEGXLJPEGRecompressionTransferSyntax "1.2.840.10008.1.2.4.111"
/// JPEG XL
#define UID_JPEGXLTransferSyntax "1.2.840.10008.1.2.4.112"
/// High-Throughput JPEG 2000 Image Compression (Lossless Only)
#define UID_HighThroughputJPEG2000ImageCompressionLosslessOnlyTransferSyntax "1.2.840.10008.1.2.4.201"
/// High-Throughput JPEG 2000 with RPCL Options Image Compression (Lossless Only)
Expand Down
18 changes: 12 additions & 6 deletions dcmdata/include/dcmtk/dcmdata/dcxfer.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,18 +136,24 @@ typedef enum {
EXS_HEVCMainProfileLevel5_1 = 47,
/// HEVC/H.265 Main 10 Profile / Level 5.1
EXS_HEVCMain10ProfileLevel5_1 = 48,
/// JPEG XL Lossless
EXS_JPEGXLLossless = 49,
/// JPEG XL JPEG Recompression
EXS_JPEGXLJPEGRecompression = 50,
/// JPEG XL
EXS_JPEGXL = 51,
/// High-Throughput JPEG 2000 Image Compression (Lossless Only)
EXS_HighThroughputJPEG2000LosslessOnly = 49,
EXS_HighThroughputJPEG2000LosslessOnly = 52,
/// High-Throughput JPEG 2000 with RPCL Options Image Compression (Lossless Only)
EXS_HighThroughputJPEG2000withRPCLOptionsLosslessOnly = 50,
EXS_HighThroughputJPEG2000withRPCLOptionsLosslessOnly = 53,
/// High-Throughput JPEG 2000 Image Compression
EXS_HighThroughputJPEG2000 = 51,
EXS_HighThroughputJPEG2000 = 54,
/// JPIP HTJ2K Referenced
EXS_JPIPHTJ2KReferenced = 52,
EXS_JPIPHTJ2KReferenced = 55,
/// JPIP HTJ2K Referenced Deflate
EXS_JPIPHTJ2KReferencedDeflate = 53,
EXS_JPIPHTJ2KReferencedDeflate = 56,
/// Private GE Little Endian Implicit with big endian pixel data
EXS_PrivateGE_LEI_WithBigEndianPixelData = 54
EXS_PrivateGE_LEI_WithBigEndianPixelData = 57
} E_TransferSyntax;


Expand Down
3 changes: 3 additions & 0 deletions dcmdata/libsrc/dcuid.cc
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ static const UIDNameMap uidNameMap[] = {
{ UID_FragmentableMPEG4StereoHighProfileLevel4_2TransferSyntax, "MPEG4HP42STEREOF", "FragmentableMPEG4StereoHighProfile/Level4.2", { EUS_DICOM, EUV_Standard, EUT_TransferSyntax, EUST_other, EUIT_other, UID_PROP_NONE } },
{ UID_HEVCMainProfileLevel5_1TransferSyntax, "HEVCMP51", "HEVCMainProfile/Level5.1", { EUS_DICOM, EUV_Standard, EUT_TransferSyntax, EUST_other, EUIT_other, UID_PROP_NONE } },
{ UID_HEVCMain10ProfileLevel5_1TransferSyntax, "HEVCM10P51", "HEVCMain10Profile/Level5.1", { EUS_DICOM, EUV_Standard, EUT_TransferSyntax, EUST_other, EUIT_other, UID_PROP_NONE } },
{ UID_JPEGXLLosslessTransferSyntax, "JPEGXLLossless", "JPEGXLLossless", { EUS_DICOM, EUV_Standard, EUT_TransferSyntax, EUST_other, EUIT_other, UID_PROP_NONE } },
{ UID_JPEGXLJPEGRecompressionTransferSyntax, "JPEGXLJPEGRecompression", "JPEGXLJPEGRecompression", { EUS_DICOM, EUV_Standard, EUT_TransferSyntax, EUST_other, EUIT_other, UID_PROP_NONE } },
{ UID_JPEGXLTransferSyntax, "JPEGXL", "JPEGXL", { EUS_DICOM, EUV_Standard, EUT_TransferSyntax, EUST_other, EUIT_other, UID_PROP_NONE } },
{ UID_HighThroughputJPEG2000ImageCompressionLosslessOnlyTransferSyntax, "HTJ2KLossless", "HighThroughputJPEG2000ImageCompressionLosslessOnly", { EUS_DICOM, EUV_Standard, EUT_TransferSyntax, EUST_other, EUIT_other, UID_PROP_NONE } },
{ UID_HighThroughputJPEG2000RPCLImageCompressionLosslessOnlyTransferSyntax, "HTJ2KLosslessRPCL", "HighThroughputJPEG2000withRPCLOptionsImageCompressionLosslessOnly", { EUS_DICOM, EUV_Standard, EUT_TransferSyntax, EUST_other, EUIT_other, UID_PROP_NONE } },
{ UID_HighThroughputJPEG2000ImageCompressionTransferSyntax, "HTJ2K", "HighThroughputJPEG2000ImageCompression", { EUS_DICOM, EUV_Standard, EUT_TransferSyntax, EUST_other, EUIT_other, UID_PROP_NONE } },
Expand Down
52 changes: 47 additions & 5 deletions dcmdata/libsrc/dcxfer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,48 @@ const S_XferNames XferNames[] =
EXV_Standard
},
// entry #49
{ UID_JPEGXLLosslessTransferSyntax,
"JPEG XL Lossless",
EXS_JPEGXLLossless,
EBO_LittleEndian,
EBO_LittleEndian,
EVT_Explicit,
EPE_Encapsulated,
EPC_LosslessCompressed,
OFFalse,
0L, 0L,
ESC_none,
EXV_Standard
},
// entry #50
{ UID_JPEGXLJPEGRecompressionTransferSyntax,
"JPEG XL JPEG Recompression",
EXS_JPEGXLJPEGRecompression,
EBO_LittleEndian,
EBO_LittleEndian,
EVT_Explicit,
EPE_Encapsulated,
EPC_LossyCompressed,
OFFalse,
0L, 0L,
ESC_none,
EXV_Standard
},
// entry #51
{ UID_JPEGXLTransferSyntax,
"JPEG XL",
EXS_JPEGXL,
EBO_LittleEndian,
EBO_LittleEndian,
EVT_Explicit,
EPE_Encapsulated,
EPC_LossyCompressed,
OFFalse,
0L, 0L,
ESC_none,
EXV_Standard
},
// entry #52
{ UID_HighThroughputJPEG2000ImageCompressionLosslessOnlyTransferSyntax,
"High-Throughput JPEG 2000 Image Compression (Lossless Only)",
EXS_HighThroughputJPEG2000LosslessOnly,
Expand All @@ -755,7 +797,7 @@ const S_XferNames XferNames[] =
ESC_none,
EXV_Standard
},
// entry #50
// entry #53
{ UID_HighThroughputJPEG2000RPCLImageCompressionLosslessOnlyTransferSyntax,
"High-Throughput JPEG 2000 with RPCL Options Image Compression (Lossless Only)",
EXS_HighThroughputJPEG2000withRPCLOptionsLosslessOnly,
Expand All @@ -769,7 +811,7 @@ const S_XferNames XferNames[] =
ESC_none,
EXV_Standard
},
// entry #51
// entry #54
{ UID_HighThroughputJPEG2000ImageCompressionTransferSyntax,
"High-Throughput JPEG 2000 Image Compression",
EXS_HighThroughputJPEG2000,
Expand All @@ -783,7 +825,7 @@ const S_XferNames XferNames[] =
ESC_none,
EXV_Standard
},
// entry #52
// entry #55
{ UID_JPIPHTJ2KReferencedTransferSyntax,
"JPIP HTJ2K Referenced",
EXS_JPIPHTJ2KReferenced,
Expand All @@ -797,7 +839,7 @@ const S_XferNames XferNames[] =
ESC_none,
EXV_Standard
},
// entry #53
// entry #56
{ UID_JPIPHTJ2KReferencedDeflateTransferSyntax,
"JPIP HTJ2K Referenced Deflate",
EXS_JPIPHTJ2KReferencedDeflate,
Expand All @@ -815,7 +857,7 @@ const S_XferNames XferNames[] =
#endif
EXV_Standard
},
// entry #54
// entry #57
{ UID_PrivateGE_LEI_WithBigEndianPixelDataTransferSyntax,
"Private GE Little Endian Implicit with big endian pixel data",
EXS_PrivateGE_LEI_WithBigEndianPixelData,
Expand Down
5 changes: 4 additions & 1 deletion dcmnet/apps/echoscu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,10 @@ static const char* transferSyntaxes[] = {
UID_FragmentableMPEG4StereoHighProfileLevel4_2TransferSyntax,
UID_HighThroughputJPEG2000ImageCompressionLosslessOnlyTransferSyntax,
UID_HighThroughputJPEG2000RPCLImageCompressionLosslessOnlyTransferSyntax,
UID_HighThroughputJPEG2000ImageCompressionTransferSyntax
UID_HighThroughputJPEG2000ImageCompressionTransferSyntax,
UID_JPEGXLLosslessTransferSyntax,
UID_JPEGXLJPEGRecompressionTransferSyntax,
UID_JPEGXLTransferSyntax
};

// ********************************************
Expand Down
21 changes: 12 additions & 9 deletions dcmnet/apps/movescu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,7 @@ acceptSubAssoc(T_ASC_Network *aNet, T_ASC_Association **assoc)
const char* transferSyntaxes[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 10
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 20
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 30
NULL, NULL }; // +2
NULL, NULL, NULL, NULL, NULL }; // +5
int numTransferSyntaxes;
OFString temp_str;

Expand Down Expand Up @@ -1207,18 +1207,21 @@ acceptSubAssoc(T_ASC_Network *aNet, T_ASC_Association **assoc)
transferSyntaxes[24] = UID_HighThroughputJPEG2000ImageCompressionLosslessOnlyTransferSyntax;
transferSyntaxes[25] = UID_HighThroughputJPEG2000RPCLImageCompressionLosslessOnlyTransferSyntax;
transferSyntaxes[26] = UID_HighThroughputJPEG2000ImageCompressionTransferSyntax;
transferSyntaxes[27] = UID_DeflatedExplicitVRLittleEndianTransferSyntax;
transferSyntaxes[28] = UID_EncapsulatedUncompressedExplicitVRLittleEndianTransferSyntax;
transferSyntaxes[27] = UID_JPEGXLLosslessTransferSyntax;
transferSyntaxes[28] = UID_JPEGXLJPEGRecompressionTransferSyntax;
transferSyntaxes[29] = UID_JPEGXLTransferSyntax;
transferSyntaxes[30] = UID_DeflatedExplicitVRLittleEndianTransferSyntax;
transferSyntaxes[31] = UID_EncapsulatedUncompressedExplicitVRLittleEndianTransferSyntax;
if (gLocalByteOrder == EBO_LittleEndian)
{
transferSyntaxes[29] = UID_LittleEndianExplicitTransferSyntax;
transferSyntaxes[30] = UID_BigEndianExplicitTransferSyntax;
transferSyntaxes[32] = UID_LittleEndianExplicitTransferSyntax;
transferSyntaxes[33] = UID_BigEndianExplicitTransferSyntax;
} else {
transferSyntaxes[29] = UID_BigEndianExplicitTransferSyntax;
transferSyntaxes[30] = UID_LittleEndianExplicitTransferSyntax;
transferSyntaxes[32] = UID_BigEndianExplicitTransferSyntax;
transferSyntaxes[33] = UID_LittleEndianExplicitTransferSyntax;
}
transferSyntaxes[31] = UID_LittleEndianImplicitTransferSyntax;
numTransferSyntaxes = 32;
transferSyntaxes[34] = UID_LittleEndianImplicitTransferSyntax;
numTransferSyntaxes = 35;
} else {
/* We prefer explicit transfer syntaxes.
* If we are running on a Little Endian machine we prefer
Expand Down
21 changes: 12 additions & 9 deletions dcmnet/apps/storescp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ static OFCondition acceptAssociation(T_ASC_Network *net, DcmAssociationConfigura
const char* transferSyntaxes[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 10
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 20
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 30
NULL, NULL }; // +2
NULL, NULL, NULL, NULL, NULL }; // +5
int numTransferSyntaxes = 0;

// try to receive an association. Here we either want to use blocking or
Expand Down Expand Up @@ -1302,18 +1302,21 @@ static OFCondition acceptAssociation(T_ASC_Network *net, DcmAssociationConfigura
transferSyntaxes[24] = UID_HighThroughputJPEG2000ImageCompressionLosslessOnlyTransferSyntax;
transferSyntaxes[25] = UID_HighThroughputJPEG2000RPCLImageCompressionLosslessOnlyTransferSyntax;
transferSyntaxes[26] = UID_HighThroughputJPEG2000ImageCompressionTransferSyntax;
transferSyntaxes[27] = UID_DeflatedExplicitVRLittleEndianTransferSyntax;
transferSyntaxes[28] = UID_EncapsulatedUncompressedExplicitVRLittleEndianTransferSyntax;
transferSyntaxes[27] = UID_JPEGXLLosslessTransferSyntax;
transferSyntaxes[28] = UID_JPEGXLJPEGRecompressionTransferSyntax;
transferSyntaxes[29] = UID_JPEGXLTransferSyntax;
transferSyntaxes[30] = UID_DeflatedExplicitVRLittleEndianTransferSyntax;
transferSyntaxes[31] = UID_EncapsulatedUncompressedExplicitVRLittleEndianTransferSyntax;
if (gLocalByteOrder == EBO_LittleEndian)
{
transferSyntaxes[29] = UID_LittleEndianExplicitTransferSyntax;
transferSyntaxes[30] = UID_BigEndianExplicitTransferSyntax;
transferSyntaxes[32] = UID_LittleEndianExplicitTransferSyntax;
transferSyntaxes[33] = UID_BigEndianExplicitTransferSyntax;
} else {
transferSyntaxes[29] = UID_BigEndianExplicitTransferSyntax;
transferSyntaxes[30] = UID_LittleEndianExplicitTransferSyntax;
transferSyntaxes[32] = UID_BigEndianExplicitTransferSyntax;
transferSyntaxes[33] = UID_LittleEndianExplicitTransferSyntax;
}
transferSyntaxes[31] = UID_LittleEndianImplicitTransferSyntax;
numTransferSyntaxes = 32;
transferSyntaxes[34] = UID_LittleEndianImplicitTransferSyntax;
numTransferSyntaxes = 35;
} else {
/* We prefer explicit transfer syntaxes.
* If we are running on a Little Endian machine we prefer
Expand Down
30 changes: 15 additions & 15 deletions dcmnet/docs/dcmsend.man
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ Please note, however, that "unsuccessful store" does not mean that the DIMSE
status of the C-STORE response indicates an error. It means that the C-STORE
request could not be sent to the storage SCP.

If more than 128 presentation contexts are needed, which is the maximum number
If more than 128 Presentation Contexts are needed, which is the maximum number
allowed according to the DICOM standard, a new association is started after the
previous one has been completed. In cases where this behavior is unwanted, it
can be disabled using option \e --single-association. In addition, whether
Expand Down Expand Up @@ -278,20 +278,20 @@ UID of the DICOM file in order to make sure that only valid SOP instances are
sent. With option \e --no-uid-checks this check can be disabled.

The \b dcmsend application also supports all Transfer Syntaxes that are defined
in the DICOM standard. Private transfer syntaxes can only be used if the UID
in the DICOM standard. Private Transfer Syntaxes can only be used if the UID
check is disabled with option \e --no-uid-checks. Please note, however, that
only a limited number of transfer syntaxes are supported for converting them to
the default transfer syntax (Implicit VR Little Endian). With option
\e --list-decoders the transfer syntaxes supported natively or by decoders are
only a limited number of Transfer Syntaxes are supported for converting them to
the DICOM Default Transfer Syntax (Implicit VR Little Endian). With option
\e --list-decoders the Transfer Syntaxes supported natively or by decoders are
listed. The output typically looks like the following:

\verbatim
Transfer syntaxes supported natively:
Transfer Syntaxes supported natively:
- Little Endian Implicit
- Little Endian Explicit
- Big Endian Explicit

Transfer syntaxes supported by decoders:
Transfer Syntaxes supported by decoders:
- Deflated Explicit VR Little Endian
- JPEG Baseline
- JPEG Extended, Process 2+4
Expand All @@ -305,18 +305,18 @@ Transfer syntaxes supported by decoders:
\endverbatim

Since \b dcmsend tries to be as simple as possible for the user, by default
presentation contexts might be proposed to the SCP that are strictly speaking
Presentation Contexts might be proposed to the SCP that are strictly speaking
"illegal". This is because, according to the DICOM standard, the SCU always
has to propose the default transfer syntax in at least one presentation context
associated with each abstract syntax (i.e. SOP class). This requirement is
waived if the SCU only has access to the SOP instance in lossy compressed form
or if the decompressed pixel data would be too large to be encoded. With
has to propose the DICOM Default Transfer Syntax in at least one Presentation
Context associated with each abstract syntax (i.e. SOP class). This requirement
is waived if the SCU only has access to the SOP instance in lossy compressed
form or if the decompressed pixel data would be too large to be encoded. With
option \e --no-illegal-proposal the strict DICOM-conformant behavior can be
enforced, i.e. no possibly illegal presentation context will be proposed but
enforced, i.e. no possibly illegal Presentation Context will be proposed but
the corresponding SOP instance will be rejected (if needed). Please note,
however, that the size of the decompressed pixel data is not checked.

The default transfer syntax for "Lossless JPEG Compression", "Lossy JPEG
The default Transfer Syntax for "Lossless JPEG Compression", "Lossy JPEG
Compression" and so on are not always proposed as also required by the DICOM
standard. The same limitation applies to other compression schemes. See DICOM
PS 3.5 section 10 for details.
Expand Down Expand Up @@ -420,6 +420,6 @@ It is an error if no data dictionary can be loaded.

\section dcmsend_copyright COPYRIGHT

Copyright (C) 2011-2023 by OFFIS e.V., Escherweg 2, 26121 Oldenburg, Germany.
Copyright (C) 2011-2024 by OFFIS e.V., Escherweg 2, 26121 Oldenburg, Germany.

*/
2 changes: 1 addition & 1 deletion dcmnet/docs/echoscu.man
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ application entity titles:

association negotiation debugging:

-pts --propose-ts [n]umber: integer (1..49)
-pts --propose-ts [n]umber: integer (1..52)
propose n transfer syntaxes

-ppc --propose-pc [n]umber: integer (1..128)
Expand Down
3 changes: 3 additions & 0 deletions dcmnet/docs/movescu.man
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,9 @@ MPEG4StereoHighProfileLevel4_2TransferSyntax 1.2.840.10008.1.2.4.106
FragmentableMPEG4StereoHighProfileLevel4_2TransferS. 1.2.840.10008.1.2.4.106.1
HEVCMainProfileLevel5_1TransferSyntax 1.2.840.10008.1.2.4.107
HEVCMain10ProfileLevel5_1TransferSyntax 1.2.840.10008.1.2.4.108
JPEGXLLosslesTransferSyntax 1.2.840.10008.1.2.4.110
JPEGXLJPEGRecompressionTransferSyntax 1.2.840.10008.1.2.4.111
JPEGXLTransferSyntax 1.2.840.10008.1.2.4.112
HighThroughputJPEG2000ImageCompressionLossless.Tr.S. 1.2.840.10008.1.2.4.201
HighThroughputJPEG2000RPCLImageCompressionLoss.Tr.S. 1.2.840.10008.1.2.4.202
HighThroughputJPEG2000ImageCompressionTransferSynta. 1.2.840.10008.1.2.4.203
Expand Down
5 changes: 4 additions & 1 deletion dcmnet/docs/storescp.man
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,9 @@ MPEG4StereoHighProfileLevel4_2TransferSyntax 1.2.840.10008.1.2.4.106
FragmentableMPEG4StereoHighProfileLevel4_2TransferS. 1.2.840.10008.1.2.4.106.1
HEVCMainProfileLevel5_1TransferSyntax 1.2.840.10008.1.2.4.107
HEVCMain10ProfileLevel5_1TransferSyntax 1.2.840.10008.1.2.4.108
JPEGXLLosslesTransferSyntax 1.2.840.10008.1.2.4.110
JPEGXLJPEGRecompressionTransferSyntax 1.2.840.10008.1.2.4.111
JPEGXLTransferSyntax 1.2.840.10008.1.2.4.112
HighThroughputJPEG2000ImageCompressionLossless.Tr.S. 1.2.840.10008.1.2.4.201
HighThroughputJPEG2000RPCLImageCompressionLoss.Tr.S. 1.2.840.10008.1.2.4.202
HighThroughputJPEG2000ImageCompressionTransferSynta. 1.2.840.10008.1.2.4.203
Expand All @@ -884,7 +887,7 @@ RLELosslessTransferSyntax 1.2.840.10008.1.2.5

(*) if compiled with zlib support enabled (see \e --version output)

Additional Storage SOP Classes and Transfer Syntaxes can be used with the
Additional Storage SOP Classes and transfer syntaxes can be used with the
so-called "association negotiation profiles" (see below). This could be both
Private Storage SOP Classes and Standard Storage SOP Classes that do not fit
into the PATIENT-STUDY-SERIES-INSTANCE information model.
Expand Down
Loading

0 comments on commit ec1bb01

Please sign in to comment.