Mercurial > hg > orthanc
diff Core/DicomParsing/FromDcmtkBridge.cpp @ 3748:ca36e3f1112c transcoding
transcoding to uncompressed transfer syntaxes
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 13 Mar 2020 16:50:13 +0100 |
parents | 33c19a6643e1 |
children | 4a25727401cd |
line wrap: on
line diff
--- a/Core/DicomParsing/FromDcmtkBridge.cpp Fri Mar 13 08:32:13 2020 +0100 +++ b/Core/DicomParsing/FromDcmtkBridge.cpp Fri Mar 13 16:50:13 2020 +0100 @@ -120,6 +120,12 @@ #endif +#include <dcmtk/dcmdata/dcrledrg.h> +#if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 +# include <dcmtk/dcmdata/dcrleerg.h> +#endif + + namespace Orthanc { static bool IsBinaryTag(const DcmTag& key) @@ -1197,6 +1203,52 @@ } } + + + static bool SaveToMemoryBufferInternal(std::string& buffer, + DcmFileFormat& dicom, + E_TransferSyntax xfer) + { + E_EncodingType encodingType = /*opt_sequenceType*/ EET_ExplicitLength; + + // Create a memory buffer with the proper size + { + const uint32_t estimatedSize = dicom.calcElementLength(xfer, encodingType); // (*) + buffer.resize(estimatedSize); + } + + DcmOutputBufferStream ob(&buffer[0], buffer.size()); + + // Fill the memory buffer with the meta-header and the dataset + dicom.transferInit(); + OFCondition c = dicom.write(ob, xfer, encodingType, NULL, + /*opt_groupLength*/ EGL_recalcGL, + /*opt_paddingType*/ EPD_withoutPadding); + dicom.transferEnd(); + + if (c.good()) + { + // The DICOM file is successfully written, truncate the target + // buffer if its size was overestimated by (*) + ob.flush(); + + size_t effectiveSize = static_cast<size_t>(ob.tell()); + if (effectiveSize < buffer.size()) + { + buffer.resize(effectiveSize); + } + + return true; + } + else + { + // Error + buffer.clear(); + return false; + } + } + + bool FromDcmtkBridge::SaveToMemoryBuffer(std::string& buffer, DcmDataset& dataSet) { @@ -1221,47 +1273,51 @@ xfer = EXS_LittleEndianExplicit; } - E_EncodingType encodingType = /*opt_sequenceType*/ EET_ExplicitLength; - // Create the meta-header information DcmFileFormat ff(&dataSet); ff.validateMetaInfo(xfer); ff.removeInvalidGroups(); - // Create a memory buffer with the proper size + return SaveToMemoryBufferInternal(buffer, ff, xfer); + } + + + bool FromDcmtkBridge::SaveToMemoryBuffer(std::string& buffer, + DcmFileFormat& dicom) + { + E_TransferSyntax xfer = dicom.getDataset()->getOriginalXfer(); + if (xfer == EXS_Unknown) { - const uint32_t estimatedSize = ff.calcElementLength(xfer, encodingType); // (*) - buffer.resize(estimatedSize); + throw OrthancException(ErrorCode_InternalError, + "Cannot write a DICOM instance with unknown transfer syntax"); } - - DcmOutputBufferStream ob(&buffer[0], buffer.size()); - - // Fill the memory buffer with the meta-header and the dataset - ff.transferInit(); - OFCondition c = ff.write(ob, xfer, encodingType, NULL, - /*opt_groupLength*/ EGL_recalcGL, - /*opt_paddingType*/ EPD_withoutPadding); - ff.transferEnd(); - - if (c.good()) + else if (!dicom.validateMetaInfo(xfer).good()) { - // The DICOM file is successfully written, truncate the target - // buffer if its size was overestimated by (*) - ob.flush(); - - size_t effectiveSize = static_cast<size_t>(ob.tell()); - if (effectiveSize < buffer.size()) - { - buffer.resize(effectiveSize); - } - - return true; + throw OrthancException(ErrorCode_InternalError, + "Cannot setup the transfer syntax to write a DICOM instance"); } else { - // Error - buffer.clear(); - return false; + return SaveToMemoryBufferInternal(buffer, dicom, xfer); + } + } + + + bool FromDcmtkBridge::Transcode(std::string& buffer, + DcmFileFormat& dicom, + DicomTransferSyntax syntax, + const DcmRepresentationParameter* representation) + { + E_TransferSyntax xfer; + if (!LookupDcmtkTransferSyntax(xfer, syntax)) + { + throw OrthancException(ErrorCode_InternalError); + } + else + { + return (dicom.getDataset()->chooseRepresentation(xfer, representation).good() && + dicom.getDataset()->canWriteXfer(xfer) && + SaveToMemoryBufferInternal(buffer, dicom, xfer)); } } @@ -2064,6 +2120,12 @@ DJEncoderRegistration::registerCodecs(); # endif #endif + + LOG(INFO) << "Registering RLE codecs in DCMTK"; + DcmRLEDecoderRegistration::registerCodecs(); +#if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 + DcmRLEEncoderRegistration::registerCodecs(); +#endif } @@ -2084,6 +2146,11 @@ DJEncoderRegistration::cleanup(); # endif #endif + + DcmRLEDecoderRegistration::cleanup(); +#if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 + DcmRLEEncoderRegistration::cleanup(); +#endif }