Mercurial > hg > orthanc
changeset 3522:00b0f4ce84e2
merge
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Mon, 23 Sep 2019 17:48:12 +0200 |
parents | 793c141be598 (current diff) 77bede920d22 (diff) |
children | d96379a965de |
files | |
diffstat | 9 files changed, 161 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- a/Core/DicomFormat/DicomArray.h Mon Sep 23 17:47:54 2019 +0200 +++ b/Core/DicomFormat/DicomArray.h Mon Sep 23 17:48:12 2019 +0200 @@ -62,6 +62,6 @@ return *elements_[i]; } - void Print(FILE* fp) const; + void Print(FILE* fp) const; // For debugging only }; }
--- a/Core/DicomFormat/DicomImageInformation.cpp Mon Sep 23 17:47:54 2019 +0200 +++ b/Core/DicomFormat/DicomImageInformation.cpp Mon Sep 23 17:48:12 2019 +0200 @@ -116,8 +116,9 @@ photometric_ = PhotometricInterpretation_Unknown; } - width_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_COLUMNS).GetContent()); - height_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_ROWS).GetContent()); + values.GetValue(DICOM_TAG_COLUMNS).ParseFirstUnsignedInteger(width_); // in some US images, we've seen tag values of "800\0"; that's why we parse the 'first' value + values.GetValue(DICOM_TAG_ROWS).ParseFirstUnsignedInteger(height_); + bitsAllocated_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_BITS_ALLOCATED).GetContent()); try
--- a/Core/DicomFormat/DicomMap.cpp Mon Sep 23 17:47:54 2019 +0200 +++ b/Core/DicomFormat/DicomMap.cpp Mon Sep 23 17:48:12 2019 +0200 @@ -41,6 +41,7 @@ #include "../Logging.h" #include "../OrthancException.h" #include "../Toolbox.h" +#include "DicomArray.h" namespace Orthanc @@ -876,9 +877,9 @@ } - bool DicomMap::CopyToString(std::string& result, - const DicomTag& tag, - bool allowBinary) const + bool DicomMap::LookupStringValue(std::string& result, + const DicomTag& tag, + bool allowBinary) const { const DicomValue* value = TestAndGetValue(tag); @@ -1275,4 +1276,27 @@ } } } + + + std::string DicomMap::GetStringValue(const DicomTag& tag, + const std::string& defaultValue, + bool allowBinary) const + { + std::string s; + if (LookupStringValue(s, tag, allowBinary)) + { + return s; + } + else + { + return defaultValue; + } + } + + + void DicomMap::Print(FILE* fp) const + { + DicomArray a(*this); + a.Print(fp); + } }
--- a/Core/DicomFormat/DicomMap.h Mon Sep 23 17:47:54 2019 +0200 +++ b/Core/DicomFormat/DicomMap.h Mon Sep 23 17:48:12 2019 +0200 @@ -198,9 +198,9 @@ void LogMissingTagsForStore() const; - bool CopyToString(std::string& result, - const DicomTag& tag, - bool allowBinary) const; + bool LookupStringValue(std::string& result, + const DicomTag& tag, + bool allowBinary) const; bool ParseInteger32(int32_t& result, const DicomTag& tag) const; @@ -233,5 +233,11 @@ void Unserialize(const Json::Value& source); void FromDicomWeb(const Json::Value& source); + + std::string GetStringValue(const DicomTag& tag, + const std::string& defaultValue, + bool allowBinary) const; + + void Print(FILE* fp) const; // For debugging only }; }
--- a/Core/DicomFormat/DicomValue.cpp Mon Sep 23 17:47:54 2019 +0200 +++ b/Core/DicomFormat/DicomValue.cpp Mon Sep 23 17:48:12 2019 +0200 @@ -94,6 +94,60 @@ } #endif + // same as ParseValue but in case the value actually contains a sequence, + // it will return the first value + // this has been introduced to support invalid "width/height" DICOM tags in some US + // images where the width is stored as "800\0" ! + template <typename T, + bool allowSigned> + static bool ParseFirstValue(T& result, + const DicomValue& source) + { + if (source.IsBinary() || + source.IsNull()) + { + return false; + } + + try + { + std::string value = Toolbox::StripSpaces(source.GetContent()); + if (value.empty()) + { + return false; + } + + if (!allowSigned && + value[0] == '-') + { + return false; + } + + if (value.find("\\") == std::string::npos) + { + result = boost::lexical_cast<T>(value); + return true; + } + else + { + std::vector<std::string> tokens; + Toolbox::TokenizeString(tokens, value, '\\'); + + if (tokens.size() >= 1) + { + result = boost::lexical_cast<T>(tokens[0]); + return true; + } + + return false; + } + } + catch (boost::bad_lexical_cast&) + { + return false; + } + } + template <typename T, bool allowSigned> @@ -177,6 +231,11 @@ return ParseValue<double, true>(result, *this); } + bool DicomValue::ParseFirstUnsignedInteger(unsigned int& result) const + { + return ParseFirstValue<unsigned int, true>(result, *this); + } + bool DicomValue::CopyToString(std::string& result, bool allowBinary) const {
--- a/Core/DicomFormat/DicomValue.h Mon Sep 23 17:47:54 2019 +0200 +++ b/Core/DicomFormat/DicomValue.h Mon Sep 23 17:48:12 2019 +0200 @@ -112,6 +112,8 @@ bool ParseDouble(double& result) const; + bool ParseFirstUnsignedInteger(unsigned int& result) const; + void Serialize(Json::Value& target) const; void Unserialize(const Json::Value& source);
--- a/Core/HttpClient.cpp Mon Sep 23 17:47:54 2019 +0200 +++ b/Core/HttpClient.cpp Mon Sep 23 17:48:12 2019 +0200 @@ -933,6 +933,8 @@ CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_WRITEDATA, &answer)); + const boost::posix_time::ptime start = boost::posix_time::microsec_clock::universal_time(); + if (boost::starts_with(url_, "https://")) { code = OrthancHttpClientPerformSSL(pimpl_->curl_, &status); @@ -942,7 +944,10 @@ code = GetHttpStatus(curl_easy_perform(pimpl_->curl_), pimpl_->curl_, &status); } - LOG(INFO) << "HTTP status code " << status << " after " + const boost::posix_time::ptime end = boost::posix_time::microsec_clock::universal_time(); + + LOG(INFO) << "HTTP status code " << status << " in " + << ((end - start).total_milliseconds()) << " ms after " << EnumerationToString(method_) << " request on: " << url_; if (isVerbose_)
--- a/UnitTestsSources/DicomMapTests.cpp Mon Sep 23 17:47:54 2019 +0200 +++ b/UnitTestsSources/DicomMapTests.cpp Mon Sep 23 17:48:12 2019 +0200 @@ -239,6 +239,7 @@ int64_t j; uint32_t k; uint64_t l; + unsigned int ui; std::string s; m.SetValue(DICOM_TAG_PATIENT_NAME, " ", false); // Empty value @@ -257,8 +258,8 @@ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k)); ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l)); - ASSERT_FALSE(m.CopyToString(s, DICOM_TAG_PATIENT_NAME, false)); - ASSERT_TRUE(m.CopyToString(s, DICOM_TAG_PATIENT_NAME, true)); + ASSERT_FALSE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, false)); + ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, true)); ASSERT_EQ("0", s); @@ -292,9 +293,9 @@ ASSERT_EQ(42u, k); ASSERT_EQ(42ull, l); - ASSERT_TRUE(m.CopyToString(s, DICOM_TAG_PATIENT_NAME, false)); + ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, false)); ASSERT_EQ("42", s); - ASSERT_TRUE(m.CopyToString(s, DICOM_TAG_PATIENT_NAME, true)); + ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, true)); ASSERT_EQ("42", s); @@ -375,6 +376,15 @@ ASSERT_FLOAT_EQ(-2147483649.0f, f); ASSERT_DOUBLE_EQ(-2147483649.0, d); ASSERT_EQ(-2147483649ll, j); + + + // "800\0" in US COLMUNS tag + m.SetValue(DICOM_TAG_COLUMNS, "800\0", false); + ASSERT_TRUE(m.GetValue(DICOM_TAG_COLUMNS).ParseFirstUnsignedInteger(ui)); + ASSERT_EQ(800, ui); + m.SetValue(DICOM_TAG_COLUMNS, "800", false); + ASSERT_TRUE(m.GetValue(DICOM_TAG_COLUMNS).ParseFirstUnsignedInteger(ui)); + ASSERT_EQ(800, ui); } @@ -597,12 +607,12 @@ ASSERT_EQ(3u, m.GetSize()); std::string s; - ASSERT_TRUE(m.CopyToString(s, DICOM_TAG_PATIENT_NAME, false)); + ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, false)); ASSERT_EQ("SB1^SB2^SB3^SB4^SB5", s); - ASSERT_TRUE(m.CopyToString(s, DICOM_TAG_IMAGE_POSITION_PATIENT, false)); + ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_IMAGE_POSITION_PATIENT, false)); ASSERT_TRUE(s.empty()); - ASSERT_TRUE(m.CopyToString(s, DICOM_TAG_IMAGE_ORIENTATION_PATIENT, false)); + ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_IMAGE_ORIENTATION_PATIENT, false)); std::vector<std::string> v; Orthanc::Toolbox::TokenizeString(v, s, '\\'); @@ -647,7 +657,7 @@ ASSERT_EQ(1u, m.GetSize()); std::string s; - ASSERT_TRUE(m.CopyToString(s, DICOM_TAG_IMAGE_ORIENTATION_PATIENT, false)); + ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_IMAGE_ORIENTATION_PATIENT, false)); std::vector<std::string> v; Orthanc::Toolbox::TokenizeString(v, s, '\\'); @@ -851,41 +861,41 @@ ASSERT_EQ(31u, m.GetSize()); std::string s; - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0002, 0x0002), false)); ASSERT_EQ("UI", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0040, 0x0241), false)); ASSERT_EQ("AE", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0010, 0x1010), false)); ASSERT_EQ("AS", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0020, 0x9165), false)); ASSERT_EQ("00100020", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0008, 0x0052), false)); ASSERT_EQ("CS", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0008, 0x0012), false)); ASSERT_EQ("DA", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0010, 0x1020), false)); ASSERT_EQ("42", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0008, 0x002a), false)); ASSERT_EQ("DT", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0010, 0x9431), false)); ASSERT_EQ("43", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0008, 0x1163), false)); ASSERT_EQ("44", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0008, 0x1160), false)); ASSERT_EQ("45", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0008, 0x0070), false)); ASSERT_EQ("LO", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0010, 0x4000), false)); ASSERT_EQ("LT", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0028, 0x2000), true)); ASSERT_EQ("OB", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x7fe0, 0x0009), true)); ASSERT_EQ("OD", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0064, 0x0009), true)); ASSERT_EQ("OF", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0028, 0x1201), true)); ASSERT_EQ("OWOW", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0010, 0x0010), false)); ASSERT_EQ("PN", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0008, 0x0050), false)); ASSERT_EQ("SH", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0018, 0x6020), false)); ASSERT_EQ("-15", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0018, 0x9219), false)); ASSERT_EQ("-16", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0008, 0x0081), false)); ASSERT_EQ("ST", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0008, 0x0013), false)); ASSERT_EQ("TM", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0008, 0x0119), false)); ASSERT_EQ("UC", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0008, 0x0016), false)); ASSERT_EQ("UI", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0008, 0x1161), false)); ASSERT_EQ("128", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x4342, 0x1234), true)); ASSERT_EQ("UN", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0008, 0x0120), false)); ASSERT_EQ("UR", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0008, 0x0301), false)); ASSERT_EQ("17", s); - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0040, 0x0031), false)); ASSERT_EQ("UT", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0002, 0x0002), false)); ASSERT_EQ("UI", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0040, 0x0241), false)); ASSERT_EQ("AE", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0010, 0x1010), false)); ASSERT_EQ("AS", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0020, 0x9165), false)); ASSERT_EQ("00100020", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x0052), false)); ASSERT_EQ("CS", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x0012), false)); ASSERT_EQ("DA", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0010, 0x1020), false)); ASSERT_EQ("42", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x002a), false)); ASSERT_EQ("DT", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0010, 0x9431), false)); ASSERT_EQ("43", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x1163), false)); ASSERT_EQ("44", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x1160), false)); ASSERT_EQ("45", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x0070), false)); ASSERT_EQ("LO", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0010, 0x4000), false)); ASSERT_EQ("LT", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0028, 0x2000), true)); ASSERT_EQ("OB", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x7fe0, 0x0009), true)); ASSERT_EQ("OD", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0064, 0x0009), true)); ASSERT_EQ("OF", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0028, 0x1201), true)); ASSERT_EQ("OWOW", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0010, 0x0010), false)); ASSERT_EQ("PN", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x0050), false)); ASSERT_EQ("SH", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0018, 0x6020), false)); ASSERT_EQ("-15", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0018, 0x9219), false)); ASSERT_EQ("-16", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x0081), false)); ASSERT_EQ("ST", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x0013), false)); ASSERT_EQ("TM", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x0119), false)); ASSERT_EQ("UC", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x0016), false)); ASSERT_EQ("UI", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x1161), false)); ASSERT_EQ("128", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x4342, 0x1234), true)); ASSERT_EQ("UN", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x0120), false)); ASSERT_EQ("UR", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0008, 0x0301), false)); ASSERT_EQ("17", s); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0040, 0x0031), false)); ASSERT_EQ("UT", s); #if DCMTK_VERSION_NUMBER == 361 - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0066, 0x0040), false)); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0066, 0x0040), false)); #else - ASSERT_TRUE(m.CopyToString(s, DicomTag(0x0066, 0x0040), true)); + ASSERT_TRUE(m.LookupStringValue(s, DicomTag(0x0066, 0x0040), true)); #endif ASSERT_EQ("46", s); }
--- a/UnitTestsSources/FromDcmtkTests.cpp Mon Sep 23 17:47:54 2019 +0200 +++ b/UnitTestsSources/FromDcmtkTests.cpp Mon Sep 23 17:48:12 2019 +0200 @@ -1615,10 +1615,10 @@ ASSERT_EQ(2u, m.GetSize()); std::string s; - ASSERT_TRUE(m.CopyToString(s, DICOM_TAG_SPECIFIC_CHARACTER_SET, false)); + ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_SPECIFIC_CHARACTER_SET, false)); ASSERT_EQ("ISO 2022 IR 149", s); - ASSERT_TRUE(m.CopyToString(s, DICOM_TAG_PATIENT_NAME, false)); + ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, false)); std::vector<std::string> v; Toolbox::TokenizeString(v, s, '='); ASSERT_EQ(3u, v.size()); @@ -1712,10 +1712,10 @@ ASSERT_EQ(2u, m.GetSize()); std::string s; - ASSERT_TRUE(m.CopyToString(s, DICOM_TAG_SPECIFIC_CHARACTER_SET, false)); + ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_SPECIFIC_CHARACTER_SET, false)); ASSERT_EQ("ISO 2022 IR 87", s); - ASSERT_TRUE(m.CopyToString(s, DICOM_TAG_PATIENT_NAME, false)); + ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, false)); std::vector<std::string> v; Toolbox::TokenizeString(v, s, '='); ASSERT_EQ(3u, v.size());