# HG changeset patch # User Sebastien Jodogne # Date 1481799118 -3600 # Node ID 0cb3ac4f9159537c4a0de68bb1e6e78d95e05c8a # Parent 5b127ab0080b279c9f5876ae8584931921483495 refactoring diff -r 5b127ab0080b -r 0cb3ac4f9159 Applications/Dicomizer.cpp --- a/Applications/Dicomizer.cpp Wed Dec 14 17:01:34 2016 +0100 +++ b/Applications/Dicomizer.cpp Thu Dec 15 11:51:58 2016 +0100 @@ -260,78 +260,87 @@ const OrthancWSI::ITiledPyramid& source, const OrthancWSI::ImagedVolumeParameters& volume) { - std::string uid; + // Extract the identifier of the Dimension Organization, if provided + std::string organization; DcmItem* previous = OrthancWSI::DicomToolbox::ExtractSingleSequenceItem(dataset, DCM_DimensionOrganizationSequence); - if (previous != NULL) + if (previous != NULL && + previous->tagExists(DCM_DimensionOrganizationUID)) + { + organization = OrthancWSI::DicomToolbox::GetStringTag(*previous, DCM_DimensionOrganizationUID); + } + else { - const char* tmp = NULL; - if (previous->findAndGetString(DCM_DimensionOrganizationUID, tmp).good() && - tmp != NULL) + // No Dimension Organization provided: Generate an unique identifier + organization = Orthanc::FromDcmtkBridge::GenerateUniqueIdentifier(Orthanc::ResourceType_Instance); + } + + + { + // Construct tag "Dimension Organization Sequence" (0020,9221) + std::auto_ptr item(new DcmItem); + OrthancWSI::DicomToolbox::SetStringTag(*item, DCM_DimensionOrganizationUID, organization); + + std::auto_ptr sequence(new DcmSequenceOfItems(DCM_DimensionOrganizationSequence)); + + if (!sequence->insert(item.release(), false, false).good() || + !dataset.insert(sequence.release(), true /* replace */, false).good()) { - uid.assign(tmp); + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); } } - if (uid.empty()) + { - // Generate an unique identifier for the Dimension Organization - uid = Orthanc::FromDcmtkBridge::GenerateUniqueIdentifier(Orthanc::ResourceType_Instance); - } - - dataset.remove(DCM_DimensionIndexSequence); + // Construct tag "Dimension Index Sequence" (0020,9222) + std::auto_ptr item(new DcmItem); + OrthancWSI::DicomToolbox::SetStringTag(*item, DCM_DimensionOrganizationUID, organization); + OrthancWSI::DicomToolbox::SetAttributeTag(*item, DCM_FunctionalGroupPointer, DCM_FrameContentSequence); + OrthancWSI::DicomToolbox::SetAttributeTag(*item, DCM_DimensionIndexPointer, DCM_DimensionIndexValues); - std::auto_ptr item(new DcmItem); - std::auto_ptr sequence(new DcmSequenceOfItems(DCM_DimensionOrganizationSequence)); + std::auto_ptr sequence(new DcmSequenceOfItems(DCM_DimensionIndexSequence)); - if (!item->putAndInsertString(DCM_DimensionOrganizationUID, uid.c_str()).good() || - !sequence->insert(item.release(), false, false).good() || - !dataset.insert(sequence.release(), true, false).good()) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + if (!sequence->insert(item.release(), false, false).good() || + !dataset.insert(sequence.release(), true /* replace */, false).good()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } } - item.reset(new DcmItem); - sequence.reset(new DcmSequenceOfItems(DCM_DimensionIndexSequence)); - std::auto_ptr a1(new DcmAttributeTag(DCM_FunctionalGroupPointer)); - std::auto_ptr a2(new DcmAttributeTag(DCM_DimensionIndexPointer)); + { + // Construct tag "Shared Functional Groups Sequence" (5200,9229) - if (!item->putAndInsertString(DCM_DimensionOrganizationUID, uid.c_str()).good() || - !a1->putTagVal(DCM_FrameContentSequence).good() || - !a2->putTagVal(DCM_DimensionIndexValues).good() || - !item->insert(a1.release()).good() || - !item->insert(a2.release()).good() || - !sequence->insert(item.release(), false, false).good() || - !dataset.insert(sequence.release(), true, false).good()) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } + // In the 2 lines below, remember to switch X/Y when going from physical to pixel coordinates! + float spacingX = volume.GetWidth() / static_cast(source.GetLevelHeight(0)); + float spacingY = volume.GetHeight() / static_cast(source.GetLevelWidth(0)); + + std::string spacing = (boost::lexical_cast(spacingX) + '\\' + + boost::lexical_cast(spacingY)); + + std::auto_ptr item(new DcmItem); - float spacingX = volume.GetWidth() / static_cast(source.GetLevelHeight(0)); // Remember to switch X/Y! - float spacingY = volume.GetHeight() / static_cast(source.GetLevelWidth(0)); // Remember to switch X/Y! - std::string spacing = (boost::lexical_cast(spacingX) + '\\' + - boost::lexical_cast(spacingY)); + std::auto_ptr item2(new DcmItem); + OrthancWSI::DicomToolbox::SetStringTag(*item2, DCM_SliceThickness, + boost::lexical_cast(volume.GetDepth())); + OrthancWSI::DicomToolbox::SetStringTag(*item2, DCM_PixelSpacing, spacing); - item.reset(new DcmItem); - sequence.reset(new DcmSequenceOfItems(DCM_SharedFunctionalGroupsSequence)); - std::auto_ptr item2(new DcmItem); - std::auto_ptr item3(new DcmItem); - std::auto_ptr sequence2(new DcmSequenceOfItems(DCM_PixelMeasuresSequence)); - std::auto_ptr sequence3(new DcmSequenceOfItems(DCM_OpticalPathIdentificationSequence)); + std::auto_ptr item3(new DcmItem); + OrthancWSI::DicomToolbox::SetStringTag(*item3, DCM_OpticalPathIdentifier, opticalPathId); - OrthancWSI::DicomToolbox::SetStringTag(*item2, DCM_SliceThickness, boost::lexical_cast(volume.GetDepth())); - OrthancWSI::DicomToolbox::SetStringTag(*item2, DCM_PixelSpacing, spacing); - OrthancWSI::DicomToolbox::SetStringTag(*item3, DCM_OpticalPathIdentifier, opticalPathId); + std::auto_ptr sequence(new DcmSequenceOfItems(DCM_SharedFunctionalGroupsSequence)); + std::auto_ptr sequence2(new DcmSequenceOfItems(DCM_PixelMeasuresSequence)); + std::auto_ptr sequence3(new DcmSequenceOfItems(DCM_OpticalPathIdentificationSequence)); - if (!sequence2->insert(item2.release(), false, false).good() || - !sequence3->insert(item3.release(), false, false).good() || - !item->insert(sequence2.release(), false, false).good() || - !item->insert(sequence3.release(), false, false).good() || - !sequence->insert(item.release(), false, false).good() || - !dataset.insert(sequence.release(), true, false).good()) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + if (!sequence2->insert(item2.release(), false, false).good() || + !sequence3->insert(item3.release(), false, false).good() || + !item->insert(sequence2.release(), false, false).good() || + !item->insert(sequence3.release(), false, false).good() || + !sequence->insert(item.release(), false, false).good() || + !dataset.insert(sequence.release(), true /* replace */, false).good()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } } } diff -r 5b127ab0080b -r 0cb3ac4f9159 Framework/DicomToolbox.cpp --- a/Framework/DicomToolbox.cpp Wed Dec 14 17:01:34 2016 +0100 +++ b/Framework/DicomToolbox.cpp Thu Dec 15 11:51:58 2016 +0100 @@ -28,6 +28,7 @@ #if ORTHANC_ENABLE_DCMTK == 1 # include # include +# include #endif namespace OrthancWSI @@ -70,6 +71,23 @@ } + void SetAttributeTag(DcmItem& dataset, + const DcmTagKey& key, + const DcmTagKey& value) + { + if (!dataset.tagExists(key)) + { + std::auto_ptr tag(new DcmAttributeTag(key)); + + if (!tag->putTagVal(value).good() || + !dataset.insert(tag.release()).good()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + } + } + + DcmItem* ExtractSingleSequenceItem(DcmItem& dataset, const DcmTagKey& key) { diff -r 5b127ab0080b -r 0cb3ac4f9159 Framework/DicomToolbox.h --- a/Framework/DicomToolbox.h Wed Dec 14 17:01:34 2016 +0100 +++ b/Framework/DicomToolbox.h Thu Dec 15 11:51:58 2016 +0100 @@ -47,6 +47,10 @@ const DcmTagKey& key, uint32_t value); + void SetAttributeTag(DcmItem& dataset, + const DcmTagKey& key, + const DcmTagKey& value); + DcmItem* ExtractSingleSequenceItem(DcmItem& dataset, const DcmTagKey& key);