# HG changeset patch # User Sebastien Jodogne # Date 1549445823 -3600 # Node ID 9316f341e40f729270736309ec9f506ba51111df # Parent 7724ed267b5cc1f5b28828b0037c56a31630818d unit testing json for dicomweb diff -r 7724ed267b5c -r 9316f341e40f Core/DicomParsing/FromDcmtkBridge.cpp --- a/Core/DicomParsing/FromDcmtkBridge.cpp Wed Feb 06 07:28:58 2019 +0100 +++ b/Core/DicomParsing/FromDcmtkBridge.cpp Wed Feb 06 10:37:03 2019 +0100 @@ -90,8 +90,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -1289,7 +1291,7 @@ case EVR_OB: return ValueRepresentation_OtherByte; -#if DCMTK_VERSION_NUMBER >= 362 +#if DCMTK_VERSION_NUMBER >= 361 case EVR_OD: return ValueRepresentation_OtherDouble; #endif @@ -1326,7 +1328,7 @@ case EVR_TM: return ValueRepresentation_Time; -#if DCMTK_VERSION_NUMBER >= 362 +#if DCMTK_VERSION_NUMBER >= 361 case EVR_UC: return ValueRepresentation_UnlimitedCharacters; #endif @@ -1340,7 +1342,7 @@ case EVR_UN: return ValueRepresentation_Unknown; -#if DCMTK_VERSION_NUMBER >= 362 +#if DCMTK_VERSION_NUMBER >= 361 case EVR_UR: return ValueRepresentation_UniversalResource; #endif @@ -1359,7 +1361,14 @@ static bool IsBinaryTag(const DcmTag& key) { - return (key.isUnknownVR() || + return (key.isUnknownVR() || +#if DCMTK_VERSION_NUMBER >= 361 + key.getEVR() == EVR_OD || +#endif + +#if DCMTK_VERSION_NUMBER >= 362 + key.getEVR() == EVR_OL || +#endif key.getEVR() == EVR_OB || key.getEVR() == EVR_OF || key.getEVR() == EVR_OW || @@ -1386,6 +1395,14 @@ * Binary types, handled above **/ +#if DCMTK_VERSION_NUMBER >= 361 + case EVR_OD: +#endif + +#if DCMTK_VERSION_NUMBER >= 362 + case EVR_OL: +#endif + case EVR_OB: // other byte case EVR_OF: // other float case EVR_OW: // other word @@ -1444,6 +1461,12 @@ case EVR_PN: // person name return new DcmPersonName(key); + case EVR_UC: // unlimited characters + return new DcmUnlimitedCharacters(key); + + case EVR_UR: // URI/URL + return new DcmUniversalResourceIdentifierOrLocator(key); + /** * Numerical types @@ -1544,7 +1567,29 @@ if (tag.IsPrivate() || IsBinaryTag(key)) { - if (element.putUint8Array((const Uint8*) decoded->c_str(), decoded->size()).good()) + bool ok; + + switch (key.getEVR()) + { + case EVR_OW: + if (decoded->size() % sizeof(Uint16) != 0) + { + LOG(ERROR) << "A tag with OW VR must have an even number of bytes"; + ok = false; + } + else + { + ok = element.putUint16Array((const Uint16*) decoded->c_str(), decoded->size() / sizeof(Uint16)).good(); + } + + break; + + default: + ok = element.putUint8Array((const Uint8*) decoded->c_str(), decoded->size()).good(); + break; + } + + if (ok) { return; } @@ -1595,6 +1640,8 @@ case EVR_UT: // unlimited text case EVR_PN: // person name case EVR_UI: // unique identifier + case EVR_UC: // unlimited characters + case EVR_UR: // URI/URL { ok = element.putString(decoded->c_str()).good(); break; @@ -2199,16 +2246,25 @@ if (evr == EVR_OB || // other byte evr == EVR_OF || // other float +#if DCMTK_VERSION_NUMBER >= 361 + evr == EVR_OD || // other double +#endif #if DCMTK_VERSION_NUMBER >= 362 - evr == EVR_OD || // other double evr == EVR_OL || // other long #endif evr == EVR_OW || // other word evr == EVR_UN) // unknown value representation { + Uint16* data16 = NULL; Uint8* data = NULL; - if (element.getUint8Array(data) == EC_Normal) + if (evr == EVR_OW && + element.getUint16Array(data16) == EC_Normal) + { + visitor.VisitBinary(parentTags, parentIndexes, tag, vr, data16, element.getLength()); + } + else if (evr != EVR_OW && + element.getUint8Array(data) == EC_Normal) { visitor.VisitBinary(parentTags, parentIndexes, tag, vr, data, element.getLength()); } diff -r 7724ed267b5c -r 9316f341e40f UnitTestsSources/DicomMapTests.cpp --- a/UnitTestsSources/DicomMapTests.cpp Wed Feb 06 07:28:58 2019 +0100 +++ b/UnitTestsSources/DicomMapTests.cpp Wed Feb 06 10:37:03 2019 +0100 @@ -555,7 +555,6 @@ -#if 1 #include @@ -1036,11 +1035,36 @@ dicom.ReplacePlainString(DicomTag(0x0008, 0x1160), "45"); // IS dicom.ReplacePlainString(DicomTag(0x0008, 0x0070), "LO"); dicom.ReplacePlainString(DicomTag(0x0008, 0x0108), "LT"); + dicom.ReplacePlainString(DicomTag(0x0028, 0x2000), "OB"); + dicom.ReplacePlainString(DicomTag(0x7fe0, 0x0009), "OD"); + dicom.ReplacePlainString(DicomTag(0x0064, 0x0009), "OF"); +#if DCMTK_VERSION_NUMBER >= 362 + dicom.ReplacePlainString(DicomTag(0x0066, 0x0040), "OLOL"); +#endif + + ASSERT_THROW(dicom.ReplacePlainString(DicomTag(0x0028, 0x1201), "O"), OrthancException); + dicom.ReplacePlainString(DicomTag(0x0028, 0x1201), "OWOW"); + dicom.ReplacePlainString(DicomTag(0x0010, 0x0010), "PN"); + dicom.ReplacePlainString(DicomTag(0x0008, 0x0050), "SH"); + dicom.ReplacePlainString(DicomTag(0x0018, 0x6020), "-15"); // SL + dicom.ReplacePlainString(DicomTag(0x0018, 0x9219), "-16"); // SS + dicom.ReplacePlainString(DicomTag(0x0008, 0x0081), "ST"); + dicom.ReplacePlainString(DicomTag(0x0008, 0x0013), "TM"); + dicom.ReplacePlainString(DicomTag(0x0008, 0x0119), "UC"); + dicom.ReplacePlainString(DicomTag(0x0008, 0x0016), "UI"); + dicom.ReplacePlainString(DicomTag(0x0008, 0x1161), "128"); // UL + dicom.ReplacePlainString(DicomTag(0x4342, 0x1234), "UN"); // Inexistent tag + dicom.ReplacePlainString(DicomTag(0x0008, 0x0120), "UR"); + dicom.ReplacePlainString(DicomTag(0x0008, 0x0301), "17"); // US + dicom.ReplacePlainString(DicomTag(0x0040, 0x0031), "UT"); + + Orthanc::DicomJsonVisitor visitor; dicom.Apply(visitor); - std::cout << visitor.GetResult(); + std::string s; + ASSERT_EQ("AE", visitor.GetResult() ["00400241"]["vr"].asString()); ASSERT_EQ("AE", visitor.GetResult() ["00400241"]["Value"][0].asString()); ASSERT_EQ("AS", visitor.GetResult() ["00101010"]["vr"].asString()); @@ -1065,7 +1089,107 @@ ASSERT_EQ("LO", visitor.GetResult() ["00080070"]["Value"][0].asString()); ASSERT_EQ("LT", visitor.GetResult() ["00080108"]["vr"].asString()); ASSERT_EQ("LT", visitor.GetResult() ["00080108"]["Value"][0].asString()); + + ASSERT_EQ("OB", visitor.GetResult() ["00282000"]["vr"].asString()); + Toolbox::DecodeBase64(s, visitor.GetResult() ["00282000"]["InlineBinary"].asString()); + ASSERT_EQ("OB", s); + + ASSERT_EQ("OD", visitor.GetResult() ["7FE00009"]["vr"].asString()); + Toolbox::DecodeBase64(s, visitor.GetResult() ["7FE00009"]["InlineBinary"].asString()); + ASSERT_EQ("OD", s); + + ASSERT_EQ("OF", visitor.GetResult() ["00640009"]["vr"].asString()); + Toolbox::DecodeBase64(s, visitor.GetResult() ["00640009"]["InlineBinary"].asString()); + ASSERT_EQ("OF", s); + +#if DCMTK_VERSION_NUMBER >= 362 + ASSERT_EQ("OL", visitor.GetResult() ["00660040"]["vr"].asString()); + Toolbox::DecodeBase64(s, visitor.GetResult() ["00660040"]["InlineBinary"].asString()); + ASSERT_EQ("OLOL", s); +#endif + + ASSERT_EQ("OW", visitor.GetResult() ["00281201"]["vr"].asString()); + Toolbox::DecodeBase64(s, visitor.GetResult() ["00281201"]["InlineBinary"].asString()); + ASSERT_EQ("OWOW", s); + + ASSERT_EQ("PN", visitor.GetResult() ["00100010"]["vr"].asString()); + ASSERT_EQ("PN", visitor.GetResult() ["00100010"]["Value"][0]["Alphabetic"].asString()); + + ASSERT_EQ("SH", visitor.GetResult() ["00080050"]["vr"].asString()); + ASSERT_EQ("SH", visitor.GetResult() ["00080050"]["Value"][0].asString()); + + ASSERT_EQ("SL", visitor.GetResult() ["00186020"]["vr"].asString()); + ASSERT_FLOAT_EQ(-15, visitor.GetResult() ["00186020"]["Value"][0].asInt()); + + ASSERT_EQ("SS", visitor.GetResult() ["00189219"]["vr"].asString()); + ASSERT_FLOAT_EQ(-16, visitor.GetResult() ["00189219"]["Value"][0].asInt()); + + ASSERT_EQ("ST", visitor.GetResult() ["00080081"]["vr"].asString()); + ASSERT_EQ("ST", visitor.GetResult() ["00080081"]["Value"][0].asString()); + + ASSERT_EQ("TM", visitor.GetResult() ["00080013"]["vr"].asString()); + ASSERT_EQ("TM", visitor.GetResult() ["00080013"]["Value"][0].asString()); + + ASSERT_EQ("UC", visitor.GetResult() ["00080119"]["vr"].asString()); + ASSERT_EQ("UC", visitor.GetResult() ["00080119"]["Value"][0].asString()); + + ASSERT_EQ("UI", visitor.GetResult() ["00080016"]["vr"].asString()); + ASSERT_EQ("UI", visitor.GetResult() ["00080016"]["Value"][0].asString()); + + ASSERT_EQ("UL", visitor.GetResult() ["00081161"]["vr"].asString()); + ASSERT_EQ(128, visitor.GetResult() ["00081161"]["Value"][0].asUInt()); + + ASSERT_EQ("UN", visitor.GetResult() ["43421234"]["vr"].asString()); + Toolbox::DecodeBase64(s, visitor.GetResult() ["43421234"]["InlineBinary"].asString()); + ASSERT_EQ("UN", s); + + ASSERT_EQ("UR", visitor.GetResult() ["00080120"]["vr"].asString()); + ASSERT_EQ("UR", visitor.GetResult() ["00080120"]["Value"][0].asString()); + + ASSERT_EQ("US", visitor.GetResult() ["00080301"]["vr"].asString()); + ASSERT_EQ(17, visitor.GetResult() ["00080301"]["Value"][0].asUInt()); + + ASSERT_EQ("UT", visitor.GetResult() ["00400031"]["vr"].asString()); + ASSERT_EQ("UT", visitor.GetResult() ["00400031"]["Value"][0].asString()); } -#endif +TEST(DicomWebJson, Sequence) +{ + ParsedDicomFile dicom(false); + + { + std::auto_ptr sequence(new DcmSequenceOfItems(DCM_ReferencedSeriesSequence)); + + for (unsigned int i = 0; i < 3; i++) + { + std::auto_ptr item(new DcmItem); + std::string s = "item" + boost::lexical_cast(i); + item->putAndInsertString(DCM_ReferencedSOPInstanceUID, s.c_str(), OFFalse); + ASSERT_TRUE(sequence->insert(item.release(), false, false).good()); + } + + ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->insert(sequence.release(), false, false).good()); + } + + Orthanc::DicomJsonVisitor visitor; + dicom.Apply(visitor); + + ASSERT_EQ("SQ", visitor.GetResult() ["00081115"]["vr"].asString()); + ASSERT_EQ(3u, visitor.GetResult() ["00081115"]["Value"].size()); + + std::set items; + + for (Json::Value::ArrayIndex i = 0; i < 3; i++) + { + ASSERT_EQ(1u, visitor.GetResult() ["00081115"]["Value"][i].size()); + ASSERT_EQ(1u, visitor.GetResult() ["00081115"]["Value"][i]["00081155"]["Value"].size()); + ASSERT_EQ("UI", visitor.GetResult() ["00081115"]["Value"][i]["00081155"]["vr"].asString()); + items.insert(visitor.GetResult() ["00081115"]["Value"][i]["00081155"]["Value"][0].asString()); + } + + ASSERT_EQ(3u, items.size()); + ASSERT_TRUE(items.find("item0") != items.end()); + ASSERT_TRUE(items.find("item1") != items.end()); + ASSERT_TRUE(items.find("item2") != items.end()); +}