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();