Mercurial > hg > orthanc
comparison Core/DicomParsing/FromDcmtkBridge.cpp @ 3691:4922bdd046dd
Fix issue #140 (Modifying private tags with REST API changes VR from LO to UN) - DANGEROUS COMMIT
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 25 Feb 2020 21:44:09 +0100 |
parents | 46cb00e4adbb |
children | fd302ec6a502 |
comparison
equal
deleted
inserted
replaced
3690:a9ce35d67c3c | 3691:4922bdd046dd |
---|---|
113 #endif | 113 #endif |
114 | 114 |
115 | 115 |
116 namespace Orthanc | 116 namespace Orthanc |
117 { | 117 { |
118 static bool IsBinaryTag(const DcmTag& key) | |
119 { | |
120 return (key.isUnknownVR() || | |
121 key.getEVR() == EVR_OB || | |
122 key.getEVR() == EVR_OW || | |
123 key.getEVR() == EVR_UN || | |
124 key.getEVR() == EVR_ox); | |
125 } | |
126 | |
127 | |
118 #if DCMTK_USE_EMBEDDED_DICTIONARIES == 1 | 128 #if DCMTK_USE_EMBEDDED_DICTIONARIES == 1 |
119 static void LoadEmbeddedDictionary(DcmDataDictionary& dictionary, | 129 static void LoadEmbeddedDictionary(DcmDataDictionary& dictionary, |
120 EmbeddedResources::FileResourceId resource) | 130 EmbeddedResources::FileResourceId resource) |
121 { | 131 { |
122 std::string content; | 132 std::string content; |
936 } | 946 } |
937 | 947 |
938 if (!(flags & DicomToJsonFlags_IncludeUnknownTags)) | 948 if (!(flags & DicomToJsonFlags_IncludeUnknownTags)) |
939 { | 949 { |
940 DictionaryLocker locker; | 950 DictionaryLocker locker; |
941 if (locker->findEntry(element->getTag(), NULL) == NULL) | 951 if (locker->findEntry(element->getTag(), element->getTag().getPrivateCreator()) == NULL) |
942 { | 952 { |
943 continue; | 953 continue; |
944 } | 954 } |
945 } | 955 } |
946 | 956 |
947 DcmEVR evr = element->getTag().getEVR(); | 957 if (IsBinaryTag(element->getTag())) |
948 if (evr == EVR_OB || | |
949 evr == EVR_OF || | |
950 evr == EVR_OW || | |
951 evr == EVR_UN || | |
952 evr == EVR_ox) | |
953 { | 958 { |
954 // This is a binary tag | 959 // This is a binary tag |
955 if ((tag == DICOM_TAG_PIXEL_DATA && !(flags & DicomToJsonFlags_IncludePixelData)) || | 960 if ((tag == DICOM_TAG_PIXEL_DATA && !(flags & DicomToJsonFlags_IncludePixelData)) || |
956 (tag != DICOM_TAG_PIXEL_DATA && !(flags & DicomToJsonFlags_IncludeBinary))) | 961 (tag != DICOM_TAG_PIXEL_DATA && !(flags & DicomToJsonFlags_IncludeBinary))) |
957 { | 962 { |
1369 return ValueRepresentation_NotSupported; | 1374 return ValueRepresentation_NotSupported; |
1370 } | 1375 } |
1371 } | 1376 } |
1372 | 1377 |
1373 | 1378 |
1374 static bool IsBinaryTag(const DcmTag& key) | 1379 DcmElement* FromDcmtkBridge::CreateElementForTag(const DicomTag& tag, |
1375 { | 1380 const std::string& privateCreator) |
1376 return (key.isUnknownVR() || | 1381 { |
1377 #if DCMTK_VERSION_NUMBER >= 361 | 1382 if (tag.IsPrivate() && |
1378 key.getEVR() == EVR_OD || | 1383 privateCreator.empty()) |
1379 #endif | 1384 { |
1380 | 1385 // This solves issue 140 (Modifying private tags with REST API |
1381 #if DCMTK_VERSION_NUMBER >= 362 | 1386 // changes VR from LO to UN) |
1382 key.getEVR() == EVR_OL || | 1387 // https://bitbucket.org/sjodogne/orthanc/issues/140 |
1383 #endif | 1388 LOG(WARNING) << "Private creator should not be empty while creating a private tag: " << tag.Format(); |
1384 key.getEVR() == EVR_OB || | 1389 } |
1385 key.getEVR() == EVR_OF || | |
1386 key.getEVR() == EVR_OW || | |
1387 key.getEVR() == EVR_UN || | |
1388 key.getEVR() == EVR_ox); | |
1389 } | |
1390 | |
1391 | |
1392 DcmElement* FromDcmtkBridge::CreateElementForTag(const DicomTag& tag) | |
1393 { | |
1394 DcmTag key(tag.GetGroup(), tag.GetElement()); | |
1395 | |
1396 if (tag.IsPrivate() || | |
1397 IsBinaryTag(key)) | |
1398 { | |
1399 return new DcmOtherByteOtherWord(key); | |
1400 } | |
1401 | |
1402 switch (key.getEVR()) | |
1403 { | |
1404 // http://support.dcmtk.org/docs/dcvr_8h-source.html | |
1405 | |
1406 /** | |
1407 * Binary types, handled above | |
1408 **/ | |
1409 | 1390 |
1410 #if DCMTK_VERSION_NUMBER >= 361 | 1391 #if DCMTK_VERSION_NUMBER >= 361 |
1411 case EVR_OD: | 1392 DcmTag key(tag.GetGroup(), tag.GetElement()); |
1412 #endif | 1393 if (tag.IsPrivate()) |
1413 | 1394 { |
1414 #if DCMTK_VERSION_NUMBER >= 362 | 1395 return DcmItem::newDicomElement(key, privateCreator.c_str()); |
1415 case EVR_OL: | 1396 } |
1416 #endif | 1397 else |
1417 | 1398 { |
1418 case EVR_OB: // other byte | 1399 return DcmItem::newDicomElement(key, NULL); |
1419 case EVR_OF: // other float | 1400 } |
1420 case EVR_OW: // other word | 1401 |
1421 case EVR_UN: // unknown value representation | 1402 #else |
1422 case EVR_ox: // OB or OW depending on context | 1403 DcmTag key(tag.GetGroup(), tag.GetElement()); |
1423 throw OrthancException(ErrorCode_InternalError); | 1404 if (tag.IsPrivate()) |
1424 | 1405 { |
1425 | 1406 // https://forum.dcmtk.org/viewtopic.php?t=4527 |
1426 /** | 1407 LOG(WARNING) << "You are using DCMTK <= 3.6.0: All the private tags " |
1427 * String types. | 1408 "are considered as having a binary value representation"; |
1428 * http://support.dcmtk.org/docs/classDcmByteString.html | 1409 key.setPrivateCreator(privateCreator.c_str()); |
1429 **/ | 1410 return new DcmOtherByteOtherWord(key); |
1430 | 1411 } |
1431 case EVR_AS: // age string | 1412 else |
1432 return new DcmAgeString(key); | 1413 { |
1433 | 1414 return newDicomElement(key); |
1434 case EVR_AE: // application entity title | 1415 } |
1435 return new DcmApplicationEntity(key); | 1416 #endif |
1436 | |
1437 case EVR_CS: // code string | |
1438 return new DcmCodeString(key); | |
1439 | |
1440 case EVR_DA: // date string | |
1441 return new DcmDate(key); | |
1442 | |
1443 case EVR_DT: // date time string | |
1444 return new DcmDateTime(key); | |
1445 | |
1446 case EVR_DS: // decimal string | |
1447 return new DcmDecimalString(key); | |
1448 | |
1449 case EVR_IS: // integer string | |
1450 return new DcmIntegerString(key); | |
1451 | |
1452 case EVR_TM: // time string | |
1453 return new DcmTime(key); | |
1454 | |
1455 case EVR_UI: // unique identifier | |
1456 return new DcmUniqueIdentifier(key); | |
1457 | |
1458 case EVR_ST: // short text | |
1459 return new DcmShortText(key); | |
1460 | |
1461 case EVR_LO: // long string | |
1462 return new DcmLongString(key); | |
1463 | |
1464 case EVR_LT: // long text | |
1465 return new DcmLongText(key); | |
1466 | |
1467 case EVR_UT: // unlimited text | |
1468 return new DcmUnlimitedText(key); | |
1469 | |
1470 case EVR_SH: // short string | |
1471 return new DcmShortString(key); | |
1472 | |
1473 case EVR_PN: // person name | |
1474 return new DcmPersonName(key); | |
1475 | |
1476 #if DCMTK_VERSION_NUMBER >= 361 | |
1477 case EVR_UC: // unlimited characters | |
1478 return new DcmUnlimitedCharacters(key); | |
1479 #endif | |
1480 | |
1481 #if DCMTK_VERSION_NUMBER >= 361 | |
1482 case EVR_UR: // URI/URL | |
1483 return new DcmUniversalResourceIdentifierOrLocator(key); | |
1484 #endif | |
1485 | |
1486 | |
1487 /** | |
1488 * Numerical types | |
1489 **/ | |
1490 | |
1491 case EVR_SL: // signed long | |
1492 return new DcmSignedLong(key); | |
1493 | |
1494 case EVR_SS: // signed short | |
1495 return new DcmSignedShort(key); | |
1496 | |
1497 case EVR_UL: // unsigned long | |
1498 return new DcmUnsignedLong(key); | |
1499 | |
1500 case EVR_US: // unsigned short | |
1501 return new DcmUnsignedShort(key); | |
1502 | |
1503 case EVR_FL: // float single-precision | |
1504 return new DcmFloatingPointSingle(key); | |
1505 | |
1506 case EVR_FD: // float double-precision | |
1507 return new DcmFloatingPointDouble(key); | |
1508 | |
1509 | |
1510 /** | |
1511 * Sequence types, should never occur at this point. | |
1512 **/ | |
1513 | |
1514 case EVR_SQ: // sequence of items | |
1515 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
1516 | |
1517 | |
1518 /** | |
1519 * TODO | |
1520 **/ | |
1521 | |
1522 case EVR_AT: // attribute tag | |
1523 throw OrthancException(ErrorCode_NotImplemented); | |
1524 | |
1525 | |
1526 /** | |
1527 * Internal to DCMTK. | |
1528 **/ | |
1529 | |
1530 case EVR_xs: // SS or US depending on context | |
1531 case EVR_lt: // US, SS or OW depending on context, used for LUT Data (thus the name) | |
1532 case EVR_na: // na="not applicable", for data which has no VR | |
1533 case EVR_up: // up="unsigned pointer", used internally for DICOMDIR suppor | |
1534 case EVR_item: // used internally for items | |
1535 case EVR_metainfo: // used internally for meta info datasets | |
1536 case EVR_dataset: // used internally for datasets | |
1537 case EVR_fileFormat: // used internally for DICOM files | |
1538 case EVR_dicomDir: // used internally for DICOMDIR objects | |
1539 case EVR_dirRecord: // used internally for DICOMDIR records | |
1540 case EVR_pixelSQ: // used internally for pixel sequences in a compressed image | |
1541 case EVR_pixelItem: // used internally for pixel items in a compressed image | |
1542 case EVR_UNKNOWN: // used internally for elements with unknown VR (encoded with 4-byte length field in explicit VR) | |
1543 case EVR_PixelData: // used internally for uncompressed pixeld data | |
1544 case EVR_OverlayData: // used internally for overlay data | |
1545 case EVR_UNKNOWN2B: // used internally for elements with unknown VR with 2-byte length field in explicit VR | |
1546 default: | |
1547 break; | |
1548 } | |
1549 | |
1550 throw OrthancException(ErrorCode_InternalError); | |
1551 } | 1417 } |
1552 | 1418 |
1553 | 1419 |
1554 | 1420 |
1555 void FromDcmtkBridge::FillElementWithString(DcmElement& element, | 1421 void FromDcmtkBridge::FillElementWithString(DcmElement& element, |
1556 const DicomTag& tag, | |
1557 const std::string& utf8Value, | 1422 const std::string& utf8Value, |
1558 bool decodeDataUriScheme, | 1423 bool decodeDataUriScheme, |
1559 Encoding dicomEncoding) | 1424 Encoding dicomEncoding) |
1560 { | 1425 { |
1561 std::string binary; | 1426 std::string binary; |
1576 { | 1441 { |
1577 binary = Toolbox::ConvertFromUtf8(utf8Value, dicomEncoding); | 1442 binary = Toolbox::ConvertFromUtf8(utf8Value, dicomEncoding); |
1578 decoded = &binary; | 1443 decoded = &binary; |
1579 } | 1444 } |
1580 | 1445 |
1581 DcmTag key(tag.GetGroup(), tag.GetElement()); | 1446 if (IsBinaryTag(element.getTag())) |
1582 | |
1583 if (tag.IsPrivate() || | |
1584 IsBinaryTag(key)) | |
1585 { | 1447 { |
1586 bool ok; | 1448 bool ok; |
1587 | 1449 |
1588 switch (key.getEVR()) | 1450 switch (element.getTag().getEVR()) |
1589 { | 1451 { |
1590 case EVR_OW: | 1452 case EVR_OW: |
1591 if (decoded->size() % sizeof(Uint16) != 0) | 1453 if (decoded->size() % sizeof(Uint16) != 0) |
1592 { | 1454 { |
1593 LOG(ERROR) << "A tag with OW VR must have an even number of bytes"; | 1455 LOG(ERROR) << "A tag with OW VR must have an even number of bytes"; |
1617 | 1479 |
1618 bool ok = false; | 1480 bool ok = false; |
1619 | 1481 |
1620 try | 1482 try |
1621 { | 1483 { |
1622 switch (key.getEVR()) | 1484 switch (element.getTag().getEVR()) |
1623 { | 1485 { |
1624 // http://support.dcmtk.org/docs/dcvr_8h-source.html | 1486 // http://support.dcmtk.org/docs/dcvr_8h-source.html |
1625 | 1487 |
1626 /** | 1488 /** |
1627 * TODO. | 1489 * TODO. |
1628 **/ | 1490 **/ |
1629 | 1491 |
1630 case EVR_OB: // other byte | 1492 case EVR_OB: // other byte |
1631 case EVR_OF: // other float | |
1632 case EVR_OW: // other word | 1493 case EVR_OW: // other word |
1633 case EVR_AT: // attribute tag | 1494 case EVR_AT: // attribute tag |
1634 throw OrthancException(ErrorCode_NotImplemented); | 1495 throw OrthancException(ErrorCode_NotImplemented); |
1635 | 1496 |
1636 case EVR_UN: // unknown value representation | 1497 case EVR_UN: // unknown value representation |
1681 ok = element.putSint16(boost::lexical_cast<Sint16>(*decoded)).good(); | 1542 ok = element.putSint16(boost::lexical_cast<Sint16>(*decoded)).good(); |
1682 break; | 1543 break; |
1683 } | 1544 } |
1684 | 1545 |
1685 case EVR_UL: // unsigned long | 1546 case EVR_UL: // unsigned long |
1547 #if DCMTK_VERSION_NUMBER >= 361 | |
1548 case EVR_OL: // other long (requires byte-swapping) | |
1549 #endif | |
1686 { | 1550 { |
1687 ok = element.putUint32(boost::lexical_cast<Uint32>(*decoded)).good(); | 1551 ok = element.putUint32(boost::lexical_cast<Uint32>(*decoded)).good(); |
1688 break; | 1552 break; |
1689 } | 1553 } |
1690 | 1554 |
1693 ok = element.putUint16(boost::lexical_cast<Uint16>(*decoded)).good(); | 1557 ok = element.putUint16(boost::lexical_cast<Uint16>(*decoded)).good(); |
1694 break; | 1558 break; |
1695 } | 1559 } |
1696 | 1560 |
1697 case EVR_FL: // float single-precision | 1561 case EVR_FL: // float single-precision |
1562 case EVR_OF: // other float (requires byte swapping) | |
1698 { | 1563 { |
1699 ok = element.putFloat32(boost::lexical_cast<float>(*decoded)).good(); | 1564 ok = element.putFloat32(boost::lexical_cast<float>(*decoded)).good(); |
1700 break; | 1565 break; |
1701 } | 1566 } |
1702 | 1567 |
1703 case EVR_FD: // float double-precision | 1568 case EVR_FD: // float double-precision |
1569 #if DCMTK_VERSION_NUMBER >= 361 | |
1570 case EVR_OD: // other double (requires byte-swapping) | |
1571 #endif | |
1704 { | 1572 { |
1705 ok = element.putFloat64(boost::lexical_cast<double>(*decoded)).good(); | 1573 ok = element.putFloat64(boost::lexical_cast<double>(*decoded)).good(); |
1706 break; | 1574 break; |
1707 } | 1575 } |
1708 | 1576 |
1748 ok = false; | 1616 ok = false; |
1749 } | 1617 } |
1750 | 1618 |
1751 if (!ok) | 1619 if (!ok) |
1752 { | 1620 { |
1621 DicomTag tag(element.getTag().getGroup(), element.getTag().getElement()); | |
1753 throw OrthancException(ErrorCode_BadFileFormat, | 1622 throw OrthancException(ErrorCode_BadFileFormat, |
1754 "While creating a DICOM instance, tag (" + tag.Format() + | 1623 "While creating a DICOM instance, tag (" + tag.Format() + |
1755 ") has out-of-range value: \"" + (*decoded) + "\""); | 1624 ") has out-of-range value: \"" + (*decoded) + "\""); |
1756 } | 1625 } |
1757 } | 1626 } |
1758 | 1627 |
1759 | 1628 |
1760 DcmElement* FromDcmtkBridge::FromJson(const DicomTag& tag, | 1629 DcmElement* FromDcmtkBridge::FromJson(const DicomTag& tag, |
1761 const Json::Value& value, | 1630 const Json::Value& value, |
1762 bool decodeDataUriScheme, | 1631 bool decodeDataUriScheme, |
1763 Encoding dicomEncoding) | 1632 Encoding dicomEncoding, |
1633 const std::string& privateCreator) | |
1764 { | 1634 { |
1765 std::auto_ptr<DcmElement> element; | 1635 std::auto_ptr<DcmElement> element; |
1766 | 1636 |
1767 switch (value.type()) | 1637 switch (value.type()) |
1768 { | 1638 { |
1769 case Json::stringValue: | 1639 case Json::stringValue: |
1770 element.reset(CreateElementForTag(tag)); | 1640 element.reset(CreateElementForTag(tag, privateCreator)); |
1771 FillElementWithString(*element, tag, value.asString(), decodeDataUriScheme, dicomEncoding); | 1641 FillElementWithString(*element, value.asString(), decodeDataUriScheme, dicomEncoding); |
1772 break; | 1642 break; |
1773 | 1643 |
1774 case Json::nullValue: | 1644 case Json::nullValue: |
1775 element.reset(CreateElementForTag(tag)); | 1645 element.reset(CreateElementForTag(tag, privateCreator)); |
1776 FillElementWithString(*element, tag, "", decodeDataUriScheme, dicomEncoding); | 1646 FillElementWithString(*element, "", decodeDataUriScheme, dicomEncoding); |
1777 break; | 1647 break; |
1778 | 1648 |
1779 case Json::arrayValue: | 1649 case Json::arrayValue: |
1780 { | 1650 { |
1781 DcmTag key(tag.GetGroup(), tag.GetElement()); | 1651 DcmTag key(tag.GetGroup(), tag.GetElement()); |
1796 case Json::objectValue: | 1666 case Json::objectValue: |
1797 { | 1667 { |
1798 Json::Value::Members members = value[i].getMemberNames(); | 1668 Json::Value::Members members = value[i].getMemberNames(); |
1799 for (Json::Value::ArrayIndex j = 0; j < members.size(); j++) | 1669 for (Json::Value::ArrayIndex j = 0; j < members.size(); j++) |
1800 { | 1670 { |
1801 item->insert(FromJson(ParseTag(members[j]), value[i][members[j]], decodeDataUriScheme, dicomEncoding)); | 1671 item->insert(FromJson(ParseTag(members[j]), value[i][members[j]], decodeDataUriScheme, dicomEncoding, privateCreator)); |
1802 } | 1672 } |
1803 break; | 1673 break; |
1804 } | 1674 } |
1805 | 1675 |
1806 case Json::arrayValue: | 1676 case Json::arrayValue: |
1905 | 1775 |
1906 | 1776 |
1907 DcmDataset* FromDcmtkBridge::FromJson(const Json::Value& json, // Encoded using UTF-8 | 1777 DcmDataset* FromDcmtkBridge::FromJson(const Json::Value& json, // Encoded using UTF-8 |
1908 bool generateIdentifiers, | 1778 bool generateIdentifiers, |
1909 bool decodeDataUriScheme, | 1779 bool decodeDataUriScheme, |
1910 Encoding defaultEncoding) | 1780 Encoding defaultEncoding, |
1781 const std::string& privateCreator) | |
1911 { | 1782 { |
1912 std::auto_ptr<DcmDataset> result(new DcmDataset); | 1783 std::auto_ptr<DcmDataset> result(new DcmDataset); |
1913 Encoding encoding = ExtractEncoding(json, defaultEncoding); | 1784 Encoding encoding = ExtractEncoding(json, defaultEncoding); |
1914 | 1785 |
1915 SetString(*result, DCM_SpecificCharacterSet, GetDicomSpecificCharacterSet(encoding)); | 1786 SetString(*result, DCM_SpecificCharacterSet, GetDicomSpecificCharacterSet(encoding)); |
1943 hasSopInstanceUid = true; | 1814 hasSopInstanceUid = true; |
1944 } | 1815 } |
1945 | 1816 |
1946 if (tag != DICOM_TAG_SPECIFIC_CHARACTER_SET) | 1817 if (tag != DICOM_TAG_SPECIFIC_CHARACTER_SET) |
1947 { | 1818 { |
1948 std::auto_ptr<DcmElement> element(FromDcmtkBridge::FromJson(tag, value, decodeDataUriScheme, encoding)); | 1819 std::auto_ptr<DcmElement> element(FromDcmtkBridge::FromJson(tag, value, decodeDataUriScheme, encoding, privateCreator)); |
1949 const DcmTagKey& tag = element->getTag(); | 1820 const DcmTagKey& tag = element->getTag(); |
1950 | 1821 |
1951 result->findAndDeleteElement(tag); | 1822 result->findAndDeleteElement(tag); |
1952 | 1823 |
1953 DcmElement* tmp = element.release(); | 1824 DcmElement* tmp = element.release(); |
2266 /** | 2137 /** |
2267 * Deal with binary data (including PixelData). | 2138 * Deal with binary data (including PixelData). |
2268 **/ | 2139 **/ |
2269 | 2140 |
2270 if (evr == EVR_OB || // other byte | 2141 if (evr == EVR_OB || // other byte |
2271 evr == EVR_OF || // other float | |
2272 #if DCMTK_VERSION_NUMBER >= 361 | |
2273 evr == EVR_OD || // other double | |
2274 #endif | |
2275 #if DCMTK_VERSION_NUMBER >= 362 | |
2276 evr == EVR_OL || // other long | |
2277 #endif | |
2278 evr == EVR_OW || // other word | 2142 evr == EVR_OW || // other word |
2279 evr == EVR_UN) // unknown value representation | 2143 evr == EVR_UN) // unknown value representation |
2280 { | 2144 { |
2281 Uint16* data16 = NULL; | 2145 Uint16* data16 = NULL; |
2282 Uint8* data = NULL; | 2146 Uint8* data = NULL; |
2462 visitor.VisitIntegers(parentTags, parentIndexes, tag, vr, values); | 2326 visitor.VisitIntegers(parentTags, parentIndexes, tag, vr, values); |
2463 break; | 2327 break; |
2464 } | 2328 } |
2465 | 2329 |
2466 case EVR_UL: // unsigned long | 2330 case EVR_UL: // unsigned long |
2331 #if DCMTK_VERSION_NUMBER >= 362 | |
2332 case EVR_OL: | |
2333 #endif | |
2467 { | 2334 { |
2468 DcmUnsignedLong& content = dynamic_cast<DcmUnsignedLong&>(element); | 2335 DcmUnsignedLong& content = dynamic_cast<DcmUnsignedLong&>(element); |
2469 | 2336 |
2470 std::vector<int64_t> values; | 2337 std::vector<int64_t> values; |
2471 values.reserve(content.getVM()); | 2338 values.reserve(content.getVM()); |
2502 visitor.VisitIntegers(parentTags, parentIndexes, tag, vr, values); | 2369 visitor.VisitIntegers(parentTags, parentIndexes, tag, vr, values); |
2503 break; | 2370 break; |
2504 } | 2371 } |
2505 | 2372 |
2506 case EVR_FL: // float single-precision | 2373 case EVR_FL: // float single-precision |
2374 case EVR_OF: | |
2507 { | 2375 { |
2508 DcmFloatingPointSingle& content = dynamic_cast<DcmFloatingPointSingle&>(element); | 2376 DcmFloatingPointSingle& content = dynamic_cast<DcmFloatingPointSingle&>(element); |
2509 | 2377 |
2510 std::vector<double> values; | 2378 std::vector<double> values; |
2511 values.reserve(content.getVM()); | 2379 values.reserve(content.getVM()); |
2522 visitor.VisitDoubles(parentTags, parentIndexes, tag, vr, values); | 2390 visitor.VisitDoubles(parentTags, parentIndexes, tag, vr, values); |
2523 break; | 2391 break; |
2524 } | 2392 } |
2525 | 2393 |
2526 case EVR_FD: // float double-precision | 2394 case EVR_FD: // float double-precision |
2395 #if DCMTK_VERSION_NUMBER >= 361 | |
2396 case EVR_OD: | |
2397 #endif | |
2527 { | 2398 { |
2528 DcmFloatingPointDouble& content = dynamic_cast<DcmFloatingPointDouble&>(element); | 2399 DcmFloatingPointDouble& content = dynamic_cast<DcmFloatingPointDouble&>(element); |
2529 | 2400 |
2530 std::vector<double> values; | 2401 std::vector<double> values; |
2531 values.reserve(content.getVM()); | 2402 values.reserve(content.getVM()); |