comparison OrthancServer/ParsedDicomFile.cpp @ 971:509e146c3cb3 plugins

integration mainline->plugins
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 30 Jun 2014 13:36:01 +0200
parents e078ea944089 2fd5a163776d
children af014624dac1
comparison
equal deleted inserted replaced
955:743a75b14bef 971:509e146c3cb3
144 namespace Orthanc 144 namespace Orthanc
145 { 145 {
146 struct ParsedDicomFile::PImpl 146 struct ParsedDicomFile::PImpl
147 { 147 {
148 std::auto_ptr<DcmFileFormat> file_; 148 std::auto_ptr<DcmFileFormat> file_;
149 Encoding encoding_;
149 }; 150 };
150 151
151 152
152 // This method can only be called from the constructors! 153 // This method can only be called from the constructors!
153 void ParsedDicomFile::Setup(const char* buffer, size_t size) 154 void ParsedDicomFile::Setup(const char* buffer, size_t size)
168 169
169 throw OrthancException(ErrorCode_BadFileFormat); 170 throw OrthancException(ErrorCode_BadFileFormat);
170 } 171 }
171 pimpl_->file_->loadAllDataIntoMemory(); 172 pimpl_->file_->loadAllDataIntoMemory();
172 pimpl_->file_->transferEnd(); 173 pimpl_->file_->transferEnd();
174
175 pimpl_->encoding_ = FromDcmtkBridge::DetectEncoding(*pimpl_->file_->getDataset());
173 } 176 }
174 177
175 178
176 static void SendPathValueForDictionary(RestApiOutput& output, 179 static void SendPathValueForDictionary(RestApiOutput& output,
177 DcmItem& dicom) 180 DcmItem& dicom)
870 element == NULL) 873 element == NULL)
871 { 874 {
872 return false; 875 return false;
873 } 876 }
874 877
875 std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(*element)); 878 std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(*element, pimpl_->encoding_));
876 879
877 if (v.get() == NULL) 880 if (v.get() == NULL)
878 { 881 {
879 value = ""; 882 value = "";
880 } 883 }
883 value = v->AsString(); 886 value = v->AsString();
884 } 887 }
885 888
886 return true; 889 return true;
887 } 890 }
888
889 891
890 892
891 DicomInstanceHasher ParsedDicomFile::GetHasher() 893 DicomInstanceHasher ParsedDicomFile::GetHasher()
892 { 894 {
893 std::string patientId, studyUid, seriesUid, instanceUid; 895 std::string patientId, studyUid, seriesUid, instanceUid;
899 { 901 {
900 throw OrthancException(ErrorCode_BadFileFormat); 902 throw OrthancException(ErrorCode_BadFileFormat);
901 } 903 }
902 904
903 return DicomInstanceHasher(patientId, studyUid, seriesUid, instanceUid); 905 return DicomInstanceHasher(patientId, studyUid, seriesUid, instanceUid);
904 }
905
906
907 static void StoreElement(Json::Value& target,
908 DcmElement& element,
909 unsigned int maxStringLength);
910
911 static void StoreItem(Json::Value& target,
912 DcmItem& item,
913 unsigned int maxStringLength)
914 {
915 target = Json::Value(Json::objectValue);
916
917 for (unsigned long i = 0; i < item.card(); i++)
918 {
919 DcmElement* element = item.getElement(i);
920 StoreElement(target, *element, maxStringLength);
921 }
922 }
923
924
925 static void StoreElement(Json::Value& target,
926 DcmElement& element,
927 unsigned int maxStringLength)
928 {
929 assert(target.type() == Json::objectValue);
930
931 DicomTag tag(FromDcmtkBridge::GetTag(element));
932 const std::string formattedTag = tag.Format();
933
934 #if 0
935 const std::string tagName = FromDcmtkBridge::GetName(tag);
936 #else
937 // This version of the code gives access to the name of the private tags
938 DcmTag tagbis(element.getTag());
939 const std::string tagName(tagbis.getTagName());
940 #endif
941
942 if (element.isLeaf())
943 {
944 Json::Value value(Json::objectValue);
945 value["Name"] = tagName;
946
947 if (tagbis.getPrivateCreator() != NULL)
948 {
949 value["PrivateCreator"] = tagbis.getPrivateCreator();
950 }
951
952 std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(element));
953 if (v->IsNull())
954 {
955 value["Type"] = "Null";
956 value["Value"] = Json::nullValue;
957 }
958 else
959 {
960 std::string s = v->AsString();
961 if (maxStringLength == 0 ||
962 s.size() <= maxStringLength)
963 {
964 value["Type"] = "String";
965 value["Value"] = s;
966 }
967 else
968 {
969 value["Type"] = "TooLong";
970 value["Value"] = Json::nullValue;
971 }
972 }
973
974 target[formattedTag] = value;
975 }
976 else
977 {
978 Json::Value children(Json::arrayValue);
979
980 // "All subclasses of DcmElement except for DcmSequenceOfItems
981 // are leaf nodes, while DcmSequenceOfItems, DcmItem, DcmDataset
982 // etc. are not." The following cast is thus OK.
983 DcmSequenceOfItems& sequence = dynamic_cast<DcmSequenceOfItems&>(element);
984
985 for (unsigned long i = 0; i < sequence.card(); i++)
986 {
987 DcmItem* child = sequence.getItem(i);
988 Json::Value& v = children.append(Json::objectValue);
989 StoreItem(v, *child, maxStringLength);
990 }
991
992 target[formattedTag]["Name"] = tagName;
993 target[formattedTag]["Type"] = "Sequence";
994 target[formattedTag]["Value"] = children;
995 }
996 } 906 }
997 907
998 908
999 template <typename T> 909 template <typename T>
1000 static void ExtractPngImageTruncate(std::string& result, 910 static void ExtractPngImageTruncate(std::string& result,
1042 952
1043 953
1044 ParsedDicomFile::ParsedDicomFile() : pimpl_(new PImpl) 954 ParsedDicomFile::ParsedDicomFile() : pimpl_(new PImpl)
1045 { 955 {
1046 pimpl_->file_.reset(new DcmFileFormat); 956 pimpl_->file_.reset(new DcmFileFormat);
957 pimpl_->encoding_ = Encoding_Ascii;
1047 Replace(DICOM_TAG_PATIENT_ID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Patient)); 958 Replace(DICOM_TAG_PATIENT_ID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Patient));
1048 Replace(DICOM_TAG_STUDY_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Study)); 959 Replace(DICOM_TAG_STUDY_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Study));
1049 Replace(DICOM_TAG_SERIES_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series)); 960 Replace(DICOM_TAG_SERIES_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series));
1050 Replace(DICOM_TAG_SOP_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Instance)); 961 Replace(DICOM_TAG_SOP_INSTANCE_UID, FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Instance));
1051 } 962 }
1071 982
1072 ParsedDicomFile::ParsedDicomFile(ParsedDicomFile& other) : 983 ParsedDicomFile::ParsedDicomFile(ParsedDicomFile& other) :
1073 pimpl_(new PImpl) 984 pimpl_(new PImpl)
1074 { 985 {
1075 pimpl_->file_.reset(dynamic_cast<DcmFileFormat*>(other.pimpl_->file_->clone())); 986 pimpl_->file_.reset(dynamic_cast<DcmFileFormat*>(other.pimpl_->file_->clone()));
987
988 pimpl_->encoding_ = other.pimpl_->encoding_;
1076 } 989 }
1077 990
1078 991
1079 ParsedDicomFile::~ParsedDicomFile() 992 ParsedDicomFile::~ParsedDicomFile()
1080 { 993 {
1277 ImageAccessor accessor(buffer.GetConstAccessor()); 1190 ImageAccessor accessor(buffer.GetConstAccessor());
1278 PngWriter writer; 1191 PngWriter writer;
1279 writer.WriteToMemory(result, accessor); 1192 writer.WriteToMemory(result, accessor);
1280 } 1193 }
1281 1194
1195
1196 Encoding ParsedDicomFile::GetEncoding() const
1197 {
1198 return pimpl_->encoding_;
1199 }
1282 } 1200 }