Mercurial > hg > orthanc-wsi
changeset 220:7ffcce8ec94c
Fix issue #145 (support of Concatenation UID)
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 12 Jan 2021 18:32:30 +0100 |
parents | ef3f8c5126a4 |
children | dbcf9ad44a70 |
files | Framework/Outputs/DicomPyramidWriter.cpp Framework/Outputs/MultiframeDicomWriter.cpp Framework/Outputs/MultiframeDicomWriter.h NEWS |
diffstat | 4 files changed, 54 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/Framework/Outputs/DicomPyramidWriter.cpp Tue Jan 12 17:09:57 2021 +0100 +++ b/Framework/Outputs/DicomPyramidWriter.cpp Tue Jan 12 18:32:30 2021 +0100 @@ -138,9 +138,10 @@ if (writer == NULL) { + const bool isConcatenation = (maxSize_ != 0); writer = new MultiframeDicomWriter (dataset_, GetImageCompression(), GetPixelFormat(), level.width_, level.height_, - GetTileWidth(), GetTileHeight(), photometric_); + GetTileWidth(), GetTileHeight(), photometric_, isConcatenation); writers_[z] = writer; {
--- a/Framework/Outputs/MultiframeDicomWriter.cpp Tue Jan 12 17:09:57 2021 +0100 +++ b/Framework/Outputs/MultiframeDicomWriter.cpp Tue Jan 12 18:32:30 2021 +0100 @@ -25,8 +25,9 @@ #include "../DicomToolbox.h" #include <Compatibility.h> // For std::unique_ptr +#include <DicomParsing/FromDcmtkBridge.h> +#include <Logging.h> #include <OrthancException.h> -#include <Logging.h> #include <dcmtk/dcmdata/dcuid.h> #include <dcmtk/dcmdata/dcdeftag.h> @@ -98,6 +99,9 @@ offsetList_.reset(new DcmOffsetList); } + firstFrameInInstance_ += framesCount_; + countInstances_ ++; + writtenSize_ = 0; framesCount_ = 0; } @@ -150,10 +154,15 @@ unsigned int height, unsigned int tileWidth, unsigned int tileHeight, - Orthanc::PhotometricInterpretation photometric) : + Orthanc::PhotometricInterpretation photometric, + bool isConcatenation) : compression_(compression), + framesCount_(0), width_(width), - height_(height) + height_(height), + isConcatenation_(isConcatenation), + countInstances_(0), + firstFrameInInstance_(0) { switch (compression) { @@ -208,6 +217,28 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } + if (isConcatenation) + { + /** + * Generate a shared SOP Instance UID that corresponds to the + * main instance containing all the instances. This main + * instance is purely "virtual", as it is never generated. + * https://bugs.orthanc-server.com/show_bug.cgi?id=145 + * http://dicom.nema.org/medical/dicom/2020d/output/chtml/part03/figures/PS3.3_C.7.6.16-1a.svg + **/ + DicomToolbox::SetStringTag(sharedTags_, DCM_SOPInstanceUIDOfConcatenationSource, + Orthanc::FromDcmtkBridge::GenerateUniqueIdentifier(Orthanc::ResourceType_Instance)); + + /** + * Similarly, we generate one random UID to identify the + * concatenation. As we never generate two different + * concatenations of the "main" instance, this UID is shared by + * all the instances of the concatenation. + **/ + DicomToolbox::SetStringTag(sharedTags_, DCM_ConcatenationUID, + Orthanc::FromDcmtkBridge::GenerateUniqueIdentifier(Orthanc::ResourceType_Instance)); + } + ResetImage(); } @@ -259,23 +290,27 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } - std::string tmp = boost::lexical_cast<std::string>(instanceNumber); - std::unique_ptr<DcmFileFormat> dicom(new DcmFileFormat); - char uid[100]; - dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT); - + const std::string uid = Orthanc::FromDcmtkBridge::GenerateUniqueIdentifier(Orthanc::ResourceType_Instance); + if (!dicom->getDataset()->copyFrom(sharedTags_).good() || !dicom->getDataset()->insert(perFrameFunctionalGroups_.release(), false, false).good() || - !dicom->getDataset()->putAndInsertString(DCM_SOPInstanceUID, uid).good() || - !dicom->getDataset()->putAndInsertString(DCM_InstanceNumber, tmp.c_str()).good()) + !dicom->getDataset()->putAndInsertString(DCM_SOPInstanceUID, uid.c_str()).good()) { throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); } + // The two tags below have "IS" (integer string) value representation + DicomToolbox::SetStringTag(*dicom->getDataset(), DCM_InstanceNumber, boost::lexical_cast<std::string>(instanceNumber)); DicomToolbox::SetStringTag(*dicom->getDataset(), DCM_NumberOfFrames, boost::lexical_cast<std::string>(framesCount_)); + if (isConcatenation_) + { + DicomToolbox::SetUint32Tag(*dicom->getDataset(), DCM_ConcatenationFrameOffsetNumber, firstFrameInInstance_); + DicomToolbox::SetUint16Tag(*dicom->getDataset(), DCM_InConcatenationNumber, countInstances_); + } + switch (compression_) { case ImageCompression_None:
--- a/Framework/Outputs/MultiframeDicomWriter.h Tue Jan 12 17:09:57 2021 +0100 +++ b/Framework/Outputs/MultiframeDicomWriter.h Tue Jan 12 18:32:30 2021 +0100 @@ -54,6 +54,10 @@ DcmPixelItem* offsetTable_; std::unique_ptr<DcmOffsetList> offsetList_; + bool isConcatenation_; + unsigned int countInstances_; + unsigned int firstFrameInInstance_; + void ResetImage(); void InjectUncompressedPixelData(DcmFileFormat& dicom); @@ -66,7 +70,8 @@ unsigned int height, unsigned int tileWidth, unsigned int tileHeight, - Orthanc::PhotometricInterpretation photometric); + Orthanc::PhotometricInterpretation photometric, + bool isConcatenation); void AddFrame(const std::string& frame, DcmItem* functionalGroup); // This takes the ownership
--- a/NEWS Tue Jan 12 17:09:57 2021 +0100 +++ b/NEWS Tue Jan 12 18:32:30 2021 +0100 @@ -6,6 +6,7 @@ * Better handling of PhotometricInterpretation in viewer * Fix colorspace of TIFF containing JPEG with RGB photometric interpretation (not YCbCr) * Don't display the thumbnail/overview instances in the Web viewer +* Fix issue #145 (support of Concatenation UID) * Support of dynamic linking against the system-wide Orthanc framework library