1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
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
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program. If not, see
19 * <http://www.gnu.org/licenses/>.
20 **/
21
22
23 #if ORTHANC_UNIT_TESTS_LINK_FRAMEWORK == 1
24 // Must be the first to be sure to use the Orthanc framework shared library
25 # include <OrthancFramework.h>
26 #endif
27
28 #if !defined(DCMTK_VERSION_NUMBER)
29 # error DCMTK_VERSION_NUMBER is not defined
30 #endif
31
32 #include <gtest/gtest.h>
33
34 #include "../Sources/Compatibility.h"
35 #include "../Sources/OrthancException.h"
36 #include "../Sources/DicomFormat/DicomMap.h"
37 #include "../Sources/DicomFormat/DicomStreamReader.h"
38 #include "../Sources/DicomParsing/FromDcmtkBridge.h"
39 #include "../Sources/DicomParsing/ToDcmtkBridge.h"
40 #include "../Sources/DicomParsing/ParsedDicomFile.h"
41 #include "../Sources/DicomParsing/DicomWebJsonVisitor.h"
42
43 #include <boost/lexical_cast.hpp>
44
45 using namespace Orthanc;
46
TEST(DicomMap,MainTags)47 TEST(DicomMap, MainTags)
48 {
49 ASSERT_TRUE(DicomMap::IsMainDicomTag(DICOM_TAG_PATIENT_ID));
50 ASSERT_TRUE(DicomMap::IsMainDicomTag(DICOM_TAG_PATIENT_ID, ResourceType_Patient));
51 ASSERT_FALSE(DicomMap::IsMainDicomTag(DICOM_TAG_PATIENT_ID, ResourceType_Study));
52
53 ASSERT_TRUE(DicomMap::IsMainDicomTag(DICOM_TAG_STUDY_INSTANCE_UID));
54 ASSERT_TRUE(DicomMap::IsMainDicomTag(DICOM_TAG_ACCESSION_NUMBER));
55 ASSERT_TRUE(DicomMap::IsMainDicomTag(DICOM_TAG_SERIES_INSTANCE_UID));
56 ASSERT_TRUE(DicomMap::IsMainDicomTag(DICOM_TAG_SOP_INSTANCE_UID));
57
58 std::set<DicomTag> s;
59 DicomMap::GetMainDicomTags(s);
60 ASSERT_TRUE(s.end() != s.find(DICOM_TAG_PATIENT_ID));
61 ASSERT_TRUE(s.end() != s.find(DICOM_TAG_STUDY_INSTANCE_UID));
62 ASSERT_TRUE(s.end() != s.find(DICOM_TAG_ACCESSION_NUMBER));
63 ASSERT_TRUE(s.end() != s.find(DICOM_TAG_SERIES_INSTANCE_UID));
64 ASSERT_TRUE(s.end() != s.find(DICOM_TAG_SOP_INSTANCE_UID));
65
66 DicomMap::GetMainDicomTags(s, ResourceType_Patient);
67 ASSERT_TRUE(s.end() != s.find(DICOM_TAG_PATIENT_ID));
68 ASSERT_TRUE(s.end() == s.find(DICOM_TAG_STUDY_INSTANCE_UID));
69
70 DicomMap::GetMainDicomTags(s, ResourceType_Study);
71 ASSERT_TRUE(s.end() != s.find(DICOM_TAG_STUDY_INSTANCE_UID));
72 ASSERT_TRUE(s.end() != s.find(DICOM_TAG_ACCESSION_NUMBER));
73 ASSERT_TRUE(s.end() == s.find(DICOM_TAG_PATIENT_ID));
74
75 DicomMap::GetMainDicomTags(s, ResourceType_Series);
76 ASSERT_TRUE(s.end() != s.find(DICOM_TAG_SERIES_INSTANCE_UID));
77 ASSERT_TRUE(s.end() == s.find(DICOM_TAG_PATIENT_ID));
78
79 DicomMap::GetMainDicomTags(s, ResourceType_Instance);
80 ASSERT_TRUE(s.end() != s.find(DICOM_TAG_SOP_INSTANCE_UID));
81 ASSERT_TRUE(s.end() == s.find(DICOM_TAG_PATIENT_ID));
82 }
83
84
TEST(DicomMap,Tags)85 TEST(DicomMap, Tags)
86 {
87 std::set<DicomTag> s;
88
89 DicomMap m;
90 m.GetTags(s);
91 ASSERT_EQ(0u, s.size());
92
93 ASSERT_FALSE(m.HasTag(DICOM_TAG_PATIENT_NAME));
94 ASSERT_FALSE(m.HasTag(0x0010, 0x0010));
95 m.SetValue(0x0010, 0x0010, "PatientName", false);
96 ASSERT_TRUE(m.HasTag(DICOM_TAG_PATIENT_NAME));
97 ASSERT_TRUE(m.HasTag(0x0010, 0x0010));
98
99 m.GetTags(s);
100 ASSERT_EQ(1u, s.size());
101 ASSERT_EQ(DICOM_TAG_PATIENT_NAME, *s.begin());
102
103 ASSERT_FALSE(m.HasTag(DICOM_TAG_PATIENT_ID));
104 m.SetValue(DICOM_TAG_PATIENT_ID, "PatientID", false);
105 ASSERT_TRUE(m.HasTag(0x0010, 0x0020));
106 m.SetValue(DICOM_TAG_PATIENT_ID, "PatientID2", false);
107 ASSERT_EQ("PatientID2", m.GetValue(0x0010, 0x0020).GetContent());
108
109 m.GetTags(s);
110 ASSERT_EQ(2u, s.size());
111
112 m.Remove(DICOM_TAG_PATIENT_ID);
113 ASSERT_THROW(m.GetValue(0x0010, 0x0020), OrthancException);
114
115 m.GetTags(s);
116 ASSERT_EQ(1u, s.size());
117 ASSERT_EQ(DICOM_TAG_PATIENT_NAME, *s.begin());
118
119 std::unique_ptr<DicomMap> mm(m.Clone());
120 ASSERT_EQ("PatientName", mm->GetValue(DICOM_TAG_PATIENT_NAME).GetContent());
121
122 m.SetValue(DICOM_TAG_PATIENT_ID, "Hello", false);
123 ASSERT_THROW(mm->GetValue(DICOM_TAG_PATIENT_ID), OrthancException);
124 mm->CopyTagIfExists(m, DICOM_TAG_PATIENT_ID);
125 ASSERT_EQ("Hello", mm->GetValue(DICOM_TAG_PATIENT_ID).GetContent());
126
127 DicomValue v;
128 ASSERT_TRUE(v.IsNull());
129 }
130
131
TEST(DicomMap,FindTemplates)132 TEST(DicomMap, FindTemplates)
133 {
134 DicomMap m;
135
136 DicomMap::SetupFindPatientTemplate(m);
137 ASSERT_TRUE(m.HasTag(DICOM_TAG_PATIENT_ID));
138
139 DicomMap::SetupFindStudyTemplate(m);
140 ASSERT_TRUE(m.HasTag(DICOM_TAG_STUDY_INSTANCE_UID));
141 ASSERT_TRUE(m.HasTag(DICOM_TAG_ACCESSION_NUMBER));
142
143 DicomMap::SetupFindSeriesTemplate(m);
144 ASSERT_TRUE(m.HasTag(DICOM_TAG_SERIES_INSTANCE_UID));
145
146 DicomMap::SetupFindInstanceTemplate(m);
147 ASSERT_TRUE(m.HasTag(DICOM_TAG_SOP_INSTANCE_UID));
148 }
149
150
151
152
TestModule(ResourceType level,DicomModule module)153 static void TestModule(ResourceType level,
154 DicomModule module)
155 {
156 // REFERENCE: DICOM PS3.3 2015c - Information Object Definitions
157 // http://dicom.nema.org/medical/dicom/current/output/html/part03.html
158
159 std::set<DicomTag> moduleTags, main;
160 DicomTag::AddTagsForModule(moduleTags, module);
161 DicomMap::GetMainDicomTags(main, level);
162
163 // The main dicom tags are a subset of the module
164 for (std::set<DicomTag>::const_iterator it = main.begin(); it != main.end(); ++it)
165 {
166 bool ok = moduleTags.find(*it) != moduleTags.end();
167
168 // Exceptions for the Study level
169 if (level == ResourceType_Study &&
170 (*it == DicomTag(0x0008, 0x0080) || /* InstitutionName, from Visit identification module, related to Visit */
171 *it == DicomTag(0x0032, 0x1032) || /* RequestingPhysician, from Imaging Service Request module, related to Study */
172 *it == DicomTag(0x0032, 0x1060))) /* RequestedProcedureDescription, from Requested Procedure module, related to Study */
173 {
174 ok = true;
175 }
176
177 // Exceptions for the Series level
178 if (level == ResourceType_Series &&
179 (*it == DicomTag(0x0008, 0x0070) || /* Manufacturer, from General Equipment Module */
180 *it == DicomTag(0x0008, 0x1010) || /* StationName, from General Equipment Module */
181 *it == DicomTag(0x0018, 0x0024) || /* SequenceName, from MR Image Module (SIMPLIFICATION => Series) */
182 *it == DicomTag(0x0018, 0x1090) || /* CardiacNumberOfImages, from MR Image Module (SIMPLIFICATION => Series) */
183 *it == DicomTag(0x0020, 0x0037) || /* ImageOrientationPatient, from Image Plane Module (SIMPLIFICATION => Series) */
184 *it == DicomTag(0x0020, 0x0105) || /* NumberOfTemporalPositions, from MR Image Module (SIMPLIFICATION => Series) */
185 *it == DicomTag(0x0020, 0x1002) || /* ImagesInAcquisition, from General Image Module (SIMPLIFICATION => Series) */
186 *it == DicomTag(0x0054, 0x0081) || /* NumberOfSlices, from PET Series module */
187 *it == DicomTag(0x0054, 0x0101) || /* NumberOfTimeSlices, from PET Series module */
188 *it == DicomTag(0x0054, 0x1000) || /* SeriesType, from PET Series module */
189 *it == DicomTag(0x0018, 0x1400) || /* AcquisitionDeviceProcessingDescription, from CR/X-Ray/DX/WholeSlideMicro Image (SIMPLIFICATION => Series) */
190 *it == DicomTag(0x0018, 0x0010))) /* ContrastBolusAgent, from Contrast/Bolus module (SIMPLIFICATION => Series) */
191 {
192 ok = true;
193 }
194
195 // Exceptions for the Instance level
196 if (level == ResourceType_Instance &&
197 (*it == DicomTag(0x0020, 0x0012) || /* AccessionNumber, from General Image module */
198 *it == DicomTag(0x0054, 0x1330) || /* ImageIndex, from PET Image module */
199 *it == DicomTag(0x0020, 0x0100) || /* TemporalPositionIdentifier, from MR Image module */
200 *it == DicomTag(0x0028, 0x0008) || /* NumberOfFrames, from Multi-frame module attributes, related to Image */
201 *it == DicomTag(0x0020, 0x0032) || /* ImagePositionPatient, from Image Plan module, related to Image */
202 *it == DicomTag(0x0020, 0x0037) || /* ImageOrientationPatient, from Image Plane Module (Orthanc 1.4.2) */
203 *it == DicomTag(0x0020, 0x4000))) /* ImageComments, from General Image module */
204 {
205 ok = true;
206 }
207
208 if (!ok)
209 {
210 std::cout << it->Format() << ": " << FromDcmtkBridge::GetTagName(*it, "")
211 << " not expected at level " << EnumerationToString(level) << std::endl;
212 }
213
214 EXPECT_TRUE(ok);
215 }
216 }
217
218
TEST(DicomMap,Modules)219 TEST(DicomMap, Modules)
220 {
221 TestModule(ResourceType_Patient, DicomModule_Patient);
222 TestModule(ResourceType_Study, DicomModule_Study);
223 TestModule(ResourceType_Series, DicomModule_Series); // TODO
224 TestModule(ResourceType_Instance, DicomModule_Instance);
225 }
226
227
TEST(DicomMap,Parse)228 TEST(DicomMap, Parse)
229 {
230 DicomMap m;
231 float f;
232 double d;
233 int32_t i;
234 int64_t j;
235 uint32_t k;
236 uint64_t l;
237 unsigned int ui;
238 std::string s;
239
240 m.SetValue(DICOM_TAG_PATIENT_NAME, " ", false); // Empty value
241 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
242 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
243 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
244 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
245 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
246 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
247
248 m.SetValue(DICOM_TAG_PATIENT_NAME, "0", true); // Binary value
249 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
250 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
251 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
252 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
253 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
254 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
255
256 ASSERT_FALSE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, false));
257 ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, true));
258 ASSERT_EQ("0", s);
259
260
261 // 2**31-1
262 m.SetValue(DICOM_TAG_PATIENT_NAME, "2147483647", false);
263 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
264 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
265 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
266 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
267 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
268 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
269 ASSERT_FLOAT_EQ(2147483647.0f, f);
270 ASSERT_DOUBLE_EQ(2147483647.0, d);
271 ASSERT_EQ(2147483647, i);
272 ASSERT_EQ(2147483647ll, j);
273 ASSERT_EQ(2147483647u, k);
274 ASSERT_EQ(2147483647ull, l);
275
276 // Test shortcuts
277 m.SetValue(DICOM_TAG_PATIENT_NAME, "42", false);
278 ASSERT_TRUE(m.ParseFloat(f, DICOM_TAG_PATIENT_NAME));
279 ASSERT_TRUE(m.ParseDouble(d, DICOM_TAG_PATIENT_NAME));
280 ASSERT_TRUE(m.ParseInteger32(i, DICOM_TAG_PATIENT_NAME));
281 ASSERT_TRUE(m.ParseInteger64(j, DICOM_TAG_PATIENT_NAME));
282 ASSERT_TRUE(m.ParseUnsignedInteger32(k, DICOM_TAG_PATIENT_NAME));
283 ASSERT_TRUE(m.ParseUnsignedInteger64(l, DICOM_TAG_PATIENT_NAME));
284 ASSERT_FLOAT_EQ(42.0f, f);
285 ASSERT_DOUBLE_EQ(42.0, d);
286 ASSERT_EQ(42, i);
287 ASSERT_EQ(42ll, j);
288 ASSERT_EQ(42u, k);
289 ASSERT_EQ(42ull, l);
290
291 ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, false));
292 ASSERT_EQ("42", s);
293 ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, true));
294 ASSERT_EQ("42", s);
295
296
297 // 2**31
298 m.SetValue(DICOM_TAG_PATIENT_NAME, "2147483648", false);
299 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
300 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
301 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
302 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
303 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
304 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
305 ASSERT_FLOAT_EQ(2147483648.0f, f);
306 ASSERT_DOUBLE_EQ(2147483648.0, d);
307 ASSERT_EQ(2147483648ll, j);
308 ASSERT_EQ(2147483648u, k);
309 ASSERT_EQ(2147483648ull, l);
310
311 // 2**32-1
312 m.SetValue(DICOM_TAG_PATIENT_NAME, "4294967295", false);
313 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
314 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
315 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
316 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
317 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
318 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
319 ASSERT_FLOAT_EQ(4294967295.0f, f);
320 ASSERT_DOUBLE_EQ(4294967295.0, d);
321 ASSERT_EQ(4294967295ll, j);
322 ASSERT_EQ(4294967295u, k);
323 ASSERT_EQ(4294967295ull, l);
324
325 // 2**32
326 m.SetValue(DICOM_TAG_PATIENT_NAME, "4294967296", false);
327 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
328 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
329 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
330 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
331 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
332 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
333 ASSERT_FLOAT_EQ(4294967296.0f, f);
334 ASSERT_DOUBLE_EQ(4294967296.0, d);
335 ASSERT_EQ(4294967296ll, j);
336 ASSERT_EQ(4294967296ull, l);
337
338 m.SetValue(DICOM_TAG_PATIENT_NAME, "-1", false);
339 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
340 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
341 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
342 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
343 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
344 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
345 ASSERT_FLOAT_EQ(-1.0f, f);
346 ASSERT_DOUBLE_EQ(-1.0, d);
347 ASSERT_EQ(-1, i);
348 ASSERT_EQ(-1ll, j);
349
350 // -2**31
351 m.SetValue(DICOM_TAG_PATIENT_NAME, "-2147483648", false);
352 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
353 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
354 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
355 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
356 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
357 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
358 ASSERT_FLOAT_EQ(-2147483648.0f, f);
359 ASSERT_DOUBLE_EQ(-2147483648.0, d);
360 ASSERT_EQ(static_cast<int32_t>(-2147483648ll), i);
361 ASSERT_EQ(-2147483648ll, j);
362
363 // -2**31 - 1
364 m.SetValue(DICOM_TAG_PATIENT_NAME, "-2147483649", false);
365 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
366 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
367 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
368 ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
369 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
370 ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
371 ASSERT_FLOAT_EQ(-2147483649.0f, f);
372 ASSERT_DOUBLE_EQ(-2147483649.0, d);
373 ASSERT_EQ(-2147483649ll, j);
374
375
376 // "800\0" in US COLMUNS tag
377 m.SetValue(DICOM_TAG_COLUMNS, "800\0", false);
378 ASSERT_TRUE(m.GetValue(DICOM_TAG_COLUMNS).ParseFirstUnsignedInteger(ui));
379 ASSERT_EQ(800u, ui);
380 m.SetValue(DICOM_TAG_COLUMNS, "800", false);
381 ASSERT_TRUE(m.GetValue(DICOM_TAG_COLUMNS).ParseFirstUnsignedInteger(ui));
382 ASSERT_EQ(800u, ui);
383 }
384
385
TEST(DicomMap,Serialize)386 TEST(DicomMap, Serialize)
387 {
388 Json::Value s;
389
390 {
391 DicomMap m;
392 m.SetValue(DICOM_TAG_PATIENT_NAME, "Hello", false);
393 m.SetValue(DICOM_TAG_STUDY_DESCRIPTION, "Binary", true);
394 m.SetNullValue(DICOM_TAG_SERIES_DESCRIPTION);
395 m.Serialize(s);
396 }
397
398 {
399 DicomMap m;
400 m.Unserialize(s);
401
402 const DicomValue* v = m.TestAndGetValue(DICOM_TAG_ACCESSION_NUMBER);
403 ASSERT_TRUE(v == NULL);
404
405 v = m.TestAndGetValue(DICOM_TAG_PATIENT_NAME);
406 ASSERT_TRUE(v != NULL);
407 ASSERT_FALSE(v->IsNull());
408 ASSERT_FALSE(v->IsBinary());
409 ASSERT_EQ("Hello", v->GetContent());
410
411 v = m.TestAndGetValue(DICOM_TAG_STUDY_DESCRIPTION);
412 ASSERT_TRUE(v != NULL);
413 ASSERT_FALSE(v->IsNull());
414 ASSERT_TRUE(v->IsBinary());
415 ASSERT_EQ("Binary", v->GetContent());
416
417 v = m.TestAndGetValue(DICOM_TAG_SERIES_DESCRIPTION);
418 ASSERT_TRUE(v != NULL);
419 ASSERT_TRUE(v->IsNull());
420 ASSERT_FALSE(v->IsBinary());
421 ASSERT_THROW(v->GetContent(), OrthancException);
422 }
423 }
424
425
426
TEST(DicomMap,ExtractMainDicomTags)427 TEST(DicomMap, ExtractMainDicomTags)
428 {
429 DicomMap b;
430 b.SetValue(DICOM_TAG_PATIENT_NAME, "E", false);
431 ASSERT_TRUE(b.HasOnlyMainDicomTags());
432
433 {
434 DicomMap a;
435 a.SetValue(DICOM_TAG_PATIENT_NAME, "A", false);
436 a.SetValue(DICOM_TAG_STUDY_DESCRIPTION, "B", false);
437 a.SetValue(DICOM_TAG_SERIES_DESCRIPTION, "C", false);
438 a.SetValue(DICOM_TAG_NUMBER_OF_FRAMES, "D", false);
439 a.SetValue(DICOM_TAG_SLICE_THICKNESS, "F", false);
440 ASSERT_FALSE(a.HasOnlyMainDicomTags());
441 b.ExtractMainDicomTags(a);
442 }
443
444 ASSERT_EQ(4u, b.GetSize());
445 ASSERT_EQ("A", b.GetValue(DICOM_TAG_PATIENT_NAME).GetContent());
446 ASSERT_EQ("B", b.GetValue(DICOM_TAG_STUDY_DESCRIPTION).GetContent());
447 ASSERT_EQ("C", b.GetValue(DICOM_TAG_SERIES_DESCRIPTION).GetContent());
448 ASSERT_EQ("D", b.GetValue(DICOM_TAG_NUMBER_OF_FRAMES).GetContent());
449 ASSERT_FALSE(b.HasTag(DICOM_TAG_SLICE_THICKNESS));
450 ASSERT_TRUE(b.HasOnlyMainDicomTags());
451
452 b.SetValue(DICOM_TAG_PATIENT_NAME, "G", false);
453
454 {
455 DicomMap a;
456 a.SetValue(DICOM_TAG_PATIENT_NAME, "A", false);
457 a.SetValue(DICOM_TAG_SLICE_THICKNESS, "F", false);
458 ASSERT_FALSE(a.HasOnlyMainDicomTags());
459 b.Merge(a);
460 }
461
462 ASSERT_EQ(5u, b.GetSize());
463 ASSERT_EQ("G", b.GetValue(DICOM_TAG_PATIENT_NAME).GetContent());
464 ASSERT_EQ("B", b.GetValue(DICOM_TAG_STUDY_DESCRIPTION).GetContent());
465 ASSERT_EQ("C", b.GetValue(DICOM_TAG_SERIES_DESCRIPTION).GetContent());
466 ASSERT_EQ("D", b.GetValue(DICOM_TAG_NUMBER_OF_FRAMES).GetContent());
467 ASSERT_EQ("F", b.GetValue(DICOM_TAG_SLICE_THICKNESS).GetContent());
468 ASSERT_FALSE(b.HasOnlyMainDicomTags());
469 }
470
471
TEST(DicomMap,RemoveBinary)472 TEST(DicomMap, RemoveBinary)
473 {
474 DicomMap b;
475 b.SetValue(DICOM_TAG_PATIENT_NAME, "A", false);
476 b.SetValue(DICOM_TAG_PATIENT_ID, "B", true);
477 b.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, DicomValue()); // NULL
478 b.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, DicomValue("C", false));
479 b.SetValue(DICOM_TAG_SOP_INSTANCE_UID, DicomValue("D", true));
480
481 b.RemoveBinaryTags();
482
483 std::string s;
484 ASSERT_EQ(2u, b.GetSize());
485 ASSERT_TRUE(b.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, false)); ASSERT_EQ("A", s);
486 ASSERT_TRUE(b.LookupStringValue(s, DICOM_TAG_SERIES_INSTANCE_UID, false)); ASSERT_EQ("C", s);
487 }
488
489
490
TEST(DicomWebJson,Multiplicity)491 TEST(DicomWebJson, Multiplicity)
492 {
493 // http://dicom.nema.org/medical/dicom/current/output/chtml/part18/sect_F.2.4.html
494
495 ParsedDicomFile dicom(false);
496 dicom.ReplacePlainString(DICOM_TAG_PATIENT_NAME, "SB1^SB2^SB3^SB4^SB5");
497 dicom.ReplacePlainString(DICOM_TAG_IMAGE_ORIENTATION_PATIENT, "1\\2.3\\4");
498 dicom.ReplacePlainString(DICOM_TAG_IMAGE_POSITION_PATIENT, "");
499
500 DicomWebJsonVisitor visitor;
501 dicom.Apply(visitor);
502
503 {
504 const Json::Value& tag = visitor.GetResult() ["00200037"]; // ImageOrientationPatient
505 const Json::Value& value = tag["Value"];
506
507 ASSERT_EQ(EnumerationToString(ValueRepresentation_DecimalString), tag["vr"].asString());
508 ASSERT_EQ(2u, tag.getMemberNames().size());
509 ASSERT_EQ(3u, value.size());
510 ASSERT_EQ(Json::realValue, value[1].type());
511 ASSERT_FLOAT_EQ(1.0f, value[0].asFloat());
512 ASSERT_FLOAT_EQ(2.3f, value[1].asFloat());
513 ASSERT_FLOAT_EQ(4.0f, value[2].asFloat());
514 }
515
516 {
517 const Json::Value& tag = visitor.GetResult() ["00200032"]; // ImagePositionPatient
518 ASSERT_EQ(EnumerationToString(ValueRepresentation_DecimalString), tag["vr"].asString());
519 ASSERT_EQ(1u, tag.getMemberNames().size());
520 }
521
522 std::string xml;
523 visitor.FormatXml(xml);
524
525 {
526 DicomMap m;
527 m.FromDicomWeb(visitor.GetResult());
528 ASSERT_EQ(3u, m.GetSize());
529
530 std::string s;
531 ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_PATIENT_NAME, false));
532 ASSERT_EQ("SB1^SB2^SB3^SB4^SB5", s);
533 ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_IMAGE_POSITION_PATIENT, false));
534 ASSERT_TRUE(s.empty());
535
536 ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_IMAGE_ORIENTATION_PATIENT, false));
537
538 std::vector<std::string> v;
539 Toolbox::TokenizeString(v, s, '\\');
540 ASSERT_FLOAT_EQ(1.0f, boost::lexical_cast<float>(v[0]));
541 ASSERT_FLOAT_EQ(2.3f, boost::lexical_cast<float>(v[1]));
542 ASSERT_FLOAT_EQ(4.0f, boost::lexical_cast<float>(v[2]));
543 }
544 }
545
546
TEST(DicomWebJson,NullValue)547 TEST(DicomWebJson, NullValue)
548 {
549 // http://dicom.nema.org/medical/dicom/current/output/chtml/part18/sect_F.2.5.html
550
551 ParsedDicomFile dicom(false);
552 dicom.ReplacePlainString(DICOM_TAG_IMAGE_ORIENTATION_PATIENT, "1.5\\\\\\2.5");
553
554 DicomWebJsonVisitor visitor;
555 dicom.Apply(visitor);
556
557 {
558 const Json::Value& tag = visitor.GetResult() ["00200037"];
559 const Json::Value& value = tag["Value"];
560
561 ASSERT_EQ(EnumerationToString(ValueRepresentation_DecimalString), tag["vr"].asString());
562 ASSERT_EQ(2u, tag.getMemberNames().size());
563 ASSERT_EQ(4u, value.size());
564 ASSERT_EQ(Json::realValue, value[0].type());
565 ASSERT_EQ(Json::nullValue, value[1].type());
566 ASSERT_EQ(Json::nullValue, value[2].type());
567 ASSERT_EQ(Json::realValue, value[3].type());
568 ASSERT_FLOAT_EQ(1.5f, value[0].asFloat());
569 ASSERT_FLOAT_EQ(2.5f, value[3].asFloat());
570 }
571
572 std::string xml;
573 visitor.FormatXml(xml);
574
575 {
576 DicomMap m;
577 m.FromDicomWeb(visitor.GetResult());
578 ASSERT_EQ(1u, m.GetSize());
579
580 std::string s;
581 ASSERT_TRUE(m.LookupStringValue(s, DICOM_TAG_IMAGE_ORIENTATION_PATIENT, false));
582
583 std::vector<std::string> v;
584 Toolbox::TokenizeString(v, s, '\\');
585 ASSERT_FLOAT_EQ(1.5f, boost::lexical_cast<float>(v[0]));
586 ASSERT_TRUE(v[1].empty());
587 ASSERT_TRUE(v[2].empty());
588 ASSERT_FLOAT_EQ(2.5f, boost::lexical_cast<float>(v[3]));
589 }
590 }
591
592
TEST(DicomWebJson,PixelSpacing)593 TEST(DicomWebJson, PixelSpacing)
594 {
595 // Test related to locales: Make sure that decimal separator is
596 // correctly handled (dot "." vs comma ",")
597 ParsedDicomFile source(false);
598 source.ReplacePlainString(DICOM_TAG_PIXEL_SPACING, "1.5\\1.3");
599
600 DicomWebJsonVisitor visitor;
601 source.Apply(visitor);
602
603 DicomMap target;
604 target.FromDicomWeb(visitor.GetResult());
605
606 ASSERT_EQ("DS", visitor.GetResult() ["00280030"]["vr"].asString());
607 ASSERT_FLOAT_EQ(1.5f, visitor.GetResult() ["00280030"]["Value"][0].asFloat());
608 ASSERT_FLOAT_EQ(1.3f, visitor.GetResult() ["00280030"]["Value"][1].asFloat());
609
610 std::string s;
611 ASSERT_TRUE(target.LookupStringValue(s, DICOM_TAG_PIXEL_SPACING, false));
612 ASSERT_EQ(s, "1.5\\1.3");
613 }
614
615
TEST(DicomMap,MainTagNames)616 TEST(DicomMap, MainTagNames)
617 {
618 ASSERT_EQ(3, ResourceType_Instance - ResourceType_Patient);
619
620 for (int i = ResourceType_Patient; i <= ResourceType_Instance; i++)
621 {
622 ResourceType level = static_cast<ResourceType>(i);
623
624 std::set<DicomTag> tags;
625 DicomMap::GetMainDicomTags(tags, level);
626
627 for (std::set<DicomTag>::const_iterator it = tags.begin(); it != tags.end(); ++it)
628 {
629 DicomMap a;
630 a.SetValue(*it, "TEST", false);
631
632 Json::Value json;
633 a.DumpMainDicomTags(json, level);
634
635 ASSERT_EQ(Json::objectValue, json.type());
636 ASSERT_EQ(1u, json.getMemberNames().size());
637
638 std::string name = json.getMemberNames() [0];
639 EXPECT_EQ(name, FromDcmtkBridge::GetTagName(*it, ""));
640
641 DicomMap b;
642 b.ParseMainDicomTags(json, level);
643
644 ASSERT_EQ(1u, b.GetSize());
645 ASSERT_EQ("TEST", b.GetStringValue(*it, "", false));
646
647 std::string main = it->GetMainTagsName();
648 if (!main.empty())
649 {
650 ASSERT_EQ(main, name);
651 }
652 }
653 }
654 }
655
656
657
TEST(DicomTag,Comparisons)658 TEST(DicomTag, Comparisons)
659 {
660 DicomTag a(0x0000, 0x0000);
661 DicomTag b(0x0010, 0x0010);
662 DicomTag c(0x0010, 0x0020);
663 DicomTag d(0x0020, 0x0000);
664
665 // operator==()
666 ASSERT_TRUE(a == a);
667 ASSERT_FALSE(a == b);
668
669 // operator!=()
670 ASSERT_FALSE(a != a);
671 ASSERT_TRUE(a != b);
672
673 // operator<=()
674 ASSERT_TRUE(a <= a);
675 ASSERT_TRUE(a <= b);
676 ASSERT_TRUE(a <= c);
677 ASSERT_TRUE(a <= d);
678
679 ASSERT_FALSE(b <= a);
680 ASSERT_TRUE(b <= b);
681 ASSERT_TRUE(b <= c);
682 ASSERT_TRUE(b <= d);
683
684 ASSERT_FALSE(c <= a);
685 ASSERT_FALSE(c <= b);
686 ASSERT_TRUE(c <= c);
687 ASSERT_TRUE(c <= d);
688
689 ASSERT_FALSE(d <= a);
690 ASSERT_FALSE(d <= b);
691 ASSERT_FALSE(d <= c);
692 ASSERT_TRUE(d <= d);
693
694 // operator<()
695 ASSERT_FALSE(a < a);
696 ASSERT_TRUE(a < b);
697 ASSERT_TRUE(a < c);
698 ASSERT_TRUE(a < d);
699
700 ASSERT_FALSE(b < a);
701 ASSERT_FALSE(b < b);
702 ASSERT_TRUE(b < c);
703 ASSERT_TRUE(b < d);
704
705 ASSERT_FALSE(c < a);
706 ASSERT_FALSE(c < b);
707 ASSERT_FALSE(c < c);
708 ASSERT_TRUE(c < d);
709
710 ASSERT_FALSE(d < a);
711 ASSERT_FALSE(d < b);
712 ASSERT_FALSE(d < c);
713 ASSERT_FALSE(d < d);
714
715 // operator>=()
716 ASSERT_TRUE(a >= a);
717 ASSERT_FALSE(a >= b);
718 ASSERT_FALSE(a >= c);
719 ASSERT_FALSE(a >= d);
720
721 ASSERT_TRUE(b >= a);
722 ASSERT_TRUE(b >= b);
723 ASSERT_FALSE(b >= c);
724 ASSERT_FALSE(b >= d);
725
726 ASSERT_TRUE(c >= a);
727 ASSERT_TRUE(c >= b);
728 ASSERT_TRUE(c >= c);
729 ASSERT_FALSE(c >= d);
730
731 ASSERT_TRUE(d >= a);
732 ASSERT_TRUE(d >= b);
733 ASSERT_TRUE(d >= c);
734 ASSERT_TRUE(d >= d);
735
736 // operator>()
737 ASSERT_FALSE(a > a);
738 ASSERT_FALSE(a > b);
739 ASSERT_FALSE(a > c);
740 ASSERT_FALSE(a > d);
741
742 ASSERT_TRUE(b > a);
743 ASSERT_FALSE(b > b);
744 ASSERT_FALSE(b > c);
745 ASSERT_FALSE(b > d);
746
747 ASSERT_TRUE(c > a);
748 ASSERT_TRUE(c > b);
749 ASSERT_FALSE(c > c);
750 ASSERT_FALSE(c > d);
751
752 ASSERT_TRUE(d > a);
753 ASSERT_TRUE(d > b);
754 ASSERT_TRUE(d > c);
755 ASSERT_FALSE(d > d);
756 }
757
758
759
760 #if ORTHANC_SANDBOXED != 1
761
762 #include "../Sources/SystemToolbox.h"
763
TEST(DicomMap,DISABLED_ParseDicomMetaInformation)764 TEST(DicomMap, DISABLED_ParseDicomMetaInformation)
765 {
766 static const std::string PATH = "/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/";
767
768 std::map<std::string, DicomTransferSyntax> f;
769 f.insert(std::make_pair(PATH + "../ColorTestMalaterre.dcm", DicomTransferSyntax_LittleEndianImplicit)); // 1.2.840.10008.1.2
770 f.insert(std::make_pair(PATH + "1.2.840.10008.1.2.1.dcm", DicomTransferSyntax_LittleEndianExplicit));
771 f.insert(std::make_pair(PATH + "1.2.840.10008.1.2.2.dcm", DicomTransferSyntax_BigEndianExplicit));
772 f.insert(std::make_pair(PATH + "1.2.840.10008.1.2.4.50.dcm", DicomTransferSyntax_JPEGProcess1));
773 f.insert(std::make_pair(PATH + "1.2.840.10008.1.2.4.51.dcm", DicomTransferSyntax_JPEGProcess2_4));
774 f.insert(std::make_pair(PATH + "1.2.840.10008.1.2.4.57.dcm", DicomTransferSyntax_JPEGProcess14));
775 f.insert(std::make_pair(PATH + "1.2.840.10008.1.2.4.70.dcm", DicomTransferSyntax_JPEGProcess14SV1));
776 f.insert(std::make_pair(PATH + "1.2.840.10008.1.2.4.80.dcm", DicomTransferSyntax_JPEGLSLossless));
777 f.insert(std::make_pair(PATH + "1.2.840.10008.1.2.4.81.dcm", DicomTransferSyntax_JPEGLSLossy));
778 f.insert(std::make_pair(PATH + "1.2.840.10008.1.2.4.90.dcm", DicomTransferSyntax_JPEG2000LosslessOnly));
779 f.insert(std::make_pair(PATH + "1.2.840.10008.1.2.4.91.dcm", DicomTransferSyntax_JPEG2000));
780 f.insert(std::make_pair(PATH + "1.2.840.10008.1.2.5.dcm", DicomTransferSyntax_RLELossless));
781
782 for (std::map<std::string, DicomTransferSyntax>::const_iterator it = f.begin(); it != f.end(); ++it)
783 {
784 printf("\n== %s ==\n\n", it->first.c_str());
785
786 std::string dicom;
787 SystemToolbox::ReadFile(dicom, it->first, false);
788
789 DicomMap d;
790 ASSERT_TRUE(DicomMap::ParseDicomMetaInformation(d, dicom.c_str(), dicom.size()));
791 d.Print(stdout);
792
793 std::string s;
794 ASSERT_TRUE(d.LookupStringValue(s, DICOM_TAG_TRANSFER_SYNTAX_UID, false));
795
796 DicomTransferSyntax ts;
797 ASSERT_TRUE(LookupTransferSyntax(ts, s));
798 ASSERT_EQ(ts, it->second);
799 }
800 }
801
802
803 namespace
804 {
805 class V : public DicomStreamReader::IVisitor
806 {
807 private:
808 DicomMap map_;
809
810 public:
GetDicomMap() const811 const DicomMap& GetDicomMap() const
812 {
813 return map_;
814 }
815
VisitMetaHeaderTag(const DicomTag & tag,const ValueRepresentation & vr,const std::string & value)816 virtual void VisitMetaHeaderTag(const DicomTag& tag,
817 const ValueRepresentation& vr,
818 const std::string& value) ORTHANC_OVERRIDE
819 {
820 std::cout << "Header: " << tag.Format() << " [" << Toolbox::ConvertToAscii(value).c_str() << "] (" << value.size() << ")" << std::endl;
821 }
822
VisitTransferSyntax(DicomTransferSyntax transferSyntax)823 virtual void VisitTransferSyntax(DicomTransferSyntax transferSyntax) ORTHANC_OVERRIDE
824 {
825 printf("TRANSFER SYNTAX: %s\n", GetTransferSyntaxUid(transferSyntax));
826 }
827
VisitDatasetTag(const DicomTag & tag,const ValueRepresentation & vr,const std::string & value,bool isLittleEndian)828 virtual bool VisitDatasetTag(const DicomTag& tag,
829 const ValueRepresentation& vr,
830 const std::string& value,
831 bool isLittleEndian) ORTHANC_OVERRIDE
832 {
833 if (!isLittleEndian)
834 printf("** ");
835 if (tag.GetGroup() < 0x7f00)
836 {
837 std::cout << "Dataset: " << tag.Format() << " " << EnumerationToString(vr)
838 << " [" << Toolbox::ConvertToAscii(value).c_str() << "] (" << value.size() << ")" << std::endl;
839 }
840 else
841 {
842 std::cout << "Dataset: " << tag.Format() << " " << EnumerationToString(vr)
843 << " [PIXEL] (" << value.size() << ")" << std::endl;
844 }
845
846 map_.SetValue(tag, value, Toolbox::IsAsciiString(value));
847
848 return true;
849 }
850 };
851 }
852
853
854
TEST(DicomStreamReader,DISABLED_Tutu)855 TEST(DicomStreamReader, DISABLED_Tutu)
856 {
857 static const std::string PATH = "/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/";
858
859 std::string dicom;
860 SystemToolbox::ReadFile(dicom, PATH + "../ColorTestMalaterre.dcm", false);
861 //SystemToolbox::ReadFile(dicom, PATH + "1.2.840.10008.1.2.1.dcm", false);
862 //SystemToolbox::ReadFile(dicom, PATH + "1.2.840.10008.1.2.2.dcm", false); // Big Endian
863 //SystemToolbox::ReadFile(dicom, PATH + "1.2.840.10008.1.2.4.50.dcm", false);
864 //SystemToolbox::ReadFile(dicom, PATH + "1.2.840.10008.1.2.4.51.dcm", false);
865 //SystemToolbox::ReadFile(dicom, PATH + "1.2.840.10008.1.2.4.57.dcm", false);
866 //SystemToolbox::ReadFile(dicom, PATH + "1.2.840.10008.1.2.4.70.dcm", false);
867 //SystemToolbox::ReadFile(dicom, PATH + "1.2.840.10008.1.2.4.80.dcm", false);
868 //SystemToolbox::ReadFile(dicom, PATH + "1.2.840.10008.1.2.4.81.dcm", false);
869 //SystemToolbox::ReadFile(dicom, PATH + "1.2.840.10008.1.2.4.90.dcm", false);
870 //SystemToolbox::ReadFile(dicom, PATH + "1.2.840.10008.1.2.4.91.dcm", false);
871 //SystemToolbox::ReadFile(dicom, PATH + "1.2.840.10008.1.2.5.dcm", false);
872
873 std::stringstream stream;
874 size_t pos = 0;
875
876 DicomStreamReader r(stream);
877 V visitor;
878
879 while (pos < dicom.size() &&
880 !r.IsDone())
881 {
882 //printf(".");
883 //printf("%d\n", pos);
884 r.Consume(visitor);
885 stream.clear();
886 stream.put(dicom[pos++]);
887 }
888
889 r.Consume(visitor);
890
891 printf(">> %d\n", static_cast<int>(r.GetProcessedBytes()));
892 }
893
TEST(DicomStreamReader,DISABLED_Tutu2)894 TEST(DicomStreamReader, DISABLED_Tutu2)
895 {
896 //static const std::string PATH = "/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/";
897
898 //const std::string path = PATH + "1.2.840.10008.1.2.4.50.dcm";
899 //const std::string path = PATH + "1.2.840.10008.1.2.2.dcm";
900 const std::string path = "/home/jodogne/Subversion/orthanc-tests/Database/HierarchicalAnonymization/RTH/RT.dcm";
901
902 std::ifstream stream(path.c_str());
903
904 DicomStreamReader r(stream);
905 V visitor;
906
907 r.Consume(visitor);
908
909 printf(">> %d\n", static_cast<int>(r.GetProcessedBytes()));
910 }
911
912
913 #include <boost/filesystem.hpp>
914
TEST(DicomStreamReader,DISABLED_Tutu3)915 TEST(DicomStreamReader, DISABLED_Tutu3)
916 {
917 static const std::string PATH = "/home/jodogne/Subversion/orthanc-tests/Database/";
918
919 std::set<std::string> errors;
920 unsigned int success = 0;
921
922 for (boost::filesystem::recursive_directory_iterator current(PATH), end;
923 current != end ; ++current)
924 {
925 if (SystemToolbox::IsRegularFile(current->path().string()))
926 {
927 try
928 {
929 if (current->path().extension() == ".dcm")
930 {
931 const std::string path = current->path().string();
932 printf("[%s]\n", path.c_str());
933
934 DicomMap m1;
935
936 {
937 std::ifstream stream(path.c_str());
938
939 DicomStreamReader r(stream);
940 V visitor;
941
942 try
943 {
944 r.Consume(visitor, DICOM_TAG_PIXEL_DATA);
945 //r.Consume(visitor);
946 success++;
947 }
948 catch (OrthancException& e)
949 {
950 errors.insert(path);
951 continue;
952 }
953
954 m1.Assign(visitor.GetDicomMap());
955 }
956
957 m1.SetValue(DICOM_TAG_PIXEL_DATA, "", true);
958
959
960 DicomMap m2;
961
962 {
963 std::string dicom;
964 SystemToolbox::ReadFile(dicom, path);
965
966 ParsedDicomFile f(dicom);
967 f.ExtractDicomSummary(m2, 256);
968 }
969
970 std::set<DicomTag> tags;
971 m2.GetTags(tags);
972
973 bool first = true;
974 for (std::set<DicomTag>::const_iterator it = tags.begin(); it != tags.end(); ++it)
975 {
976 if (!m1.HasTag(*it))
977 {
978 if (first)
979 {
980 fprintf(stderr, "[%s]\n", path.c_str());
981 first = false;
982 }
983
984 std::cerr << "ERROR: " << it->Format() << std::endl;
985 }
986 else if (!m2.GetValue(*it).IsNull() &&
987 !m2.GetValue(*it).IsBinary() &&
988 Toolbox::IsAsciiString(m1.GetValue(*it).GetContent()))
989 {
990 const std::string& v1 = m1.GetValue(*it).GetContent();
991 const std::string& v2 = m2.GetValue(*it).GetContent();
992
993 if (v1 != v2 &&
994 (v1.size() != v2.size() + 1 ||
995 v1.substr(0, v2.size()) != v2))
996 {
997 std::cerr << "ERROR: [" << v1 << "] [" << v2 << "]" << std::endl;
998 }
999 }
1000 }
1001 }
1002 }
1003 catch (boost::filesystem::filesystem_error&)
1004 {
1005 }
1006 }
1007 }
1008
1009
1010 printf("\n== ERRORS ==\n");
1011 for (std::set<std::string>::const_iterator
1012 it = errors.begin(); it != errors.end(); ++it)
1013 {
1014 printf("[%s]\n", it->c_str());
1015 }
1016
1017 printf("\n== SUCCESSES: %u ==\n\n", success);
1018 }
1019
1020 #endif
1021