comparison OrthancServer/ParsedDicomFile.cpp @ 1701:4aaaecae5803 db-changes

integration mainline->db-changes
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 12 Oct 2015 14:47:58 +0200
parents de1413733c97 8ca0e89798b2
children a001f6226c7c
comparison
equal deleted inserted replaced
1683:21d31da73374 1701:4aaaecae5803
135 #include <dcmtk/dcmdata/dcpxitem.h> 135 #include <dcmtk/dcmdata/dcpxitem.h>
136 136
137 137
138 #include <boost/math/special_functions/round.hpp> 138 #include <boost/math/special_functions/round.hpp>
139 #include <dcmtk/dcmdata/dcostrmb.h> 139 #include <dcmtk/dcmdata/dcostrmb.h>
140 #include <boost/algorithm/string/predicate.hpp>
140 141
141 142
142 static const char* CONTENT_TYPE_OCTET_STREAM = "application/octet-stream"; 143 static const char* CONTENT_TYPE_OCTET_STREAM = "application/octet-stream";
143 144
144 145
146 namespace Orthanc 147 namespace Orthanc
147 { 148 {
148 struct ParsedDicomFile::PImpl 149 struct ParsedDicomFile::PImpl
149 { 150 {
150 std::auto_ptr<DcmFileFormat> file_; 151 std::auto_ptr<DcmFileFormat> file_;
151 Encoding encoding_;
152 }; 152 };
153 153
154 154
155 // This method can only be called from the constructors! 155 // This method can only be called from the constructors!
156 void ParsedDicomFile::Setup(const char* buffer, size_t size) 156 void ParsedDicomFile::Setup(const char* buffer, size_t size)
171 171
172 throw OrthancException(ErrorCode_BadFileFormat); 172 throw OrthancException(ErrorCode_BadFileFormat);
173 } 173 }
174 pimpl_->file_->loadAllDataIntoMemory(); 174 pimpl_->file_->loadAllDataIntoMemory();
175 pimpl_->file_->transferEnd(); 175 pimpl_->file_->transferEnd();
176
177 pimpl_->encoding_ = FromDcmtkBridge::DetectEncoding(*pimpl_->file_->getDataset());
178 } 176 }
179 177
180 178
181 static void SendPathValueForDictionary(RestApiOutput& output, 179 static void SendPathValueForDictionary(RestApiOutput& output,
182 DcmItem& dicom) 180 DcmItem& dicom)
517 SendPathValueForLeaf(output, uri.back(), *dicom, transferSyntax); 515 SendPathValueForLeaf(output, uri.back(), *dicom, transferSyntax);
518 } 516 }
519 } 517 }
520 518
521 519
522
523
524
525 static DcmElement* CreateElementForTag(const DicomTag& tag)
526 {
527 DcmTag key(tag.GetGroup(), tag.GetElement());
528
529 switch (key.getEVR())
530 {
531 // http://support.dcmtk.org/docs/dcvr_8h-source.html
532
533 /**
534 * TODO.
535 **/
536
537 case EVR_OB: // other byte
538 case EVR_OF: // other float
539 case EVR_OW: // other word
540 case EVR_AT: // attribute tag
541 throw OrthancException(ErrorCode_NotImplemented);
542
543 case EVR_UN: // unknown value representation
544 throw OrthancException(ErrorCode_ParameterOutOfRange);
545
546
547 /**
548 * String types.
549 * http://support.dcmtk.org/docs/classDcmByteString.html
550 **/
551
552 case EVR_AS: // age string
553 return new DcmAgeString(key);
554
555 case EVR_AE: // application entity title
556 return new DcmApplicationEntity(key);
557
558 case EVR_CS: // code string
559 return new DcmCodeString(key);
560
561 case EVR_DA: // date string
562 return new DcmDate(key);
563
564 case EVR_DT: // date time string
565 return new DcmDateTime(key);
566
567 case EVR_DS: // decimal string
568 return new DcmDecimalString(key);
569
570 case EVR_IS: // integer string
571 return new DcmIntegerString(key);
572
573 case EVR_TM: // time string
574 return new DcmTime(key);
575
576 case EVR_UI: // unique identifier
577 return new DcmUniqueIdentifier(key);
578
579 case EVR_ST: // short text
580 return new DcmShortText(key);
581
582 case EVR_LO: // long string
583 return new DcmLongString(key);
584
585 case EVR_LT: // long text
586 return new DcmLongText(key);
587
588 case EVR_UT: // unlimited text
589 return new DcmUnlimitedText(key);
590
591 case EVR_SH: // short string
592 return new DcmShortString(key);
593
594 case EVR_PN: // person name
595 return new DcmPersonName(key);
596
597
598 /**
599 * Numerical types
600 **/
601
602 case EVR_SL: // signed long
603 return new DcmSignedLong(key);
604
605 case EVR_SS: // signed short
606 return new DcmSignedShort(key);
607
608 case EVR_UL: // unsigned long
609 return new DcmUnsignedLong(key);
610
611 case EVR_US: // unsigned short
612 return new DcmUnsignedShort(key);
613
614 case EVR_FL: // float single-precision
615 return new DcmFloatingPointSingle(key);
616
617 case EVR_FD: // float double-precision
618 return new DcmFloatingPointDouble(key);
619
620
621 /**
622 * Sequence types, should never occur at this point.
623 **/
624
625 case EVR_SQ: // sequence of items
626 throw OrthancException(ErrorCode_ParameterOutOfRange);
627
628
629 /**
630 * Internal to DCMTK.
631 **/
632
633 case EVR_ox: // OB or OW depending on context
634 case EVR_xs: // SS or US depending on context
635 case EVR_lt: // US, SS or OW depending on context, used for LUT Data (thus the name)
636 case EVR_na: // na="not applicable", for data which has no VR
637 case EVR_up: // up="unsigned pointer", used internally for DICOMDIR suppor
638 case EVR_item: // used internally for items
639 case EVR_metainfo: // used internally for meta info datasets
640 case EVR_dataset: // used internally for datasets
641 case EVR_fileFormat: // used internally for DICOM files
642 case EVR_dicomDir: // used internally for DICOMDIR objects
643 case EVR_dirRecord: // used internally for DICOMDIR records
644 case EVR_pixelSQ: // used internally for pixel sequences in a compressed image
645 case EVR_pixelItem: // used internally for pixel items in a compressed image
646 case EVR_UNKNOWN: // used internally for elements with unknown VR (encoded with 4-byte length field in explicit VR)
647 case EVR_PixelData: // used internally for uncompressed pixeld data
648 case EVR_OverlayData: // used internally for overlay data
649 case EVR_UNKNOWN2B: // used internally for elements with unknown VR with 2-byte length field in explicit VR
650 default:
651 break;
652 }
653
654 throw OrthancException(ErrorCode_InternalError);
655 }
656
657
658
659 static void FillElementWithString(DcmElement& element,
660 const DicomTag& tag,
661 const std::string& value)
662 {
663 DcmTag key(tag.GetGroup(), tag.GetElement());
664 bool ok = false;
665
666 try
667 {
668 switch (key.getEVR())
669 {
670 // http://support.dcmtk.org/docs/dcvr_8h-source.html
671
672 /**
673 * TODO.
674 **/
675
676 case EVR_OB: // other byte
677 case EVR_OF: // other float
678 case EVR_OW: // other word
679 case EVR_AT: // attribute tag
680 throw OrthancException(ErrorCode_NotImplemented);
681
682 case EVR_UN: // unknown value representation
683 throw OrthancException(ErrorCode_ParameterOutOfRange);
684
685
686 /**
687 * String types.
688 **/
689
690 case EVR_DS: // decimal string
691 case EVR_IS: // integer string
692 case EVR_AS: // age string
693 case EVR_DA: // date string
694 case EVR_DT: // date time string
695 case EVR_TM: // time string
696 case EVR_AE: // application entity title
697 case EVR_CS: // code string
698 case EVR_SH: // short string
699 case EVR_LO: // long string
700 case EVR_ST: // short text
701 case EVR_LT: // long text
702 case EVR_UT: // unlimited text
703 case EVR_PN: // person name
704 case EVR_UI: // unique identifier
705 {
706 ok = element.putString(value.c_str()).good();
707 break;
708 }
709
710
711 /**
712 * Numerical types
713 **/
714
715 case EVR_SL: // signed long
716 {
717 ok = element.putSint32(boost::lexical_cast<Sint32>(value)).good();
718 break;
719 }
720
721 case EVR_SS: // signed short
722 {
723 ok = element.putSint16(boost::lexical_cast<Sint16>(value)).good();
724 break;
725 }
726
727 case EVR_UL: // unsigned long
728 {
729 ok = element.putUint32(boost::lexical_cast<Uint32>(value)).good();
730 break;
731 }
732
733 case EVR_US: // unsigned short
734 {
735 ok = element.putUint16(boost::lexical_cast<Uint16>(value)).good();
736 break;
737 }
738
739 case EVR_FL: // float single-precision
740 {
741 ok = element.putFloat32(boost::lexical_cast<float>(value)).good();
742 break;
743 }
744
745 case EVR_FD: // float double-precision
746 {
747 ok = element.putFloat64(boost::lexical_cast<double>(value)).good();
748 break;
749 }
750
751
752 /**
753 * Sequence types, should never occur at this point.
754 **/
755
756 case EVR_SQ: // sequence of items
757 {
758 ok = false;
759 break;
760 }
761
762
763 /**
764 * Internal to DCMTK.
765 **/
766
767 case EVR_ox: // OB or OW depending on context
768 case EVR_xs: // SS or US depending on context
769 case EVR_lt: // US, SS or OW depending on context, used for LUT Data (thus the name)
770 case EVR_na: // na="not applicable", for data which has no VR
771 case EVR_up: // up="unsigned pointer", used internally for DICOMDIR suppor
772 case EVR_item: // used internally for items
773 case EVR_metainfo: // used internally for meta info datasets
774 case EVR_dataset: // used internally for datasets
775 case EVR_fileFormat: // used internally for DICOM files
776 case EVR_dicomDir: // used internally for DICOMDIR objects
777 case EVR_dirRecord: // used internally for DICOMDIR records
778 case EVR_pixelSQ: // used internally for pixel sequences in a compressed image
779 case EVR_pixelItem: // used internally for pixel items in a compressed image
780 case EVR_UNKNOWN: // used internally for elements with unknown VR (encoded with 4-byte length field in explicit VR)
781 case EVR_PixelData: // used internally for uncompressed pixeld data
782 case EVR_OverlayData: // used internally for overlay data
783 case EVR_UNKNOWN2B: // used internally for elements with unknown VR with 2-byte length field in explicit VR
784 default:
785 break;
786 }
787 }
788 catch (boost::bad_lexical_cast&)
789 {
790 ok = false;
791 }
792
793 if (!ok)
794 {
795 throw OrthancException(ErrorCode_InternalError);
796 }
797 }
798
799
800 void ParsedDicomFile::Remove(const DicomTag& tag) 520 void ParsedDicomFile::Remove(const DicomTag& tag)
801 { 521 {
802 DcmTagKey key(tag.GetGroup(), tag.GetElement()); 522 DcmTagKey key(tag.GetGroup(), tag.GetElement());
803 DcmElement* element = pimpl_->file_->getDataset()->remove(key); 523 DcmElement* element = pimpl_->file_->getDataset()->remove(key);
804 if (element != NULL) 524 if (element != NULL)
821 { 541 {
822 DcmElement* element = dataset.getElement(i); 542 DcmElement* element = dataset.getElement(i);
823 DcmTag tag(element->getTag()); 543 DcmTag tag(element->getTag());
824 544
825 // Is this a private tag? 545 // Is this a private tag?
826 if (FromDcmtkBridge::IsPrivateTag(tag)) 546 if (tag.isPrivate())
827 { 547 {
828 bool remove = true; 548 bool remove = true;
829 549
830 // Check whether this private tag is to be kept 550 // Check whether this private tag is to be kept
831 if (toKeep != NULL) 551 if (toKeep != NULL)
855 } 575 }
856 } 576 }
857 } 577 }
858 578
859 579
580 static void InsertInternal(DcmDataset& dicom,
581 DcmElement* element)
582 {
583 OFCondition cond = dicom.insert(element, false, false);
584 if (!cond.good())
585 {
586 // This field already exists
587 delete element;
588 throw OrthancException(ErrorCode_InternalError);
589 }
590 }
860 591
861 592
862 void ParsedDicomFile::Insert(const DicomTag& tag, 593 void ParsedDicomFile::Insert(const DicomTag& tag,
863 const std::string& value) 594 const Json::Value& value,
864 { 595 bool decodeBinaryTags)
865 OFCondition cond; 596 {
866 597 std::auto_ptr<DcmElement> element(FromDcmtkBridge::FromJson(tag, value, decodeBinaryTags, GetEncoding()));
867 if (FromDcmtkBridge::IsPrivateTag(tag) || 598 InsertInternal(*pimpl_->file_->getDataset(), element.release());
868 FromDcmtkBridge::IsUnknownTag(tag)) 599 }
869 { 600
870 // This is a private tag 601
871 // http://support.dcmtk.org/redmine/projects/dcmtk/wiki/howto_addprivatedata 602 static void ReplaceInternal(DcmDataset& dicom,
872 603 std::auto_ptr<DcmElement>& element,
873 DcmTag key(tag.GetGroup(), tag.GetElement(), EVR_OB); 604 DicomReplaceMode mode)
874 cond = pimpl_->file_->getDataset()->putAndInsertUint8Array 605 {
875 (key, (const Uint8*) value.c_str(), value.size(), false); 606 const DcmTagKey& tag = element->getTag();
876 } 607
877 else 608 if (!dicom.findAndDeleteElement(tag).good())
878 {
879 std::auto_ptr<DcmElement> element(CreateElementForTag(tag));
880 FillElementWithString(*element, tag, value);
881
882 cond = pimpl_->file_->getDataset()->insert(element.release(), false, false);
883 }
884
885 if (!cond.good())
886 {
887 // This field already exists
888 throw OrthancException(ErrorCode_InternalError);
889 }
890 }
891
892
893 void ParsedDicomFile::Replace(const DicomTag& tag,
894 const std::string& value,
895 DicomReplaceMode mode)
896 {
897 DcmTagKey key(tag.GetGroup(), tag.GetElement());
898 DcmElement* element = NULL;
899
900 if (!pimpl_->file_->getDataset()->findAndGetElement(key, element).good() ||
901 element == NULL)
902 { 609 {
903 // This field does not exist, act wrt. the specified "mode" 610 // This field does not exist, act wrt. the specified "mode"
904 switch (mode) 611 switch (mode)
905 { 612 {
906 case DicomReplaceMode_InsertIfAbsent: 613 case DicomReplaceMode_InsertIfAbsent:
907 Insert(tag, value);
908 break; 614 break;
909 615
910 case DicomReplaceMode_ThrowIfAbsent: 616 case DicomReplaceMode_ThrowIfAbsent:
911 throw OrthancException(ErrorCode_InexistentItem); 617 throw OrthancException(ErrorCode_InexistentItem);
912 618
913 case DicomReplaceMode_IgnoreIfAbsent: 619 case DicomReplaceMode_IgnoreIfAbsent:
914 return; 620 return;
915 } 621 }
916 } 622 }
623
624 // Either the tag was not existing, or the replace mode was set to
625 // "InsertIfAbsent"
626 InsertInternal(dicom, element.release());
627 }
628
629
630 void ParsedDicomFile::UpdateStorageUid(const DicomTag& tag,
631 const std::string& utf8Value,
632 bool decodeBinaryTags)
633 {
634 if (tag != DICOM_TAG_SOP_CLASS_UID &&
635 tag != DICOM_TAG_SOP_INSTANCE_UID)
636 {
637 return;
638 }
639
640 std::string binary;
641 const std::string* decoded = &utf8Value;
642
643 if (decodeBinaryTags &&
644 boost::starts_with(utf8Value, "data:application/octet-stream;base64,"))
645 {
646 std::string mime;
647 Toolbox::DecodeDataUriScheme(mime, binary, utf8Value);
648 decoded = &binary;
649 }
917 else 650 else
918 { 651 {
919 if (FromDcmtkBridge::IsPrivateTag(tag) || 652 Encoding encoding = GetEncoding();
920 FromDcmtkBridge::IsUnknownTag(tag)) 653 if (GetEncoding() != Encoding_Utf8)
921 { 654 {
922 if (!element->putUint8Array((const Uint8*) value.c_str(), value.size()).good()) 655 binary = Toolbox::ConvertFromUtf8(utf8Value, encoding);
923 { 656 decoded = &binary;
924 throw OrthancException(ErrorCode_InternalError); 657 }
925 } 658 }
926 }
927 else
928 {
929 FillElementWithString(*element, tag, value);
930 }
931 }
932
933 659
934 /** 660 /**
935 * dcmodify will automatically correct 'Media Storage SOP Class 661 * dcmodify will automatically correct 'Media Storage SOP Class
936 * UID' and 'Media Storage SOP Instance UID' in the metaheader, if 662 * UID' and 'Media Storage SOP Instance UID' in the metaheader, if
937 * you make changes to the related tags in the dataset ('SOP Class 663 * you make changes to the related tags in the dataset ('SOP Class
940 * option. 666 * option.
941 **/ 667 **/
942 668
943 if (tag == DICOM_TAG_SOP_CLASS_UID) 669 if (tag == DICOM_TAG_SOP_CLASS_UID)
944 { 670 {
945 Replace(DICOM_TAG_MEDIA_STORAGE_SOP_CLASS_UID, value, DicomReplaceMode_InsertIfAbsent); 671 Replace(DICOM_TAG_MEDIA_STORAGE_SOP_CLASS_UID, *decoded, DicomReplaceMode_InsertIfAbsent);
946 } 672 }
947 673
948 if (tag == DICOM_TAG_SOP_INSTANCE_UID) 674 if (tag == DICOM_TAG_SOP_INSTANCE_UID)
949 { 675 {
950 Replace(DICOM_TAG_MEDIA_STORAGE_SOP_INSTANCE_UID, value, DicomReplaceMode_InsertIfAbsent); 676 Replace(DICOM_TAG_MEDIA_STORAGE_SOP_INSTANCE_UID, *decoded, DicomReplaceMode_InsertIfAbsent);
677 }
678 }
679
680
681 void ParsedDicomFile::Replace(const DicomTag& tag,
682 const std::string& utf8Value,
683 DicomReplaceMode mode)
684 {
685 std::auto_ptr<DcmElement> element(FromDcmtkBridge::CreateElementForTag(tag));
686 FromDcmtkBridge::FillElementWithString(*element, tag, utf8Value, false, GetEncoding());
687 ReplaceInternal(*pimpl_->file_->getDataset(), element, mode);
688 UpdateStorageUid(tag, utf8Value, false);
689 }
690
691
692 void ParsedDicomFile::Replace(const DicomTag& tag,
693 const Json::Value& value,
694 bool decodeBinaryTags,
695 DicomReplaceMode mode)
696 {
697 std::auto_ptr<DcmElement> element(FromDcmtkBridge::FromJson(tag, value, decodeBinaryTags, GetEncoding()));
698 ReplaceInternal(*pimpl_->file_->getDataset(), element, mode);
699
700 if (tag == DICOM_TAG_SOP_CLASS_UID ||
701 tag == DICOM_TAG_SOP_INSTANCE_UID)
702 {
703 if (value.type() != Json::stringValue)
704 {
705 throw OrthancException(ErrorCode_BadParameterType);
706 }
707
708 UpdateStorageUid(tag, value.asString(), decodeBinaryTags);
951 } 709 }
952 } 710 }
953 711
954 712
955 void ParsedDicomFile::Answer(RestApiOutput& output) 713 void ParsedDicomFile::Answer(RestApiOutput& output)
1003 element == NULL) 761 element == NULL)
1004 { 762 {
1005 return false; 763 return false;
1006 } 764 }
1007 765
1008 std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(*element, pimpl_->encoding_)); 766 std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(*element, GetEncoding()));
1009 767
1010 if (v.get() == NULL) 768 if (v.get() == NULL)
1011 { 769 {
1012 value = ""; 770 value = "";
1013 } 771 }
1083 841
1084 842
1085 ParsedDicomFile::ParsedDicomFile() : pimpl_(new PImpl) 843 ParsedDicomFile::ParsedDicomFile() : pimpl_(new PImpl)
1086 { 844 {
1087 pimpl_->file_.reset(new DcmFileFormat); 845 pimpl_->file_.reset(new DcmFileFormat);
1088 pimpl_->encoding_ = Encoding_Ascii;
1089 Replace(DICOM_TAG_PATIENT_ID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Patient)); 846 Replace(DICOM_TAG_PATIENT_ID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Patient));
1090 Replace(DICOM_TAG_STUDY_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Study)); 847 Replace(DICOM_TAG_STUDY_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Study));
1091 Replace(DICOM_TAG_SERIES_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series)); 848 Replace(DICOM_TAG_SERIES_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series));
1092 Replace(DICOM_TAG_SOP_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Instance)); 849 Replace(DICOM_TAG_SOP_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Instance));
1093 } 850 }
1113 870
1114 ParsedDicomFile::ParsedDicomFile(ParsedDicomFile& other) : 871 ParsedDicomFile::ParsedDicomFile(ParsedDicomFile& other) :
1115 pimpl_(new PImpl) 872 pimpl_(new PImpl)
1116 { 873 {
1117 pimpl_->file_.reset(dynamic_cast<DcmFileFormat*>(other.pimpl_->file_->clone())); 874 pimpl_->file_.reset(dynamic_cast<DcmFileFormat*>(other.pimpl_->file_->clone()));
1118 pimpl_->encoding_ = other.pimpl_->encoding_;
1119 875
1120 // Create a new instance-level identifier 876 // Create a new instance-level identifier
1121 Replace(DICOM_TAG_SOP_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Instance)); 877 Replace(DICOM_TAG_SOP_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Instance));
1122 } 878 }
1123 879
1154 { 910 {
1155 EmbedPdf(content); 911 EmbedPdf(content);
1156 } 912 }
1157 else 913 else
1158 { 914 {
1159 LOG(ERROR) << "Unsupported MIME type for the content of a new DICOM file"; 915 LOG(ERROR) << "Unsupported MIME type for the content of a new DICOM file: " << mime;
1160 throw OrthancException(ErrorCode_NotImplemented); 916 throw OrthancException(ErrorCode_NotImplemented);
1161 } 917 }
1162 } 918 }
1163 919
1164 920
1343 } 1099 }
1344 1100
1345 1101
1346 Encoding ParsedDicomFile::GetEncoding() const 1102 Encoding ParsedDicomFile::GetEncoding() const
1347 { 1103 {
1348 return pimpl_->encoding_; 1104 return FromDcmtkBridge::DetectEncoding(*pimpl_->file_->getDataset());
1349 } 1105 }
1350 1106
1351 1107
1352 void ParsedDicomFile::SetEncoding(Encoding encoding) 1108 void ParsedDicomFile::SetEncoding(Encoding encoding)
1353 { 1109 {
1356 // This Cyrillic codepage is not officially supported by the 1112 // This Cyrillic codepage is not officially supported by the
1357 // DICOM standard. Do not set the SpecificCharacterSet tag. 1113 // DICOM standard. Do not set the SpecificCharacterSet tag.
1358 return; 1114 return;
1359 } 1115 }
1360 1116
1361 pimpl_->encoding_ = encoding;
1362
1363 std::string s = GetDicomSpecificCharacterSet(encoding); 1117 std::string s = GetDicomSpecificCharacterSet(encoding);
1364 Replace(DICOM_TAG_SPECIFIC_CHARACTER_SET, s, DicomReplaceMode_InsertIfAbsent); 1118 Replace(DICOM_TAG_SPECIFIC_CHARACTER_SET, s, DicomReplaceMode_InsertIfAbsent);
1365 } 1119 }
1366 1120
1367 void ParsedDicomFile::ToJson(Json::Value& target, bool simplify) 1121 void ParsedDicomFile::ToJson(Json::Value& target,
1368 { 1122 DicomToJsonFormat format,
1369 if (simplify) 1123 unsigned int maxStringLength)
1370 { 1124 {
1371 Json::Value tmp; 1125 FromDcmtkBridge::ToJson(target, *pimpl_->file_->getDataset(), format, maxStringLength);
1372 FromDcmtkBridge::ToJson(tmp, *pimpl_->file_->getDataset());
1373 Toolbox::SimplifyTags(target, tmp);
1374 }
1375 else
1376 {
1377 FromDcmtkBridge::ToJson(target, *pimpl_->file_->getDataset());
1378 }
1379 } 1126 }
1380 1127
1381 1128
1382 bool ParsedDicomFile::HasTag(const DicomTag& tag) const 1129 bool ParsedDicomFile::HasTag(const DicomTag& tag) const
1383 { 1130 {