Mercurial > hg > orthanc
annotate OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.cpp @ 4792:434843934307 storage-cache
Added a StorageCache in the StorageAccessor
author | Alain Mazy <am@osimis.io> |
---|---|
date | Thu, 30 Sep 2021 12:14:19 +0200 |
parents | 979ae3ea3381 |
children | 7053502fbf97 |
rev | line source |
---|---|
3202 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
4437
d9473bd5ed43
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4304
diff
changeset
|
5 * Copyright (C) 2017-2021 Osimis S.A., Belgium |
3202 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
4119
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
8 * modify it under the terms of the GNU Lesser General Public License |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
9 * as published by the Free Software Foundation, either version 3 of |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
10 * the License, or (at your option) any later version. |
3202 | 11 * |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
4119
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
15 * Lesser General Public License for more details. |
3202 | 16 * |
4119
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
18 * License along with this program. If not, see |
bf7b9edf6b81
re-licensing the OrthancFramework to LGPL, in order to license Stone of Orthanc under LGPL
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4044
diff
changeset
|
19 * <http://www.gnu.org/licenses/>. |
3202 | 20 **/ |
21 | |
22 | |
23 #include "../PrecompiledHeaders.h" | |
24 #include "DicomWebJsonVisitor.h" | |
25 | |
4304 | 26 #include "../Logging.h" |
3202 | 27 #include "../OrthancException.h" |
28 #include "../Toolbox.h" | |
29 #include "FromDcmtkBridge.h" | |
30 | |
31 #include <boost/math/special_functions/round.hpp> | |
32 #include <boost/lexical_cast.hpp> | |
33 | |
34 | |
35 static const char* const KEY_ALPHABETIC = "Alphabetic"; | |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
36 static const char* const KEY_IDEOGRAPHIC = "Ideographic"; |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
37 static const char* const KEY_PHONETIC = "Phonetic"; |
4655
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
38 static const char* const KEY_BULK_DATA = "BulkData"; |
3202 | 39 static const char* const KEY_BULK_DATA_URI = "BulkDataURI"; |
40 static const char* const KEY_INLINE_BINARY = "InlineBinary"; | |
41 static const char* const KEY_SQ = "SQ"; | |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
42 static const char* const KEY_TAG = "tag"; |
3202 | 43 static const char* const KEY_VALUE = "Value"; |
44 static const char* const KEY_VR = "vr"; | |
4655
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
45 static const char* const KEY_NUMBER = "number"; |
3202 | 46 |
47 | |
48 namespace Orthanc | |
49 { | |
50 #if ORTHANC_ENABLE_PUGIXML == 1 | |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
51 static void DecomposeXmlPersonName(pugi::xml_node& target, |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
52 const std::string& source) |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
53 { |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
54 std::vector<std::string> tokens; |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
55 Toolbox::TokenizeString(tokens, source, '^'); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
56 |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
57 if (tokens.size() >= 1) |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
58 { |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
59 target.append_child("FamilyName").text() = tokens[0].c_str(); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
60 } |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
61 |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
62 if (tokens.size() >= 2) |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
63 { |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
64 target.append_child("GivenName").text() = tokens[1].c_str(); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
65 } |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
66 |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
67 if (tokens.size() >= 3) |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
68 { |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
69 target.append_child("MiddleName").text() = tokens[2].c_str(); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
70 } |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
71 |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
72 if (tokens.size() >= 4) |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
73 { |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
74 target.append_child("NamePrefix").text() = tokens[3].c_str(); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
75 } |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
76 |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
77 if (tokens.size() >= 5) |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
78 { |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
79 target.append_child("NameSuffix").text() = tokens[4].c_str(); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
80 } |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
81 } |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
82 |
3202 | 83 static void ExploreXmlDataset(pugi::xml_node& target, |
84 const Json::Value& source) | |
85 { | |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
86 // http://dicom.nema.org/medical/dicom/current/output/chtml/part18/sect_F.3.html#table_F.3.1-1 |
3202 | 87 assert(source.type() == Json::objectValue); |
88 | |
89 Json::Value::Members members = source.getMemberNames(); | |
90 for (size_t i = 0; i < members.size(); i++) | |
91 { | |
92 const DicomTag tag = FromDcmtkBridge::ParseTag(members[i]); | |
93 const Json::Value& content = source[members[i]]; | |
94 | |
95 assert(content.type() == Json::objectValue && | |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
96 content.isMember(KEY_VR) && |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
97 content[KEY_VR].type() == Json::stringValue); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
98 const std::string vr = content[KEY_VR].asString(); |
3202 | 99 |
100 const std::string keyword = FromDcmtkBridge::GetTagName(tag, ""); | |
101 | |
102 pugi::xml_node node = target.append_child("DicomAttribute"); | |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
103 node.append_attribute(KEY_TAG).set_value(members[i].c_str()); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
104 node.append_attribute(KEY_VR).set_value(vr.c_str()); |
3202 | 105 |
106 if (keyword != std::string(DcmTag_ERROR_TagName)) | |
107 { | |
108 node.append_attribute("keyword").set_value(keyword.c_str()); | |
109 } | |
110 | |
111 if (content.isMember(KEY_VALUE)) | |
112 { | |
113 assert(content[KEY_VALUE].type() == Json::arrayValue); | |
114 | |
115 for (Json::Value::ArrayIndex j = 0; j < content[KEY_VALUE].size(); j++) | |
116 { | |
117 std::string number = boost::lexical_cast<std::string>(j + 1); | |
118 | |
119 if (vr == "SQ") | |
120 { | |
121 if (content[KEY_VALUE][j].type() == Json::objectValue) | |
122 { | |
123 pugi::xml_node child = node.append_child("Item"); | |
4655
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
124 child.append_attribute(KEY_NUMBER).set_value(number.c_str()); |
3202 | 125 ExploreXmlDataset(child, content[KEY_VALUE][j]); |
126 } | |
127 } | |
128 if (vr == "PN") | |
129 { | |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
130 bool hasAlphabetic = (content[KEY_VALUE][j].isMember(KEY_ALPHABETIC) && |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
131 content[KEY_VALUE][j][KEY_ALPHABETIC].type() == Json::stringValue); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
132 |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
133 bool hasIdeographic = (content[KEY_VALUE][j].isMember(KEY_IDEOGRAPHIC) && |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
134 content[KEY_VALUE][j][KEY_IDEOGRAPHIC].type() == Json::stringValue); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
135 |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
136 bool hasPhonetic = (content[KEY_VALUE][j].isMember(KEY_PHONETIC) && |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
137 content[KEY_VALUE][j][KEY_PHONETIC].type() == Json::stringValue); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
138 |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
139 if (hasAlphabetic || |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
140 hasIdeographic || |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
141 hasPhonetic) |
3202 | 142 { |
143 pugi::xml_node child = node.append_child("PersonName"); | |
4655
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
144 child.append_attribute(KEY_NUMBER).set_value(number.c_str()); |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
145 |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
146 if (hasAlphabetic) |
3202 | 147 { |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
148 pugi::xml_node name = child.append_child(KEY_ALPHABETIC); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
149 DecomposeXmlPersonName(name, content[KEY_VALUE][j][KEY_ALPHABETIC].asString()); |
3202 | 150 } |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
151 |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
152 if (hasIdeographic) |
3202 | 153 { |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
154 pugi::xml_node name = child.append_child(KEY_IDEOGRAPHIC); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
155 DecomposeXmlPersonName(name, content[KEY_VALUE][j][KEY_IDEOGRAPHIC].asString()); |
3202 | 156 } |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
157 |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
158 if (hasPhonetic) |
3202 | 159 { |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
160 pugi::xml_node name = child.append_child(KEY_PHONETIC); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
161 DecomposeXmlPersonName(name, content[KEY_VALUE][j][KEY_PHONETIC].asString()); |
3202 | 162 } |
163 } | |
164 } | |
165 else | |
166 { | |
4655
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
167 pugi::xml_node child = node.append_child(KEY_VALUE); |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
168 child.append_attribute(KEY_NUMBER).set_value(number.c_str()); |
3202 | 169 |
170 switch (content[KEY_VALUE][j].type()) | |
171 { | |
172 case Json::stringValue: | |
173 child.text() = content[KEY_VALUE][j].asCString(); | |
174 break; | |
175 | |
176 case Json::realValue: | |
177 child.text() = content[KEY_VALUE][j].asFloat(); | |
178 break; | |
179 | |
180 case Json::intValue: | |
181 child.text() = content[KEY_VALUE][j].asInt(); | |
182 break; | |
183 | |
184 case Json::uintValue: | |
185 child.text() = content[KEY_VALUE][j].asUInt(); | |
186 break; | |
187 | |
188 default: | |
189 break; | |
190 } | |
191 } | |
192 } | |
193 } | |
194 else if (content.isMember(KEY_BULK_DATA_URI) && | |
195 content[KEY_BULK_DATA_URI].type() == Json::stringValue) | |
196 { | |
4655
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
197 pugi::xml_node child = node.append_child(KEY_BULK_DATA); |
3202 | 198 child.append_attribute("URI").set_value(content[KEY_BULK_DATA_URI].asCString()); |
199 } | |
200 else if (content.isMember(KEY_INLINE_BINARY) && | |
201 content[KEY_INLINE_BINARY].type() == Json::stringValue) | |
202 { | |
4655
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
203 pugi::xml_node child = node.append_child(KEY_INLINE_BINARY); |
3202 | 204 child.text() = content[KEY_INLINE_BINARY].asCString(); |
205 } | |
206 } | |
207 } | |
208 #endif | |
209 | |
210 | |
211 #if ORTHANC_ENABLE_PUGIXML == 1 | |
212 static void DicomWebJsonToXml(pugi::xml_document& target, | |
213 const Json::Value& source) | |
214 { | |
215 pugi::xml_node root = target.append_child("NativeDicomModel"); | |
216 root.append_attribute("xmlns").set_value("http://dicom.nema.org/PS3.19/models/NativeDICOM"); | |
217 root.append_attribute("xsi:schemaLocation").set_value("http://dicom.nema.org/PS3.19/models/NativeDICOM"); | |
218 root.append_attribute("xmlns:xsi").set_value("http://www.w3.org/2001/XMLSchema-instance"); | |
219 | |
220 ExploreXmlDataset(root, source); | |
221 | |
222 pugi::xml_node decl = target.prepend_child(pugi::node_declaration); | |
223 decl.append_attribute("version").set_value("1.0"); | |
224 decl.append_attribute("encoding").set_value("utf-8"); | |
225 } | |
226 #endif | |
227 | |
228 | |
229 std::string DicomWebJsonVisitor::FormatTag(const DicomTag& tag) | |
230 { | |
231 char buf[16]; | |
232 sprintf(buf, "%04X%04X", tag.GetGroup(), tag.GetElement()); | |
233 return std::string(buf); | |
234 } | |
235 | |
236 | |
237 Json::Value& DicomWebJsonVisitor::CreateNode(const std::vector<DicomTag>& parentTags, | |
238 const std::vector<size_t>& parentIndexes, | |
239 const DicomTag& tag) | |
240 { | |
241 assert(parentTags.size() == parentIndexes.size()); | |
242 | |
243 Json::Value* node = &result_; | |
244 | |
245 for (size_t i = 0; i < parentTags.size(); i++) | |
246 { | |
247 std::string t = FormatTag(parentTags[i]); | |
248 | |
249 if (!node->isMember(t)) | |
250 { | |
251 Json::Value item = Json::objectValue; | |
252 item[KEY_VR] = KEY_SQ; | |
253 item[KEY_VALUE] = Json::arrayValue; | |
254 item[KEY_VALUE].append(Json::objectValue); | |
255 (*node) [t] = item; | |
256 | |
257 node = &(*node)[t][KEY_VALUE][0]; | |
258 } | |
259 else if ((*node) [t].type() != Json::objectValue || | |
260 !(*node) [t].isMember(KEY_VR) || | |
261 (*node) [t][KEY_VR].type() != Json::stringValue || | |
262 (*node) [t][KEY_VR].asString() != KEY_SQ || | |
263 !(*node) [t].isMember(KEY_VALUE) || | |
264 (*node) [t][KEY_VALUE].type() != Json::arrayValue) | |
265 { | |
266 throw OrthancException(ErrorCode_InternalError); | |
267 } | |
268 else | |
269 { | |
270 size_t currentSize = (*node) [t][KEY_VALUE].size(); | |
271 | |
272 if (parentIndexes[i] < currentSize) | |
273 { | |
274 // The node already exists | |
275 } | |
276 else if (parentIndexes[i] == currentSize) | |
277 { | |
278 (*node) [t][KEY_VALUE].append(Json::objectValue); | |
279 } | |
280 else | |
281 { | |
282 throw OrthancException(ErrorCode_InternalError); | |
283 } | |
284 | |
285 node = &(*node) [t][KEY_VALUE][Json::ArrayIndex(parentIndexes[i])]; | |
286 } | |
287 } | |
288 | |
289 assert(node->type() == Json::objectValue); | |
290 | |
291 std::string t = FormatTag(tag); | |
292 if (node->isMember(t)) | |
293 { | |
294 throw OrthancException(ErrorCode_InternalError); | |
295 } | |
296 else | |
297 { | |
298 (*node) [t] = Json::objectValue; | |
299 return (*node) [t]; | |
300 } | |
301 } | |
302 | |
303 | |
304 Json::Value DicomWebJsonVisitor::FormatInteger(int64_t value) | |
305 { | |
306 if (value < 0) | |
307 { | |
308 return Json::Value(static_cast<int32_t>(value)); | |
309 } | |
310 else | |
311 { | |
312 return Json::Value(static_cast<uint32_t>(value)); | |
313 } | |
314 } | |
315 | |
316 | |
317 Json::Value DicomWebJsonVisitor::FormatDouble(double value) | |
318 { | |
3312 | 319 try |
320 { | |
321 long long a = boost::math::llround<double>(value); | |
3202 | 322 |
3312 | 323 double d = fabs(value - static_cast<double>(a)); |
3202 | 324 |
3312 | 325 if (d <= std::numeric_limits<double>::epsilon() * 100.0) |
326 { | |
327 return FormatInteger(a); | |
328 } | |
329 else | |
330 { | |
331 return Json::Value(value); | |
332 } | |
333 } | |
334 catch (boost::math::rounding_error&) | |
3202 | 335 { |
3312 | 336 // Can occur if "long long" is too small to receive this value |
337 // (e.g. infinity) | |
3202 | 338 return Json::Value(value); |
339 } | |
340 } | |
341 | |
4297 | 342 DicomWebJsonVisitor::DicomWebJsonVisitor() : |
343 formatter_(NULL) | |
344 { | |
345 Clear(); | |
346 } | |
347 | |
348 void DicomWebJsonVisitor::SetFormatter(DicomWebJsonVisitor::IBinaryFormatter &formatter) | |
349 { | |
350 formatter_ = &formatter; | |
351 } | |
352 | |
353 void DicomWebJsonVisitor::Clear() | |
354 { | |
355 result_ = Json::objectValue; | |
356 } | |
357 | |
358 const Json::Value &DicomWebJsonVisitor::GetResult() const | |
359 { | |
360 return result_; | |
361 } | |
362 | |
3202 | 363 |
364 #if ORTHANC_ENABLE_PUGIXML == 1 | |
3203
810772486249
URI "/instances/.../file" can return DICOMweb JSON or XML, depending on Accept header
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3202
diff
changeset
|
365 void DicomWebJsonVisitor::FormatXml(std::string& target) const |
3202 | 366 { |
3203
810772486249
URI "/instances/.../file" can return DICOMweb JSON or XML, depending on Accept header
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3202
diff
changeset
|
367 pugi::xml_document doc; |
810772486249
URI "/instances/.../file" can return DICOMweb JSON or XML, depending on Accept header
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3202
diff
changeset
|
368 DicomWebJsonToXml(doc, result_); |
810772486249
URI "/instances/.../file" can return DICOMweb JSON or XML, depending on Accept header
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3202
diff
changeset
|
369 Toolbox::XmlToString(target, doc); |
3202 | 370 } |
371 #endif | |
372 | |
373 | |
4734
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
374 ITagVisitor::Action |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
375 DicomWebJsonVisitor::VisitNotSupported(const std::vector<DicomTag> &parentTags, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
376 const std::vector<size_t> &parentIndexes, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
377 const DicomTag &tag, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
378 ValueRepresentation vr) |
4297 | 379 { |
4734
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
380 return Action_None; |
4297 | 381 } |
382 | |
383 | |
4734
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
384 ITagVisitor::Action |
4737
979ae3ea3381
DANGEROUS commit: Anonymization is now also applied to nested sequences
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4734
diff
changeset
|
385 DicomWebJsonVisitor::VisitSequence(const std::vector<DicomTag>& parentTags, |
979ae3ea3381
DANGEROUS commit: Anonymization is now also applied to nested sequences
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4734
diff
changeset
|
386 const std::vector<size_t>& parentIndexes, |
979ae3ea3381
DANGEROUS commit: Anonymization is now also applied to nested sequences
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4734
diff
changeset
|
387 const DicomTag& tag, |
979ae3ea3381
DANGEROUS commit: Anonymization is now also applied to nested sequences
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4734
diff
changeset
|
388 size_t countItems) |
3202 | 389 { |
4737
979ae3ea3381
DANGEROUS commit: Anonymization is now also applied to nested sequences
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4734
diff
changeset
|
390 if (countItems == 0 && |
979ae3ea3381
DANGEROUS commit: Anonymization is now also applied to nested sequences
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4734
diff
changeset
|
391 tag.GetElement() != 0x0000) |
3202 | 392 { |
393 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); | |
394 node[KEY_VR] = EnumerationToString(ValueRepresentation_Sequence); | |
395 } | |
4734
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
396 |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
397 return Action_None; |
3202 | 398 } |
399 | |
400 | |
4734
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
401 ITagVisitor::Action |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
402 DicomWebJsonVisitor::VisitBinary(const std::vector<DicomTag>& parentTags, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
403 const std::vector<size_t>& parentIndexes, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
404 const DicomTag& tag, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
405 ValueRepresentation vr, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
406 const void* data, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
407 size_t size) |
3202 | 408 { |
409 assert(vr == ValueRepresentation_OtherByte || | |
410 vr == ValueRepresentation_OtherDouble || | |
411 vr == ValueRepresentation_OtherFloat || | |
412 vr == ValueRepresentation_OtherLong || | |
413 vr == ValueRepresentation_OtherWord || | |
414 vr == ValueRepresentation_Unknown); | |
415 | |
416 if (tag.GetElement() != 0x0000) | |
417 { | |
418 BinaryMode mode; | |
419 std::string bulkDataUri; | |
420 | |
421 if (formatter_ == NULL) | |
422 { | |
423 mode = BinaryMode_InlineBinary; | |
424 } | |
425 else | |
426 { | |
427 mode = formatter_->Format(bulkDataUri, parentTags, parentIndexes, tag, vr); | |
428 } | |
429 | |
430 if (mode != BinaryMode_Ignore) | |
431 { | |
432 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); | |
433 node[KEY_VR] = EnumerationToString(vr); | |
434 | |
4655
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
435 /** |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
436 * The test on "size > 0" is new in Orthanc 1.9.3, and fixes |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
437 * issue #195 (No need for BulkDataURI when Data Element is |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
438 * empty): https://bugs.orthanc-server.com/show_bug.cgi?id=195 |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
439 **/ |
4660
4e81412ead0a
in DICOMweb JSON, BulkDataURI is forced for sequences and pixel data
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4655
diff
changeset
|
440 if (size > 0 || |
4e81412ead0a
in DICOMweb JSON, BulkDataURI is forced for sequences and pixel data
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4655
diff
changeset
|
441 tag == DICOM_TAG_PIXEL_DATA || |
4e81412ead0a
in DICOMweb JSON, BulkDataURI is forced for sequences and pixel data
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4655
diff
changeset
|
442 vr == ValueRepresentation_Sequence /* new in Orthanc 1.9.4 */) |
3202 | 443 { |
4655
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
444 switch (mode) |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
445 { |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
446 case BinaryMode_BulkDataUri: |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
447 node[KEY_BULK_DATA_URI] = bulkDataUri; |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
448 break; |
3202 | 449 |
4655
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
450 case BinaryMode_InlineBinary: |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
451 { |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
452 std::string tmp(static_cast<const char*>(data), size); |
3202 | 453 |
4655
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
454 std::string base64; |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
455 Toolbox::EncodeBase64(base64, tmp); |
3202 | 456 |
4655
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
457 node[KEY_INLINE_BINARY] = base64; |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
458 break; |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
459 } |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
460 |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
461 default: |
9f7eef20bc7d
Fix issue #195 (No need for BulkDataURI when Data Element is empty)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4437
diff
changeset
|
462 throw OrthancException(ErrorCode_ParameterOutOfRange); |
3202 | 463 } |
464 } | |
465 } | |
466 } | |
4734
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
467 |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
468 return Action_None; |
3202 | 469 } |
470 | |
471 | |
4734
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
472 ITagVisitor::Action |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
473 DicomWebJsonVisitor::VisitIntegers(const std::vector<DicomTag>& parentTags, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
474 const std::vector<size_t>& parentIndexes, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
475 const DicomTag& tag, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
476 ValueRepresentation vr, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
477 const std::vector<int64_t>& values) |
3202 | 478 { |
479 if (tag.GetElement() != 0x0000 && | |
480 vr != ValueRepresentation_NotSupported) | |
481 { | |
482 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); | |
483 node[KEY_VR] = EnumerationToString(vr); | |
484 | |
485 if (!values.empty()) | |
486 { | |
487 Json::Value content = Json::arrayValue; | |
488 for (size_t i = 0; i < values.size(); i++) | |
489 { | |
490 content.append(FormatInteger(values[i])); | |
491 } | |
492 | |
493 node[KEY_VALUE] = content; | |
494 } | |
495 } | |
4734
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
496 |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
497 return Action_None; |
3202 | 498 } |
499 | |
4734
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
500 ITagVisitor::Action |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
501 DicomWebJsonVisitor::VisitDoubles(const std::vector<DicomTag>& parentTags, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
502 const std::vector<size_t>& parentIndexes, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
503 const DicomTag& tag, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
504 ValueRepresentation vr, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
505 const std::vector<double>& values) |
3202 | 506 { |
507 if (tag.GetElement() != 0x0000 && | |
508 vr != ValueRepresentation_NotSupported) | |
509 { | |
510 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); | |
511 node[KEY_VR] = EnumerationToString(vr); | |
512 | |
513 if (!values.empty()) | |
514 { | |
515 Json::Value content = Json::arrayValue; | |
516 for (size_t i = 0; i < values.size(); i++) | |
517 { | |
518 content.append(FormatDouble(values[i])); | |
519 } | |
520 | |
521 node[KEY_VALUE] = content; | |
522 } | |
523 } | |
4734
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
524 |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
525 return Action_None; |
3202 | 526 } |
527 | |
528 | |
4734
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
529 ITagVisitor::Action |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
530 DicomWebJsonVisitor::VisitAttributes(const std::vector<DicomTag>& parentTags, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
531 const std::vector<size_t>& parentIndexes, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
532 const DicomTag& tag, |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
533 const std::vector<DicomTag>& values) |
3202 | 534 { |
535 if (tag.GetElement() != 0x0000) | |
536 { | |
537 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); | |
538 node[KEY_VR] = EnumerationToString(ValueRepresentation_AttributeTag); | |
539 | |
540 if (!values.empty()) | |
541 { | |
542 Json::Value content = Json::arrayValue; | |
543 for (size_t i = 0; i < values.size(); i++) | |
544 { | |
545 content.append(FormatTag(values[i])); | |
546 } | |
547 | |
548 node[KEY_VALUE] = content; | |
549 } | |
550 } | |
4734
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
551 |
b51c08bd5c38
added ITagVisitor::Action_Remove
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4660
diff
changeset
|
552 return Action_None; |
3202 | 553 } |
554 | |
555 | |
556 ITagVisitor::Action | |
557 DicomWebJsonVisitor::VisitString(std::string& newValue, | |
558 const std::vector<DicomTag>& parentTags, | |
559 const std::vector<size_t>& parentIndexes, | |
560 const DicomTag& tag, | |
561 ValueRepresentation vr, | |
562 const std::string& value) | |
563 { | |
564 if (tag.GetElement() == 0x0000 || | |
565 vr == ValueRepresentation_NotSupported) | |
566 { | |
567 return Action_None; | |
568 } | |
569 else | |
570 { | |
571 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); | |
572 node[KEY_VR] = EnumerationToString(vr); | |
573 | |
3420
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
574 #if 0 |
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
575 /** |
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
576 * TODO - The JSON file has an UTF-8 encoding, thus DCMTK |
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
577 * replaces the specific character set with "ISO_IR 192" |
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
578 * (UNICODE UTF-8). On Google Cloud Healthcare, however, the |
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
579 * source encoding is reported, which seems more logical. We |
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
580 * thus choose the Google convention. Enabling this block will |
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
581 * mimic the DCMTK behavior. |
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
582 **/ |
3202 | 583 if (tag == DICOM_TAG_SPECIFIC_CHARACTER_SET) |
584 { | |
585 node[KEY_VALUE].append("ISO_IR 192"); | |
586 } | |
587 else | |
3420
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
588 #endif |
3202 | 589 { |
590 std::string truncated; | |
591 | |
592 if (!value.empty() && | |
593 value[value.size() - 1] == '\0') | |
594 { | |
595 truncated = value.substr(0, value.size() - 1); | |
596 } | |
597 else | |
598 { | |
599 truncated = value; | |
600 } | |
3420
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
601 |
3202 | 602 if (!truncated.empty()) |
603 { | |
604 std::vector<std::string> tokens; | |
605 Toolbox::TokenizeString(tokens, truncated, '\\'); | |
606 | |
3420
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
607 if (tag == DICOM_TAG_SPECIFIC_CHARACTER_SET && |
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
608 tokens.size() > 1 && |
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
609 tokens[0].empty()) |
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
610 { |
3448
b3bdd6dc10f2
don't change encoding of SpecificCharacterSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3420
diff
changeset
|
611 // Specific character set with code extension: Remove the |
b3bdd6dc10f2
don't change encoding of SpecificCharacterSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3420
diff
changeset
|
612 // first element from the vector of encodings |
b3bdd6dc10f2
don't change encoding of SpecificCharacterSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3420
diff
changeset
|
613 tokens.erase(tokens.begin()); |
3420
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
614 } |
0a0e7eca95ae
fix encoding in DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3391
diff
changeset
|
615 |
3202 | 616 node[KEY_VALUE] = Json::arrayValue; |
617 for (size_t i = 0; i < tokens.size(); i++) | |
618 { | |
619 try | |
620 { | |
621 switch (vr) | |
622 { | |
623 case ValueRepresentation_PersonName: | |
624 { | |
4200 | 625 Json::Value tmp = Json::objectValue; |
3202 | 626 if (!tokens[i].empty()) |
627 { | |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
628 std::vector<std::string> components; |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
629 Toolbox::TokenizeString(components, tokens[i], '='); |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
630 |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
631 if (components.size() >= 1) |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
632 { |
4200 | 633 tmp[KEY_ALPHABETIC] = components[0]; |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
634 } |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
635 |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
636 if (components.size() >= 2) |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
637 { |
4200 | 638 tmp[KEY_IDEOGRAPHIC] = components[1]; |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
639 } |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
640 |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
641 if (components.size() >= 3) |
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
642 { |
4200 | 643 tmp[KEY_PHONETIC] = components[2]; |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
644 } |
3202 | 645 } |
3221
4be505c2ac56
Separation of ideographic and phonetic characters in DICOMweb JSON and XML
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3203
diff
changeset
|
646 |
4200 | 647 node[KEY_VALUE].append(tmp); |
3202 | 648 break; |
649 } | |
650 | |
651 case ValueRepresentation_IntegerString: | |
3391 | 652 { |
653 /** | |
654 * The calls to "StripSpaces()" below fix the | |
655 * issue reported by Rana Asim Wajid on 2019-06-05 | |
656 * ("Error Exception while invoking plugin service | |
657 * 32: Bad file format"): | |
658 * https://groups.google.com/d/msg/orthanc-users/T32FovWPcCE/-hKFbfRJBgAJ | |
659 **/ | |
660 | |
4297 | 661 std::string t = Toolbox::StripSpaces(tokens[i]); |
3391 | 662 if (t.empty()) |
3202 | 663 { |
664 node[KEY_VALUE].append(Json::nullValue); | |
665 } | |
666 else | |
667 { | |
4200 | 668 int64_t tmp = boost::lexical_cast<int64_t>(t); |
669 node[KEY_VALUE].append(FormatInteger(tmp)); | |
3202 | 670 } |
3391 | 671 |
3202 | 672 break; |
3391 | 673 } |
3202 | 674 |
675 case ValueRepresentation_DecimalString: | |
3391 | 676 { |
4297 | 677 std::string t = Toolbox::StripSpaces(tokens[i]); |
3391 | 678 if (t.empty()) |
3202 | 679 { |
680 node[KEY_VALUE].append(Json::nullValue); | |
681 } | |
682 else | |
683 { | |
4200 | 684 double tmp = boost::lexical_cast<double>(t); |
685 node[KEY_VALUE].append(FormatDouble(tmp)); | |
3202 | 686 } |
3391 | 687 |
3202 | 688 break; |
3391 | 689 } |
690 | |
3202 | 691 default: |
692 if (tokens[i].empty()) | |
693 { | |
694 node[KEY_VALUE].append(Json::nullValue); | |
695 } | |
696 else | |
697 { | |
698 node[KEY_VALUE].append(tokens[i]); | |
699 } | |
700 | |
701 break; | |
702 } | |
703 } | |
704 catch (boost::bad_lexical_cast&) | |
705 { | |
3464
418a89acef3b
In DICOM-to-DICOMweb/JSON conversion, be more tolerant wrt. invalid DICOM files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3448
diff
changeset
|
706 std::string tmp; |
418a89acef3b
In DICOM-to-DICOMweb/JSON conversion, be more tolerant wrt. invalid DICOM files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3448
diff
changeset
|
707 if (value.size() < 64 && |
418a89acef3b
In DICOM-to-DICOMweb/JSON conversion, be more tolerant wrt. invalid DICOM files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3448
diff
changeset
|
708 Toolbox::IsAsciiString(value)) |
418a89acef3b
In DICOM-to-DICOMweb/JSON conversion, be more tolerant wrt. invalid DICOM files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3448
diff
changeset
|
709 { |
418a89acef3b
In DICOM-to-DICOMweb/JSON conversion, be more tolerant wrt. invalid DICOM files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3448
diff
changeset
|
710 tmp = ": " + value; |
418a89acef3b
In DICOM-to-DICOMweb/JSON conversion, be more tolerant wrt. invalid DICOM files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3448
diff
changeset
|
711 } |
418a89acef3b
In DICOM-to-DICOMweb/JSON conversion, be more tolerant wrt. invalid DICOM files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3448
diff
changeset
|
712 |
418a89acef3b
In DICOM-to-DICOMweb/JSON conversion, be more tolerant wrt. invalid DICOM files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3448
diff
changeset
|
713 LOG(WARNING) << "Ignoring DICOM tag (" << tag.Format() |
418a89acef3b
In DICOM-to-DICOMweb/JSON conversion, be more tolerant wrt. invalid DICOM files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
3448
diff
changeset
|
714 << ") with invalid content for VR " << EnumerationToString(vr) << tmp; |
3202 | 715 } |
716 } | |
717 } | |
718 } | |
719 } | |
720 | |
721 return Action_None; | |
722 } | |
723 } |