Mercurial > hg > orthanc
changeset 3904:c62f84c7eda9 transcoding
fixing incorrect behavior in MemoryBufferTranscoder
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 07 May 2020 17:21:20 +0200 |
parents | d1273d7cc200 |
children | 061f3d031b5d |
files | Core/DicomNetworking/DicomStoreUserConnection.cpp Core/DicomParsing/DcmtkTranscoder.cpp Core/DicomParsing/DcmtkTranscoder.h Core/DicomParsing/IDicomTranscoder.h Core/DicomParsing/MemoryBufferTranscoder.cpp Core/DicomParsing/MemoryBufferTranscoder.h OrthancServer/ServerContext.cpp OrthancServer/ServerContext.h |
diffstat | 8 files changed, 95 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- 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)) {
--- 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; + } }
--- 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<DicomTransferSyntax>& allowedSyntaxes, bool allowNewSopInstanceUid) ORTHANC_OVERRIDE; - virtual bool HasInplaceTranscode() const + virtual bool HasInplaceTranscode(DicomTransferSyntax inputSyntax, + const std::set<DicomTransferSyntax>& outputSyntaxes) const { return true; } @@ -85,5 +86,7 @@ size_t size, const std::set<DicomTransferSyntax>& allowedSyntaxes, bool allowNewSopInstanceUid) ORTHANC_OVERRIDE; + + static bool IsSupported(DicomTransferSyntax syntax); }; }
--- 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<DicomTransferSyntax>& allowedSyntaxes, bool allowNewSopInstanceUid) = 0; - virtual bool HasInplaceTranscode() const = 0; + virtual bool HasInplaceTranscode(DicomTransferSyntax inputSyntax, + const std::set<DicomTransferSyntax>& outputSyntaxes) const = 0; /** * In-place transcoding. This method is preferred for C-STORE.
--- 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<DicomTransferSyntax>& 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<DicomTransferSyntax>::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<DicomTransferSyntax>& 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); }
--- 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<DicomTransferSyntax>& allowedSyntaxes, bool allowNewSopInstanceUid) ORTHANC_OVERRIDE; - virtual bool HasInplaceTranscode() const ORTHANC_OVERRIDE - { - return useDcmtk_; - } + virtual bool HasInplaceTranscode( + DicomTransferSyntax inputSyntax, + const std::set<DicomTransferSyntax>& outputSyntaxes) const ORTHANC_OVERRIDE; virtual bool InplaceTranscode(bool& hasSopInstanceUidChanged /* out */, DcmFileFormat& dicom,
--- 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<DicomTransferSyntax>& 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))
--- 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<DicomTransferSyntax>& allowedSyntaxes, bool allowNewSopInstanceUid); };