# HG changeset patch # User Sebastien Jodogne # Date 1588864880 -7200 # Node ID c62f84c7eda91900e4b584b0c082c9c301fc8ae6 # Parent d1273d7cc20099d025403b51330847bf2c9114e0 fixing incorrect behavior in MemoryBufferTranscoder diff -r d1273d7cc200 -r c62f84c7eda9 Core/DicomNetworking/DicomStoreUserConnection.cpp --- a/Core/DicomNetworking/DicomStoreUserConnection.cpp Thu May 07 16:43:08 2020 +0200 +++ b/Core/DicomNetworking/DicomStoreUserConnection.cpp Thu May 07 17:21:20 2020 +0200 @@ -495,7 +495,7 @@ bool hasSopInstanceUidChanged; - if (transcoder.HasInplaceTranscode()) + if (transcoder.HasInplaceTranscode(inputSyntax, uncompressedSyntaxes)) { if (transcoder.InplaceTranscode(hasSopInstanceUidChanged, *dicom, uncompressedSyntaxes, false)) { diff -r d1273d7cc200 -r c62f84c7eda9 Core/DicomParsing/DcmtkTranscoder.cpp --- a/Core/DicomParsing/DcmtkTranscoder.cpp Thu May 07 16:43:08 2020 +0200 +++ b/Core/DicomParsing/DcmtkTranscoder.cpp Thu May 07 17:21:20 2020 +0200 @@ -339,4 +339,36 @@ return true; } } + + + bool DcmtkTranscoder::IsSupported(DicomTransferSyntax syntax) + { + if (syntax == DicomTransferSyntax_LittleEndianImplicit || + syntax == DicomTransferSyntax_LittleEndianExplicit || + syntax == DicomTransferSyntax_BigEndianExplicit || + syntax == DicomTransferSyntax_DeflatedLittleEndianExplicit) + { + return true; + } + +#if ORTHANC_ENABLE_DCMTK_JPEG == 1 + if (syntax == DicomTransferSyntax_JPEGProcess1 || + syntax == DicomTransferSyntax_JPEGProcess2_4 || + syntax == DicomTransferSyntax_JPEGProcess14 || + syntax == DicomTransferSyntax_JPEGProcess14SV1) + { + return true; + } +#endif + +#if ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS == 1 + if (syntax == DicomTransferSyntax_JPEGLSLossless || + syntax == DicomTransferSyntax_JPEGLSLossy) + { + return true; + } +#endif + + return false; + } } diff -r d1273d7cc200 -r c62f84c7eda9 Core/DicomParsing/DcmtkTranscoder.h --- a/Core/DicomParsing/DcmtkTranscoder.h Thu May 07 16:43:08 2020 +0200 +++ b/Core/DicomParsing/DcmtkTranscoder.h Thu May 07 17:21:20 2020 +0200 @@ -69,7 +69,8 @@ const std::set& allowedSyntaxes, bool allowNewSopInstanceUid) ORTHANC_OVERRIDE; - virtual bool HasInplaceTranscode() const + virtual bool HasInplaceTranscode(DicomTransferSyntax inputSyntax, + const std::set& outputSyntaxes) const { return true; } @@ -85,5 +86,7 @@ size_t size, const std::set& allowedSyntaxes, bool allowNewSopInstanceUid) ORTHANC_OVERRIDE; + + static bool IsSupported(DicomTransferSyntax syntax); }; } diff -r d1273d7cc200 -r c62f84c7eda9 Core/DicomParsing/IDicomTranscoder.h --- a/Core/DicomParsing/IDicomTranscoder.h Thu May 07 16:43:08 2020 +0200 +++ b/Core/DicomParsing/IDicomTranscoder.h Thu May 07 17:21:20 2020 +0200 @@ -73,7 +73,8 @@ const std::set& allowedSyntaxes, bool allowNewSopInstanceUid) = 0; - virtual bool HasInplaceTranscode() const = 0; + virtual bool HasInplaceTranscode(DicomTransferSyntax inputSyntax, + const std::set& outputSyntaxes) const = 0; /** * In-place transcoding. This method is preferred for C-STORE. diff -r d1273d7cc200 -r c62f84c7eda9 Core/DicomParsing/MemoryBufferTranscoder.cpp --- a/Core/DicomParsing/MemoryBufferTranscoder.cpp Thu May 07 16:43:08 2020 +0200 +++ b/Core/DicomParsing/MemoryBufferTranscoder.cpp Thu May 07 17:21:20 2020 +0200 @@ -111,13 +111,54 @@ } + bool MemoryBufferTranscoder::HasInplaceTranscode( + DicomTransferSyntax inputSyntax, + const std::set& outputSyntaxes) const + { + /** + * Inplace transcoding is only possible if DCMTK is enabled, and + * if DCMTK supports all the requested transfer + * syntaxes. Otherwise, one has to call the "buffer-to-buffer" + * transcoder. + **/ + +#if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 + if (useDcmtk_) + { + if (!DcmtkTranscoder::IsSupported(inputSyntax)) + { + return false; + } + + for (std::set::const_iterator + it = outputSyntaxes.begin(); it != outputSyntaxes.end(); ++it) + { + if (!DcmtkTranscoder::IsSupported(*it)) + { + return false; + } + } + + return true; + } + else +#endif + { + return false; + } + } + + bool MemoryBufferTranscoder::InplaceTranscode(bool& hasSopInstanceUidChanged, DcmFileFormat& dicom, const std::set& allowedSyntaxes, bool allowNewSopInstanceUid) { #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 - if (useDcmtk_) + DicomTransferSyntax inputSyntax; + if (useDcmtk_ && + FromDcmtkBridge::LookupOrthancTransferSyntax(inputSyntax, dicom) && + HasInplaceTranscode(inputSyntax, allowedSyntaxes)) { return dcmtk_.InplaceTranscode(hasSopInstanceUidChanged, dicom, allowedSyntaxes, allowNewSopInstanceUid); } diff -r d1273d7cc200 -r c62f84c7eda9 Core/DicomParsing/MemoryBufferTranscoder.h --- a/Core/DicomParsing/MemoryBufferTranscoder.h Thu May 07 16:43:08 2020 +0200 +++ b/Core/DicomParsing/MemoryBufferTranscoder.h Thu May 07 17:21:20 2020 +0200 @@ -88,10 +88,9 @@ const std::set& allowedSyntaxes, bool allowNewSopInstanceUid) ORTHANC_OVERRIDE; - virtual bool HasInplaceTranscode() const ORTHANC_OVERRIDE - { - return useDcmtk_; - } + virtual bool HasInplaceTranscode( + DicomTransferSyntax inputSyntax, + const std::set& outputSyntaxes) const ORTHANC_OVERRIDE; virtual bool InplaceTranscode(bool& hasSopInstanceUidChanged /* out */, DcmFileFormat& dicom, diff -r d1273d7cc200 -r c62f84c7eda9 OrthancServer/ServerContext.cpp --- a/OrthancServer/ServerContext.cpp Thu May 07 16:43:08 2020 +0200 +++ b/OrthancServer/ServerContext.cpp Thu May 07 17:21:20 2020 +0200 @@ -1161,6 +1161,13 @@ const std::set& allowedSyntaxes, bool allowNewSopInstanceUid) { + DicomTransferSyntax inputSyntax; + if (!FromDcmtkBridge::LookupOrthancTransferSyntax(inputSyntax, dicom.GetDcmtkObject())) + { + throw OrthancException(ErrorCode_BadFileFormat, + "Cannot determine the source transfer syntax during transcoding"); + } + IDicomTranscoder* transcoder = dcmtkTranscoder_.get(); #if ORTHANC_ENABLE_PLUGINS == 1 @@ -1174,7 +1181,7 @@ { throw OrthancException(ErrorCode_InternalError); } - else if (transcoder->HasInplaceTranscode()) + else if (transcoder->HasInplaceTranscode(inputSyntax, allowedSyntaxes)) { if (transcoder->InplaceTranscode(hasSopInstanceUidChanged, dicom.GetDcmtkObject(), allowedSyntaxes, allowNewSopInstanceUid)) diff -r d1273d7cc200 -r c62f84c7eda9 OrthancServer/ServerContext.h --- a/OrthancServer/ServerContext.h Thu May 07 16:43:08 2020 +0200 +++ b/OrthancServer/ServerContext.h Thu May 07 17:21:20 2020 +0200 @@ -463,10 +463,11 @@ const std::string& moveOriginatorAet, uint16_t moveOriginatorId); - // This method can be used even if "TranscodingEnabled" is set to "false" + // This method can be used even if the global option + // "TranscodingEnabled" is set to "false" bool Transcode(std::string& target, bool& hasSopInstanceUidChanged, - ParsedDicomFile& dicom, // Possibly modified + ParsedDicomFile& dicom, // Can possibly be modified const std::set& allowedSyntaxes, bool allowNewSopInstanceUid); };