comparison UnitTestsSources/FromDcmtkTests.cpp @ 3221:4be505c2ac56

Separation of ideographic and phonetic characters in DICOMweb JSON and XML
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 14 Feb 2019 14:04:04 +0100
parents 4351f52f15d5
children 63681433b0fc
comparison
equal deleted inserted replaced
3220:1a0b4db799e8 3221:4be505c2ac56
34 #include "PrecompiledHeadersUnitTests.h" 34 #include "PrecompiledHeadersUnitTests.h"
35 #include "gtest/gtest.h" 35 #include "gtest/gtest.h"
36 36
37 #include "../Core/DicomNetworking/DicomFindAnswers.h" 37 #include "../Core/DicomNetworking/DicomFindAnswers.h"
38 #include "../Core/DicomParsing/DicomModification.h" 38 #include "../Core/DicomParsing/DicomModification.h"
39 #include "../Core/DicomParsing/DicomWebJsonVisitor.h"
39 #include "../Core/DicomParsing/FromDcmtkBridge.h" 40 #include "../Core/DicomParsing/FromDcmtkBridge.h"
40 #include "../Core/DicomParsing/Internals/DicomImageDecoder.h" 41 #include "../Core/DicomParsing/Internals/DicomImageDecoder.h"
41 #include "../Core/DicomParsing/ToDcmtkBridge.h" 42 #include "../Core/DicomParsing/ToDcmtkBridge.h"
42 #include "../Core/Endianness.h" 43 #include "../Core/Endianness.h"
43 #include "../Core/Images/Image.h" 44 #include "../Core/Images/Image.h"
51 #include "../Plugins/Engine/PluginsEnumerations.h" 52 #include "../Plugins/Engine/PluginsEnumerations.h"
52 #include "../Resources/EncodingTests.h" 53 #include "../Resources/EncodingTests.h"
53 54
54 #include <dcmtk/dcmdata/dcelem.h> 55 #include <dcmtk/dcmdata/dcelem.h>
55 #include <dcmtk/dcmdata/dcdeftag.h> 56 #include <dcmtk/dcmdata/dcdeftag.h>
57
58 #if ORTHANC_ENABLE_PUGIXML == 1
59 # include <pugixml.hpp>
60 #endif
56 61
57 using namespace Orthanc; 62 using namespace Orthanc;
58 63
59 TEST(DicomFormat, Tag) 64 TEST(DicomFormat, Tag)
60 { 65 {
1474 ASSERT_EQ(dest, iso2022_str_escapeSequence_ref); 1479 ASSERT_EQ(dest, iso2022_str_escapeSequence_ref);
1475 1480
1476 Toolbox::RemoveIso2022EscapeSequences(dest, iso2022_str_real_ir13); 1481 Toolbox::RemoveIso2022EscapeSequences(dest, iso2022_str_real_ir13);
1477 ASSERT_EQ(dest, iso2022_str_real_ir13_ref); 1482 ASSERT_EQ(dest, iso2022_str_real_ir13_ref);
1478 } 1483 }
1484
1485
1486
1487 static std::string DecodeFromSpecification(const std::string& s)
1488 {
1489 std::vector<std::string> tokens;
1490 Toolbox::TokenizeString(tokens, s, ' ');
1491
1492 std::string result;
1493 result.resize(tokens.size());
1494
1495 for (size_t i = 0; i < tokens.size(); i++)
1496 {
1497 std::vector<std::string> components;
1498 Toolbox::TokenizeString(components, tokens[i], '/');
1499
1500 if (components.size() != 2)
1501 {
1502 throw;
1503 }
1504
1505 int a = boost::lexical_cast<int>(components[0]);
1506 int b = boost::lexical_cast<int>(components[1]);
1507 if (a < 0 || a > 15 ||
1508 b < 0 || b > 15)
1509 {
1510 throw;
1511 }
1512
1513 result[i] = static_cast<uint8_t>(a * 16 + b);
1514 }
1515
1516 return result;
1517 }
1518
1519
1520
1521 TEST(Toolbox, EncodingsKorean)
1522 {
1523 // http://dicom.nema.org/MEDICAL/dicom/2017c/output/chtml/part05/sect_I.2.html
1524
1525 std::string korean = DecodeFromSpecification(
1526 "04/08 06/15 06/14 06/07 05/14 04/07 06/09 06/12 06/04 06/15 06/14 06/07 03/13 "
1527 "01/11 02/04 02/09 04/03 15/11 15/03 05/14 01/11 02/04 02/09 04/03 13/01 12/14 "
1528 "13/04 13/07 03/13 01/11 02/04 02/09 04/03 12/08 10/11 05/14 01/11 02/04 02/09 "
1529 "04/03 11/01 14/06 11/05 11/15");
1530
1531 // This array can be re-generated using command-line:
1532 // echo -n "Hong^Gildong=..." | hexdump -v -e '14/1 "0x%02x, "' -e '"\n"'
1533 static const uint8_t utf8raw[] = {
1534 0x48, 0x6f, 0x6e, 0x67, 0x5e, 0x47, 0x69, 0x6c, 0x64, 0x6f, 0x6e, 0x67, 0x3d, 0xe6,
1535 0xb4, 0xaa, 0x5e, 0xe5, 0x90, 0x89, 0xe6, 0xb4, 0x9e, 0x3d, 0xed, 0x99, 0x8d, 0x5e,
1536 0xea, 0xb8, 0xb8, 0xeb, 0x8f, 0x99
1537 };
1538
1539 std::string utf8(reinterpret_cast<const char*>(utf8raw), sizeof(utf8raw));
1540
1541 ParsedDicomFile dicom(false);
1542 dicom.ReplacePlainString(DICOM_TAG_SPECIFIC_CHARACTER_SET, "\\ISO 2022 IR 149");
1543 ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->putAndInsertString
1544 (DCM_PatientName, korean.c_str(), korean.size(), true).good());
1545
1546 std::string value;
1547 ASSERT_TRUE(dicom.GetTagValue(value, DICOM_TAG_PATIENT_NAME));
1548 ASSERT_EQ(utf8, value);
1549
1550 DicomWebJsonVisitor visitor;
1551 dicom.Apply(visitor);
1552 ASSERT_EQ(utf8.substr(0, 12), visitor.GetResult()["00100010"]["Value"][0]["Alphabetic"].asString());
1553 ASSERT_EQ(utf8.substr(13, 10), visitor.GetResult()["00100010"]["Value"][0]["Ideographic"].asString());
1554 ASSERT_EQ(utf8.substr(24), visitor.GetResult()["00100010"]["Value"][0]["Phonetic"].asString());
1555
1556 #if ORTHANC_ENABLE_PUGIXML == 1
1557 // http://dicom.nema.org/medical/dicom/current/output/chtml/part18/sect_F.3.html#table_F.3.1-1
1558 std::string xml;
1559 visitor.FormatXml(xml);
1560
1561 pugi::xml_document doc;
1562 doc.load_string(xml.c_str());
1563
1564 pugi::xpath_node node = doc.select_single_node("//NativeDicomModel/DicomAttribute[@tag=\"00080005\"]/Value");
1565 ASSERT_STREQ("ISO_IR 192", node.node().text().as_string());
1566
1567 node = doc.select_single_node("//NativeDicomModel/DicomAttribute[@tag=\"00080005\"]");
1568 ASSERT_STREQ("CS", node.node().attribute("vr").value());
1569
1570 node = doc.select_single_node("//NativeDicomModel/DicomAttribute[@tag=\"00100010\"]");
1571 ASSERT_STREQ("PN", node.node().attribute("vr").value());
1572
1573 node = doc.select_single_node("//NativeDicomModel/DicomAttribute[@tag=\"00100010\"]/PersonName/Alphabetic/FamilyName");
1574 ASSERT_STREQ("Hong", node.node().text().as_string());
1575
1576 node = doc.select_single_node("//NativeDicomModel/DicomAttribute[@tag=\"00100010\"]/PersonName/Alphabetic/GivenName");
1577 ASSERT_STREQ("Gildong", node.node().text().as_string());
1578
1579 node = doc.select_single_node("//NativeDicomModel/DicomAttribute[@tag=\"00100010\"]/PersonName/Ideographic/FamilyName");
1580 ASSERT_EQ(utf8.substr(13, 3), node.node().text().as_string());
1581
1582 node = doc.select_single_node("//NativeDicomModel/DicomAttribute[@tag=\"00100010\"]/PersonName/Ideographic/GivenName");
1583 ASSERT_EQ(utf8.substr(17, 6), node.node().text().as_string());
1584
1585 node = doc.select_single_node("//NativeDicomModel/DicomAttribute[@tag=\"00100010\"]/PersonName/Phonetic/FamilyName");
1586 ASSERT_EQ(utf8.substr(24, 3), node.node().text().as_string());
1587
1588 node = doc.select_single_node("//NativeDicomModel/DicomAttribute[@tag=\"00100010\"]/PersonName/Phonetic/GivenName");
1589 ASSERT_EQ(utf8.substr(28), node.node().text().as_string());
1590 #endif
1591 }
1592