Mercurial > hg > orthanc
comparison OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp @ 4203:4d42408da117
improving const-correctness in ParsedDicomFile
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 17 Sep 2020 15:01:31 +0200 |
parents | 7112a8af0b63 |
children | afad57ac30ef |
comparison
equal
deleted
inserted
replaced
4202:2007ab69ac16 | 4203:4d42408da117 |
---|---|
70 | 70 |
71 #include "ParsedDicomFile.h" | 71 #include "ParsedDicomFile.h" |
72 | 72 |
73 #include "FromDcmtkBridge.h" | 73 #include "FromDcmtkBridge.h" |
74 #include "Internals/DicomFrameIndex.h" | 74 #include "Internals/DicomFrameIndex.h" |
75 #include "Internals/DicomImageDecoder.h" | |
75 #include "ToDcmtkBridge.h" | 76 #include "ToDcmtkBridge.h" |
76 | 77 |
77 #include "../Images/PamReader.h" | 78 #include "../Images/PamReader.h" |
78 #include "../Logging.h" | 79 #include "../Logging.h" |
79 #include "../OrthancException.h" | 80 #include "../OrthancException.h" |
440 } | 441 } |
441 | 442 |
442 | 443 |
443 #if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1 | 444 #if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1 |
444 void ParsedDicomFile::SendPathValue(RestApiOutput& output, | 445 void ParsedDicomFile::SendPathValue(RestApiOutput& output, |
445 const UriComponents& uri) | 446 const UriComponents& uri) const |
446 { | 447 { |
447 DcmItem* dicom = GetDcmtkObject().getDataset(); | 448 DcmItem* dicom = GetDcmtkObjectConst().getDataset(); |
448 E_TransferSyntax transferSyntax = GetDcmtkObject().getDataset()->getCurrentXfer(); | 449 E_TransferSyntax transferSyntax = GetDcmtkObjectConst().getDataset()->getCurrentXfer(); |
449 | 450 |
450 // Special case: Accessing the pixel data | 451 // Special case: Accessing the pixel data |
451 if (uri.size() == 1 || | 452 if (uri.size() == 1 || |
452 uri.size() == 2) | 453 uri.size() == 2) |
453 { | 454 { |
851 } | 852 } |
852 } | 853 } |
853 | 854 |
854 | 855 |
855 #if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1 | 856 #if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1 |
856 void ParsedDicomFile::Answer(RestApiOutput& output) | 857 void ParsedDicomFile::Answer(RestApiOutput& output) const |
857 { | 858 { |
858 std::string serialized; | 859 std::string serialized; |
859 if (FromDcmtkBridge::SaveToMemoryBuffer(serialized, *GetDcmtkObject().getDataset())) | 860 if (FromDcmtkBridge::SaveToMemoryBuffer(serialized, *GetDcmtkObjectConst().getDataset())) |
860 { | 861 { |
861 output.AnswerBuffer(serialized, MimeType_Dicom); | 862 output.AnswerBuffer(serialized, MimeType_Dicom); |
862 } | 863 } |
863 } | 864 } |
864 #endif | 865 #endif |
865 | 866 |
866 | 867 |
867 bool ParsedDicomFile::GetTagValue(std::string& value, | 868 bool ParsedDicomFile::GetTagValue(std::string& value, |
868 const DicomTag& tag) | 869 const DicomTag& tag) const |
869 { | 870 { |
870 DcmTagKey k(tag.GetGroup(), tag.GetElement()); | 871 DcmTagKey k(tag.GetGroup(), tag.GetElement()); |
871 DcmDataset& dataset = *GetDcmtkObject().getDataset(); | 872 DcmDataset& dataset = *GetDcmtkObjectConst().getDataset(); |
872 | 873 |
873 if (tag.IsPrivate() || | 874 if (tag.IsPrivate() || |
874 FromDcmtkBridge::IsUnknownTag(tag) || | 875 FromDcmtkBridge::IsUnknownTag(tag) || |
875 tag == DICOM_TAG_PIXEL_DATA || | 876 tag == DICOM_TAG_PIXEL_DATA || |
876 tag == DICOM_TAG_ENCAPSULATED_DOCUMENT) | 877 tag == DICOM_TAG_ENCAPSULATED_DOCUMENT) |
928 return true; | 929 return true; |
929 } | 930 } |
930 } | 931 } |
931 | 932 |
932 | 933 |
933 DicomInstanceHasher ParsedDicomFile::GetHasher() | 934 DicomInstanceHasher ParsedDicomFile::GetHasher() const |
934 { | 935 { |
935 std::string patientId, studyUid, seriesUid, instanceUid; | 936 std::string patientId, studyUid, seriesUid, instanceUid; |
936 | 937 |
937 if (!GetTagValue(patientId, DICOM_TAG_PATIENT_ID)) | 938 if (!GetTagValue(patientId, DICOM_TAG_PATIENT_ID)) |
938 { | 939 { |
1105 | 1106 |
1106 ParsedDicomFile::ParsedDicomFile(const ParsedDicomFile& other, | 1107 ParsedDicomFile::ParsedDicomFile(const ParsedDicomFile& other, |
1107 bool keepSopInstanceUid) : | 1108 bool keepSopInstanceUid) : |
1108 pimpl_(new PImpl) | 1109 pimpl_(new PImpl) |
1109 { | 1110 { |
1110 pimpl_->file_.reset(dynamic_cast<DcmFileFormat*>(other.GetDcmtkObject().clone())); | 1111 pimpl_->file_.reset(dynamic_cast<DcmFileFormat*>(other.GetDcmtkObjectConst().clone())); |
1111 | 1112 |
1112 if (!keepSopInstanceUid) | 1113 if (!keepSopInstanceUid) |
1113 { | 1114 { |
1114 // Create a new instance-level identifier | 1115 // Create a new instance-level identifier |
1115 ReplacePlainString(DICOM_TAG_SOP_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Instance)); | 1116 ReplacePlainString(DICOM_TAG_SOP_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Instance)); |
1133 { | 1134 { |
1134 pimpl_->file_.reset(dicom); // No cloning | 1135 pimpl_->file_.reset(dicom); // No cloning |
1135 } | 1136 } |
1136 | 1137 |
1137 | 1138 |
1138 DcmFileFormat& ParsedDicomFile::GetDcmtkObject() const | 1139 DcmFileFormat& ParsedDicomFile::GetDcmtkObjectConst() const |
1139 { | 1140 { |
1140 if (pimpl_->file_.get() == NULL) | 1141 if (pimpl_->file_.get() == NULL) |
1141 { | 1142 { |
1142 throw OrthancException(ErrorCode_BadSequenceOfCalls, | 1143 throw OrthancException(ErrorCode_BadSequenceOfCalls, |
1143 "ReleaseDcmtkObject() was called"); | 1144 "ReleaseDcmtkObject() was called"); |
1162 return pimpl_->file_.release(); | 1163 return pimpl_->file_.release(); |
1163 } | 1164 } |
1164 } | 1165 } |
1165 | 1166 |
1166 | 1167 |
1167 ParsedDicomFile* ParsedDicomFile::Clone(bool keepSopInstanceUid) | 1168 ParsedDicomFile* ParsedDicomFile::Clone(bool keepSopInstanceUid) const |
1168 { | 1169 { |
1169 return new ParsedDicomFile(*this, keepSopInstanceUid); | 1170 return new ParsedDicomFile(*this, keepSopInstanceUid); |
1170 } | 1171 } |
1171 | 1172 |
1172 | 1173 |
1401 | 1402 |
1402 | 1403 |
1403 Encoding ParsedDicomFile::DetectEncoding(bool& hasCodeExtensions) const | 1404 Encoding ParsedDicomFile::DetectEncoding(bool& hasCodeExtensions) const |
1404 { | 1405 { |
1405 return FromDcmtkBridge::DetectEncoding(hasCodeExtensions, | 1406 return FromDcmtkBridge::DetectEncoding(hasCodeExtensions, |
1406 *GetDcmtkObject().getDataset(), | 1407 *GetDcmtkObjectConst().getDataset(), |
1407 GetDefaultDicomEncoding()); | 1408 GetDefaultDicomEncoding()); |
1408 } | 1409 } |
1409 | 1410 |
1410 | 1411 |
1411 void ParsedDicomFile::SetEncoding(Encoding encoding) | 1412 void ParsedDicomFile::SetEncoding(Encoding encoding) |
1422 } | 1423 } |
1423 | 1424 |
1424 void ParsedDicomFile::DatasetToJson(Json::Value& target, | 1425 void ParsedDicomFile::DatasetToJson(Json::Value& target, |
1425 DicomToJsonFormat format, | 1426 DicomToJsonFormat format, |
1426 DicomToJsonFlags flags, | 1427 DicomToJsonFlags flags, |
1427 unsigned int maxStringLength) | 1428 unsigned int maxStringLength) const |
1428 { | 1429 { |
1429 std::set<DicomTag> ignoreTagLength; | 1430 std::set<DicomTag> ignoreTagLength; |
1430 FromDcmtkBridge::ExtractDicomAsJson(target, *GetDcmtkObject().getDataset(), | 1431 FromDcmtkBridge::ExtractDicomAsJson(target, *GetDcmtkObjectConst().getDataset(), |
1431 format, flags, maxStringLength, ignoreTagLength); | 1432 format, flags, maxStringLength, ignoreTagLength); |
1432 } | 1433 } |
1433 | 1434 |
1434 | 1435 |
1435 void ParsedDicomFile::DatasetToJson(Json::Value& target, | 1436 void ParsedDicomFile::DatasetToJson(Json::Value& target, |
1436 DicomToJsonFormat format, | 1437 DicomToJsonFormat format, |
1437 DicomToJsonFlags flags, | 1438 DicomToJsonFlags flags, |
1438 unsigned int maxStringLength, | 1439 unsigned int maxStringLength, |
1439 const std::set<DicomTag>& ignoreTagLength) | 1440 const std::set<DicomTag>& ignoreTagLength) const |
1440 { | 1441 { |
1441 FromDcmtkBridge::ExtractDicomAsJson(target, *GetDcmtkObject().getDataset(), | 1442 FromDcmtkBridge::ExtractDicomAsJson(target, *GetDcmtkObjectConst().getDataset(), |
1442 format, flags, maxStringLength, ignoreTagLength); | 1443 format, flags, maxStringLength, ignoreTagLength); |
1443 } | 1444 } |
1444 | 1445 |
1445 | 1446 |
1446 void ParsedDicomFile::HeaderToJson(Json::Value& target, | 1447 void ParsedDicomFile::HeaderToJson(Json::Value& target, |
1447 DicomToJsonFormat format) | 1448 DicomToJsonFormat format) const |
1448 { | 1449 { |
1449 FromDcmtkBridge::ExtractHeaderAsJson(target, *GetDcmtkObject().getMetaInfo(), format, DicomToJsonFlags_None, 0); | 1450 FromDcmtkBridge::ExtractHeaderAsJson(target, *GetDcmtkObjectConst().getMetaInfo(), format, DicomToJsonFlags_None, 0); |
1450 } | 1451 } |
1451 | 1452 |
1452 | 1453 |
1453 bool ParsedDicomFile::HasTag(const DicomTag& tag) const | 1454 bool ParsedDicomFile::HasTag(const DicomTag& tag) const |
1454 { | 1455 { |
1455 DcmTag key(tag.GetGroup(), tag.GetElement()); | 1456 DcmTag key(tag.GetGroup(), tag.GetElement()); |
1456 return GetDcmtkObject().getDataset()->tagExists(key); | 1457 return GetDcmtkObjectConst().getDataset()->tagExists(key); |
1457 } | 1458 } |
1458 | 1459 |
1459 | 1460 |
1460 void ParsedDicomFile::EmbedPdf(const std::string& pdf) | 1461 void ParsedDicomFile::EmbedPdf(const std::string& pdf) |
1461 { | 1462 { |
1503 throw OrthancException(ErrorCode_NotEnoughMemory); | 1504 throw OrthancException(ErrorCode_NotEnoughMemory); |
1504 } | 1505 } |
1505 } | 1506 } |
1506 | 1507 |
1507 | 1508 |
1508 bool ParsedDicomFile::ExtractPdf(std::string& pdf) | 1509 bool ParsedDicomFile::ExtractPdf(std::string& pdf) const |
1509 { | 1510 { |
1510 std::string sop, mime; | 1511 std::string sop, mime; |
1511 | 1512 |
1512 if (!GetTagValue(sop, DICOM_TAG_SOP_CLASS_UID) || | 1513 if (!GetTagValue(sop, DICOM_TAG_SOP_CLASS_UID) || |
1513 !GetTagValue(mime, FromDcmtkBridge::Convert(DCM_MIMETypeOfEncapsulatedDocument)) || | 1514 !GetTagValue(mime, FromDcmtkBridge::Convert(DCM_MIMETypeOfEncapsulatedDocument)) || |
1580 } | 1581 } |
1581 | 1582 |
1582 | 1583 |
1583 void ParsedDicomFile::GetRawFrame(std::string& target, | 1584 void ParsedDicomFile::GetRawFrame(std::string& target, |
1584 MimeType& mime, | 1585 MimeType& mime, |
1585 unsigned int frameId) | 1586 unsigned int frameId) const |
1586 { | 1587 { |
1587 if (pimpl_->frameIndex_.get() == NULL) | 1588 if (pimpl_->frameIndex_.get() == NULL) |
1588 { | 1589 { |
1589 assert(pimpl_->file_ != NULL && | 1590 assert(pimpl_->file_ != NULL && |
1590 GetDcmtkObject().getDataset() != NULL); | 1591 GetDcmtkObjectConst().getDataset() != NULL); |
1591 pimpl_->frameIndex_.reset(new DicomFrameIndex(*GetDcmtkObject().getDataset())); | 1592 pimpl_->frameIndex_.reset(new DicomFrameIndex(*GetDcmtkObjectConst().getDataset())); |
1592 } | 1593 } |
1593 | 1594 |
1594 pimpl_->frameIndex_->GetRawFrame(target, frameId); | 1595 pimpl_->frameIndex_->GetRawFrame(target, frameId); |
1595 | 1596 |
1596 E_TransferSyntax transferSyntax = GetDcmtkObject().getDataset()->getCurrentXfer(); | 1597 E_TransferSyntax transferSyntax = GetDcmtkObjectConst().getDataset()->getCurrentXfer(); |
1597 switch (transferSyntax) | 1598 switch (transferSyntax) |
1598 { | 1599 { |
1599 case EXS_JPEGProcess1: | 1600 case EXS_JPEGProcess1: |
1600 mime = MimeType_Jpeg; | 1601 mime = MimeType_Jpeg; |
1601 break; | 1602 break; |
1619 | 1620 |
1620 | 1621 |
1621 unsigned int ParsedDicomFile::GetFramesCount() const | 1622 unsigned int ParsedDicomFile::GetFramesCount() const |
1622 { | 1623 { |
1623 assert(pimpl_->file_ != NULL && | 1624 assert(pimpl_->file_ != NULL && |
1624 GetDcmtkObject().getDataset() != NULL); | 1625 GetDcmtkObjectConst().getDataset() != NULL); |
1625 return DicomFrameIndex::GetFramesCount(*GetDcmtkObject().getDataset()); | 1626 return DicomFrameIndex::GetFramesCount(*GetDcmtkObjectConst().getDataset()); |
1626 } | 1627 } |
1627 | 1628 |
1628 | 1629 |
1629 void ParsedDicomFile::ChangeEncoding(Encoding target) | 1630 void ParsedDicomFile::ChangeEncoding(Encoding target) |
1630 { | 1631 { |
1641 | 1642 |
1642 void ParsedDicomFile::ExtractDicomSummary(DicomMap& target, | 1643 void ParsedDicomFile::ExtractDicomSummary(DicomMap& target, |
1643 unsigned int maxTagLength) const | 1644 unsigned int maxTagLength) const |
1644 { | 1645 { |
1645 std::set<DicomTag> ignoreTagLength; | 1646 std::set<DicomTag> ignoreTagLength; |
1646 FromDcmtkBridge::ExtractDicomSummary(target, *GetDcmtkObject().getDataset(), | 1647 FromDcmtkBridge::ExtractDicomSummary(target, *GetDcmtkObjectConst().getDataset(), |
1647 maxTagLength, ignoreTagLength); | 1648 maxTagLength, ignoreTagLength); |
1648 } | 1649 } |
1649 | 1650 |
1650 | 1651 |
1651 void ParsedDicomFile::ExtractDicomSummary(DicomMap& target, | 1652 void ParsedDicomFile::ExtractDicomSummary(DicomMap& target, |
1652 unsigned int maxTagLength, | 1653 unsigned int maxTagLength, |
1653 const std::set<DicomTag>& ignoreTagLength) const | 1654 const std::set<DicomTag>& ignoreTagLength) const |
1654 { | 1655 { |
1655 FromDcmtkBridge::ExtractDicomSummary(target, *GetDcmtkObject().getDataset(), | 1656 FromDcmtkBridge::ExtractDicomSummary(target, *GetDcmtkObjectConst().getDataset(), |
1656 maxTagLength, ignoreTagLength); | 1657 maxTagLength, ignoreTagLength); |
1657 } | 1658 } |
1658 | 1659 |
1659 | 1660 |
1660 bool ParsedDicomFile::LookupTransferSyntax(std::string& result) | 1661 bool ParsedDicomFile::LookupTransferSyntax(std::string& result) const |
1661 { | 1662 { |
1662 #if 0 | 1663 #if 0 |
1663 // This was the implementation in Orthanc <= 1.6.1 | 1664 // This was the implementation in Orthanc <= 1.6.1 |
1664 | 1665 |
1665 // TODO - Shouldn't "dataset.getCurrentXfer()" be used instead of | 1666 // TODO - Shouldn't "dataset.getCurrentXfer()" be used instead of |
1666 // using the meta header? | 1667 // using the meta header? |
1667 const char* value = NULL; | 1668 const char* value = NULL; |
1668 | 1669 |
1669 if (GetDcmtkObject().getMetaInfo() != NULL && | 1670 if (GetDcmtkObjectConst().getMetaInfo() != NULL && |
1670 GetDcmtkObject().getMetaInfo()->findAndGetString(DCM_TransferSyntaxUID, value).good() && | 1671 GetDcmtkObjectConst().getMetaInfo()->findAndGetString(DCM_TransferSyntaxUID, value).good() && |
1671 value != NULL) | 1672 value != NULL) |
1672 { | 1673 { |
1673 result.assign(value); | 1674 result.assign(value); |
1674 return true; | 1675 return true; |
1675 } | 1676 } |
1677 { | 1678 { |
1678 return false; | 1679 return false; |
1679 } | 1680 } |
1680 #else | 1681 #else |
1681 DicomTransferSyntax s; | 1682 DicomTransferSyntax s; |
1682 if (FromDcmtkBridge::LookupOrthancTransferSyntax(s, GetDcmtkObject())) | 1683 if (FromDcmtkBridge::LookupOrthancTransferSyntax(s, GetDcmtkObjectConst())) |
1683 { | 1684 { |
1684 result.assign(GetTransferSyntaxUid(s)); | 1685 result.assign(GetTransferSyntaxUid(s)); |
1685 return true; | 1686 return true; |
1686 } | 1687 } |
1687 else | 1688 else |
1695 bool ParsedDicomFile::LookupPhotometricInterpretation(PhotometricInterpretation& result) const | 1696 bool ParsedDicomFile::LookupPhotometricInterpretation(PhotometricInterpretation& result) const |
1696 { | 1697 { |
1697 DcmTagKey k(DICOM_TAG_PHOTOMETRIC_INTERPRETATION.GetGroup(), | 1698 DcmTagKey k(DICOM_TAG_PHOTOMETRIC_INTERPRETATION.GetGroup(), |
1698 DICOM_TAG_PHOTOMETRIC_INTERPRETATION.GetElement()); | 1699 DICOM_TAG_PHOTOMETRIC_INTERPRETATION.GetElement()); |
1699 | 1700 |
1700 DcmDataset& dataset = *GetDcmtkObject().getDataset(); | 1701 DcmDataset& dataset = *GetDcmtkObjectConst().getDataset(); |
1701 | 1702 |
1702 const char *c = NULL; | 1703 const char *c = NULL; |
1703 if (dataset.findAndGetString(k, c).good() && | 1704 if (dataset.findAndGetString(k, c).good() && |
1704 c != NULL) | 1705 c != NULL) |
1705 { | 1706 { |
1711 return false; | 1712 return false; |
1712 } | 1713 } |
1713 } | 1714 } |
1714 | 1715 |
1715 | 1716 |
1716 void ParsedDicomFile::Apply(ITagVisitor& visitor) | 1717 void ParsedDicomFile::Apply(ITagVisitor& visitor) const |
1717 { | 1718 { |
1718 FromDcmtkBridge::Apply(*GetDcmtkObject().getDataset(), visitor, GetDefaultDicomEncoding()); | 1719 FromDcmtkBridge::Apply(*GetDcmtkObjectConst().getDataset(), visitor, GetDefaultDicomEncoding()); |
1720 } | |
1721 | |
1722 | |
1723 ImageAccessor* ParsedDicomFile::DecodeFrame(unsigned int frame) const | |
1724 { | |
1725 if (GetDcmtkObjectConst().getDataset() == NULL) | |
1726 { | |
1727 throw OrthancException(ErrorCode_InternalError); | |
1728 } | |
1729 else | |
1730 { | |
1731 return DicomImageDecoder::Decode(*GetDcmtkObjectConst().getDataset(), frame); | |
1732 } | |
1719 } | 1733 } |
1720 } | 1734 } |