comparison OrthancServer/FromDcmtkBridge.cpp @ 306:326d5a4a5af3

modification of instances
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 20 Dec 2012 16:44:50 +0100
parents 86bb79522f19
children fbf2b2282086
comparison
equal deleted inserted replaced
305:86bb79522f19 306:326d5a4a5af3
37 37
38 #include "ToDcmtkBridge.h" 38 #include "ToDcmtkBridge.h"
39 #include "../Core/Toolbox.h" 39 #include "../Core/Toolbox.h"
40 #include "../Core/OrthancException.h" 40 #include "../Core/OrthancException.h"
41 #include "../Core/PngWriter.h" 41 #include "../Core/PngWriter.h"
42 #include "../Core/Uuid.h"
42 #include "../Core/DicomFormat/DicomString.h" 43 #include "../Core/DicomFormat/DicomString.h"
43 #include "../Core/DicomFormat/DicomNullValue.h" 44 #include "../Core/DicomFormat/DicomNullValue.h"
44 #include "../Core/DicomFormat/DicomIntegerPixelAccessor.h" 45 #include "../Core/DicomFormat/DicomIntegerPixelAccessor.h"
45 46
47 #include <list>
46 #include <limits> 48 #include <limits>
47 49
48 #include <boost/lexical_cast.hpp> 50 #include <boost/lexical_cast.hpp>
49 51
50 #include <dcmtk/dcmdata/dcchrstr.h> 52 #include <dcmtk/dcmdata/dcchrstr.h>
548 550
549 551
550 void ParsedDicomFile::Remove(const DicomTag& tag) 552 void ParsedDicomFile::Remove(const DicomTag& tag)
551 { 553 {
552 DcmTagKey key(tag.GetGroup(), tag.GetElement()); 554 DcmTagKey key(tag.GetGroup(), tag.GetElement());
553 555 DcmElement* element = file_->getDataset()->remove(key);
554 // TODO This call results in memory leaks inside DCMTK 556 if (element != NULL)
555 file_->getDataset()->remove(key); 557 {
558 delete element;
559 }
560 }
561
562
563
564 void ParsedDicomFile::RemovePrivateTags()
565 {
566 typedef std::list<DcmElement*> Tags;
567
568 Tags privateTags;
569
570 DcmDataset& dataset = *file_->getDataset();
571 for (unsigned long i = 0; i < dataset.card(); i++)
572 {
573 DcmElement* element = dataset.getElement(i);
574 DcmTag tag(element->getTag());
575 if (tag.getPrivateCreator() != NULL)
576 {
577 privateTags.push_back(element);
578 }
579 }
580
581 for (Tags::iterator it = privateTags.begin();
582 it != privateTags.end(); it++)
583 {
584 DcmElement* tmp = dataset.remove(*it);
585 if (tmp != NULL)
586 {
587 delete tmp;
588 }
589 }
556 } 590 }
557 591
558 592
559 593
560 void ParsedDicomFile::Insert(const DicomTag& tag, 594 void ParsedDicomFile::Insert(const DicomTag& tag,
679 { 713 {
680 714
681 /** 715 /**
682 * TODO. 716 * TODO.
683 **/ 717 **/
684 718
685 case EVR_DS: // decimal string
686 case EVR_IS: // integer string
687 case EVR_OB: // other byte 719 case EVR_OB: // other byte
688 case EVR_OF: // other float 720 case EVR_OF: // other float
689 case EVR_OW: // other word 721 case EVR_OW: // other word
690 case EVR_AS: // age string
691 case EVR_AT: // attribute tag 722 case EVR_AT: // attribute tag
692 case EVR_DA: // date string
693 case EVR_DT: // date time string
694 case EVR_TM: // time string
695 case EVR_UN: // unknown value representation 723 case EVR_UN: // unknown value representation
696 return new DicomNullValue(); 724 return new DicomNullValue();
697 725
698
699 /** 726 /**
700 * String types, should never happen at this point because of 727 * String types, should never happen at this point because of
701 * "element.isaString()". 728 * "element.isaString()".
702 **/ 729 **/
703 730
731 case EVR_DS: // decimal string
732 case EVR_IS: // integer string
733 case EVR_AS: // age string
734 case EVR_DA: // date string
735 case EVR_DT: // date time string
736 case EVR_TM: // time string
704 case EVR_AE: // application entity title 737 case EVR_AE: // application entity title
705 case EVR_CS: // code string 738 case EVR_CS: // code string
706 case EVR_SH: // short string 739 case EVR_SH: // short string
707 case EVR_LO: // long string 740 case EVR_LO: // long string
708 case EVR_ST: // short text 741 case EVR_ST: // short text
719 752
720 case EVR_SL: // signed long 753 case EVR_SL: // signed long
721 { 754 {
722 Sint32 f; 755 Sint32 f;
723 if (dynamic_cast<DcmSignedLong&>(element).getSint32(f).good()) 756 if (dynamic_cast<DcmSignedLong&>(element).getSint32(f).good())
724 {
725 return new DicomString(boost::lexical_cast<std::string>(f)); 757 return new DicomString(boost::lexical_cast<std::string>(f));
726 }
727 else 758 else
728 {
729 return new DicomNullValue(); 759 return new DicomNullValue();
730 }
731 } 760 }
732 761
733 case EVR_SS: // signed short 762 case EVR_SS: // signed short
734 { 763 {
735 Sint16 f; 764 Sint16 f;
736 if (dynamic_cast<DcmSignedShort&>(element).getSint16(f).good()) 765 if (dynamic_cast<DcmSignedShort&>(element).getSint16(f).good())
737 {
738 return new DicomString(boost::lexical_cast<std::string>(f)); 766 return new DicomString(boost::lexical_cast<std::string>(f));
739 }
740 else 767 else
741 {
742 return new DicomNullValue(); 768 return new DicomNullValue();
743 }
744 } 769 }
745 770
746 case EVR_UL: // unsigned long 771 case EVR_UL: // unsigned long
747 { 772 {
748 Uint32 f; 773 Uint32 f;
749 if (dynamic_cast<DcmUnsignedLong&>(element).getUint32(f).good()) 774 if (dynamic_cast<DcmUnsignedLong&>(element).getUint32(f).good())
750 {
751 return new DicomString(boost::lexical_cast<std::string>(f)); 775 return new DicomString(boost::lexical_cast<std::string>(f));
752 }
753 else 776 else
754 {
755 return new DicomNullValue(); 777 return new DicomNullValue();
756 }
757 } 778 }
758 779
759 case EVR_US: // unsigned short 780 case EVR_US: // unsigned short
760 { 781 {
761 Uint16 f; 782 Uint16 f;
762 if (dynamic_cast<DcmUnsignedShort&>(element).getUint16(f).good()) 783 if (dynamic_cast<DcmUnsignedShort&>(element).getUint16(f).good())
763 {
764 return new DicomString(boost::lexical_cast<std::string>(f)); 784 return new DicomString(boost::lexical_cast<std::string>(f));
765 }
766 else 785 else
767 {
768 return new DicomNullValue(); 786 return new DicomNullValue();
769 }
770 } 787 }
771 788
772 case EVR_FL: // float single-precision 789 case EVR_FL: // float single-precision
773 { 790 {
774 Float32 f; 791 Float32 f;
775 if (dynamic_cast<DcmFloatingPointSingle&>(element).getFloat32(f).good()) 792 if (dynamic_cast<DcmFloatingPointSingle&>(element).getFloat32(f).good())
776 {
777 return new DicomString(boost::lexical_cast<std::string>(f)); 793 return new DicomString(boost::lexical_cast<std::string>(f));
778 }
779 else 794 else
780 {
781 return new DicomNullValue(); 795 return new DicomNullValue();
782 }
783 } 796 }
784 797
785 case EVR_FD: // float double-precision 798 case EVR_FD: // float double-precision
786 { 799 {
787 Float64 f; 800 Float64 f;
788 if (dynamic_cast<DcmFloatingPointDouble&>(element).getFloat64(f).good()) 801 if (dynamic_cast<DcmFloatingPointDouble&>(element).getFloat64(f).good())
789 {
790 return new DicomString(boost::lexical_cast<std::string>(f)); 802 return new DicomString(boost::lexical_cast<std::string>(f));
791 }
792 else 803 else
793 {
794 return new DicomNullValue(); 804 return new DicomNullValue();
795 }
796 } 805 }
797 806
798 807
799 /** 808 /**
800 * Sequence types, should never occur at this point because of 809 * Sequence types, should never occur at this point because of
839 } 848 }
840 catch (boost::bad_lexical_cast) 849 catch (boost::bad_lexical_cast)
841 { 850 {
842 return new DicomNullValue; 851 return new DicomNullValue;
843 } 852 }
853 catch (std::bad_cast)
854 {
855 return new DicomNullValue;
856 }
844 } 857 }
845 858
846 859
847 static void StoreElement(Json::Value& target, 860 static void StoreElement(Json::Value& target,
848 DcmElement& element, 861 DcmElement& element,
874 #if 0 887 #if 0
875 const std::string tagName = FromDcmtkBridge::GetName(tag); 888 const std::string tagName = FromDcmtkBridge::GetName(tag);
876 #else 889 #else
877 // This version of the code gives access to the name of the private tags 890 // This version of the code gives access to the name of the private tags
878 DcmTag tagbis(element.getTag()); 891 DcmTag tagbis(element.getTag());
879 const std::string tagName(tagbis.getTagName()); 892 const std::string tagName(tagbis.getTagName());
880 #endif 893 #endif
881 894
882 if (element.isLeaf()) 895 if (element.isLeaf())
883 { 896 {
884 Json::Value value(Json::objectValue); 897 Json::Value value(Json::objectValue);
885 value["Name"] = tagName; 898 value["Name"] = tagName;
899
900 if (tagbis.getPrivateCreator() != NULL)
901 {
902 value["PrivateCreator"] = tagbis.getPrivateCreator();
903 }
886 904
887 std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(element)); 905 std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(element));
888 if (v->IsNull()) 906 if (v->IsNull())
889 { 907 {
890 value["Type"] = "Null"; 908 value["Type"] = "Null";
1122 #if 0 1140 #if 0
1123 DcmTagKey tag(t.GetGroup(), t.GetElement()); 1141 DcmTagKey tag(t.GetGroup(), t.GetElement());
1124 const DcmDataDictionary& dict = dcmDataDict.rdlock(); 1142 const DcmDataDictionary& dict = dcmDataDict.rdlock();
1125 const DcmDictEntry* entry = dict.findEntry(tag, NULL); 1143 const DcmDictEntry* entry = dict.findEntry(tag, NULL);
1126 1144
1127 std::string s("Unknown"); 1145 std::string s(DcmTag_ERROR_TagName);
1128 if (entry != NULL) 1146 if (entry != NULL)
1129 { 1147 {
1130 s = std::string(entry->getTagName()); 1148 s = std::string(entry->getTagName());
1131 } 1149 }
1132 1150
1135 #else 1153 #else
1136 DcmTag tag(t.GetGroup(), t.GetElement()); 1154 DcmTag tag(t.GetGroup(), t.GetElement());
1137 const char* name = tag.getTagName(); 1155 const char* name = tag.getTagName();
1138 if (name == NULL) 1156 if (name == NULL)
1139 { 1157 {
1140 return "Unknown"; 1158 return DcmTag_ERROR_TagName;
1141 } 1159 }
1142 else 1160 else
1143 { 1161 {
1144 return std::string(name); 1162 return std::string(name);
1145 } 1163 }
1229 { 1247 {
1230 char uid[100]; 1248 char uid[100];
1231 1249
1232 switch (level) 1250 switch (level)
1233 { 1251 {
1252 case DicomRootLevel_Patient:
1253 {
1254 std::string uuid = Toolbox::GenerateUuid();
1255 std::string id;
1256 id.reserve(uuid.size());
1257 for (size_t i = 0; i < uuid.size() && i < 8; i++)
1258 {
1259 id.push_back(toupper(uuid[i]));
1260 }
1261
1262 return id;
1263 }
1264
1234 case DicomRootLevel_Instance: 1265 case DicomRootLevel_Instance:
1235 return dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT); 1266 return dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT);
1236 1267
1237 case DicomRootLevel_Series: 1268 case DicomRootLevel_Series:
1238 return dcmGenerateUniqueIdentifier(uid, SITE_SERIES_UID_ROOT); 1269 return dcmGenerateUniqueIdentifier(uid, SITE_SERIES_UID_ROOT);