Mercurial > hg > orthanc
comparison Core/DicomParsing/ParsedDicomFile.cpp @ 2445:6e5bc5c6d1a4
Fix to allow creating DICOM instances with empty Specific Character Set (0008,0005)
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 14 Dec 2017 13:02:06 +0100 |
parents | e4045b3c9772 |
children | 878b59270859 |
comparison
equal
deleted
inserted
replaced
2444:d9e3781d2023 | 2445:6e5bc5c6d1a4 |
---|---|
37 This file is based on portions of the following project: | 37 This file is based on portions of the following project: |
38 | 38 |
39 Program: GDCM (Grassroots DICOM). A DICOM library | 39 Program: GDCM (Grassroots DICOM). A DICOM library |
40 Module: http://gdcm.sourceforge.net/Copyright.html | 40 Module: http://gdcm.sourceforge.net/Copyright.html |
41 | 41 |
42 Copyright (c) 2006-2011 Mathieu Malaterre | 42 Copyright (c) 2006-2011 Mathieu Malaterre |
43 Copyright (c) 1993-2005 CREATIS | 43 Copyright (c) 1993-2005 CREATIS |
44 (CREATIS = Centre de Recherche et d'Applications en Traitement de l'Image) | 44 (CREATIS = Centre de Recherche et d'Applications en Traitement de l'Image) |
45 All rights reserved. | 45 All rights reserved. |
46 | 46 |
47 Redistribution and use in source and binary forms, with or without | 47 Redistribution and use in source and binary forms, with or without |
48 modification, are permitted provided that the following conditions are met: | 48 modification, are permitted provided that the following conditions are met: |
49 | 49 |
50 * Redistributions of source code must retain the above copyright notice, | 50 * Redistributions of source code must retain the above copyright notice, |
51 this list of conditions and the following disclaimer. | 51 this list of conditions and the following disclaimer. |
52 | 52 |
53 * Redistributions in binary form must reproduce the above copyright notice, | 53 * Redistributions in binary form must reproduce the above copyright notice, |
54 this list of conditions and the following disclaimer in the documentation | 54 this list of conditions and the following disclaimer in the documentation |
55 and/or other materials provided with the distribution. | 55 and/or other materials provided with the distribution. |
56 | 56 |
57 * Neither name of Mathieu Malaterre, or CREATIS, nor the names of any | 57 * Neither name of Mathieu Malaterre, or CREATIS, nor the names of any |
58 contributors (CNRS, INSERM, UCB, Universite Lyon I), may be used to | 58 contributors (CNRS, INSERM, UCB, Universite Lyon I), may be used to |
59 endorse or promote products derived from this software without specific | 59 endorse or promote products derived from this software without specific |
60 prior written permission. | 60 prior written permission. |
61 | 61 |
62 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' | 62 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' |
63 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 63 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
64 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 64 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
65 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR | 65 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR |
66 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 66 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
67 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 67 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
68 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 68 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
69 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | 69 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
70 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 70 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
71 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 71 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
72 | 72 |
73 =========================================================================*/ | 73 =========================================================================*/ |
74 | 74 |
75 | 75 |
76 #include "../PrecompiledHeaders.h" | 76 #include "../PrecompiledHeaders.h" |
77 | 77 |
78 #ifndef NOMINMAX | 78 #ifndef NOMINMAX |
909 | 909 |
910 | 910 |
911 void ParsedDicomFile::CreateFromDicomMap(const DicomMap& source, | 911 void ParsedDicomFile::CreateFromDicomMap(const DicomMap& source, |
912 Encoding defaultEncoding) | 912 Encoding defaultEncoding) |
913 { | 913 { |
914 pimpl_->file_.reset(new DcmFileFormat); | 914 try |
915 | 915 { |
916 const DicomValue* tmp = source.TestAndGetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET); | 916 pimpl_->file_.reset(new DcmFileFormat); |
917 if (tmp != NULL) | 917 |
918 { | 918 const DicomValue* tmp = source.TestAndGetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET); |
919 Encoding encoding; | 919 |
920 if (tmp->IsNull() || | 920 if (tmp == NULL) |
921 tmp->IsBinary() || | 921 { |
922 !GetDicomEncoding(encoding, tmp->GetContent().c_str())) | 922 SetEncoding(defaultEncoding); |
923 { | 923 } |
924 else if (tmp->IsBinary()) | |
925 { | |
926 LOG(ERROR) << "Invalid binary string in the SpecificCharacterSet (0008,0005) tag"; | |
924 throw OrthancException(ErrorCode_ParameterOutOfRange); | 927 throw OrthancException(ErrorCode_ParameterOutOfRange); |
925 } | 928 } |
929 else if (tmp->IsNull() || | |
930 tmp->GetContent().empty()) | |
931 { | |
932 SetEncoding(defaultEncoding); | |
933 } | |
926 else | 934 else |
927 { | 935 { |
928 SetEncoding(encoding); | 936 Encoding encoding; |
929 } | 937 |
930 } | 938 if (GetDicomEncoding(encoding, tmp->GetContent().c_str())) |
931 else | 939 { |
932 { | 940 SetEncoding(encoding); |
933 SetEncoding(defaultEncoding); | 941 } |
934 } | 942 else |
935 | 943 { |
936 for (DicomMap::Map::const_iterator | 944 LOG(ERROR) << "Unsupported value for the SpecificCharacterSet (0008,0005) tag: \"" |
937 it = source.map_.begin(); it != source.map_.end(); ++it) | 945 << tmp->GetContent() << "\""; |
938 { | 946 throw OrthancException(ErrorCode_ParameterOutOfRange); |
939 if (it->first != DICOM_TAG_SPECIFIC_CHARACTER_SET && | 947 } |
940 !it->second->IsNull()) | 948 } |
941 { | 949 |
942 ReplacePlainString(it->first, it->second->GetContent()); | 950 for (DicomMap::Map::const_iterator |
943 } | 951 it = source.map_.begin(); it != source.map_.end(); ++it) |
952 { | |
953 if (it->first != DICOM_TAG_SPECIFIC_CHARACTER_SET && | |
954 !it->second->IsNull()) | |
955 { | |
956 ReplacePlainString(it->first, it->second->GetContent()); | |
957 } | |
958 } | |
959 } | |
960 catch (OrthancException&) | |
961 { | |
962 // Manually delete the PImpl to avoid a memory leak due to | |
963 // throwing the exception in the constructor | |
964 delete pimpl_; | |
965 pimpl_ = NULL; | |
966 throw; | |
944 } | 967 } |
945 } | 968 } |
946 | 969 |
947 | 970 |
948 ParsedDicomFile::ParsedDicomFile(const DicomMap& map, | 971 ParsedDicomFile::ParsedDicomFile(const DicomMap& map, |
1068 throw OrthancException(ErrorCode_BadFileFormat); | 1091 throw OrthancException(ErrorCode_BadFileFormat); |
1069 } | 1092 } |
1070 } | 1093 } |
1071 | 1094 |
1072 | 1095 |
1073 #if (ORTHANC_ENABLE_JPEG == 1 && \ | 1096 #if (ORTHANC_ENABLE_JPEG == 1 && \ |
1074 ORTHANC_ENABLE_PNG == 1) | 1097 ORTHANC_ENABLE_PNG == 1) |
1075 void ParsedDicomFile::EmbedImage(const std::string& mime, | 1098 void ParsedDicomFile::EmbedImage(const std::string& mime, |
1076 const std::string& content) | 1099 const std::string& content) |
1077 { | 1100 { |
1078 if (mime == "image/png") | 1101 if (mime == "image/png") |
1375 | 1398 |
1376 | 1399 |
1377 ParsedDicomFile* ParsedDicomFile::CreateFromJson(const Json::Value& json, | 1400 ParsedDicomFile* ParsedDicomFile::CreateFromJson(const Json::Value& json, |
1378 DicomFromJsonFlags flags) | 1401 DicomFromJsonFlags flags) |
1379 { | 1402 { |
1380 const bool generateIdentifiers = (flags & DicomFromJsonFlags_GenerateIdentifiers) ? true : false; | 1403 const bool generateIdentifiers = (flags & DicomFromJsonFlags_GenerateIdentifiers) ? true : false; |
1381 const bool decodeDataUriScheme = (flags & DicomFromJsonFlags_DecodeDataUriScheme) ? true : false; | 1404 const bool decodeDataUriScheme = (flags & DicomFromJsonFlags_DecodeDataUriScheme) ? true : false; |
1382 | 1405 |
1383 std::auto_ptr<ParsedDicomFile> result(new ParsedDicomFile(generateIdentifiers)); | 1406 std::auto_ptr<ParsedDicomFile> result(new ParsedDicomFile(generateIdentifiers)); |
1384 result->SetEncoding(FromDcmtkBridge::ExtractEncoding(json, GetDefaultDicomEncoding())); | 1407 result->SetEncoding(FromDcmtkBridge::ExtractEncoding(json, GetDefaultDicomEncoding())); |
1385 | 1408 |
1386 const Json::Value::Members tags = json.getMemberNames(); | 1409 const Json::Value::Members tags = json.getMemberNames(); |