comparison Framework/Inputs/DicomPyramidInstance.cpp @ 196:b0bd22077cd8

sharing code with orthanc-stone
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 01 Jul 2020 17:57:38 +0200
parents e57e6ca5303d
children 2a4e1f7de5ab
comparison
equal deleted inserted replaced
195:fda17c92d784 196:b0bd22077cd8
21 21
22 #include "../PrecompiledHeadersWSI.h" 22 #include "../PrecompiledHeadersWSI.h"
23 #include "DicomPyramidInstance.h" 23 #include "DicomPyramidInstance.h"
24 24
25 #include "../DicomToolbox.h" 25 #include "../DicomToolbox.h"
26 #include "Orthanc/DicomDatasetReader.h" 26 #include "../../Resources/Orthanc/Stone/DicomDatasetReader.h"
27 #include "Orthanc/FullOrthancDataset.h" 27 #include "../../Resources/Orthanc/Stone/FullOrthancDataset.h"
28 28
29 #include <Logging.h> 29 #include <Logging.h>
30 #include <OrthancException.h> 30 #include <OrthancException.h>
31 #include <Toolbox.h> 31 #include <Toolbox.h>
32 32
33 #include <cassert> 33 #include <cassert>
34 #include <json/writer.h> 34 #include <json/writer.h>
35 35
36 #define SERIALIZED_METADATA "4200" 36 #define SERIALIZED_METADATA "4200"
37 37
38
38 namespace OrthancWSI 39 namespace OrthancWSI
39 { 40 {
40 static ImageCompression DetectImageCompression(OrthancPlugins::IOrthancConnection& orthanc, 41 static const Orthanc::DicomTag DICOM_TAG_COLUMN_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021e);
42 static const Orthanc::DicomTag DICOM_TAG_PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE(0x5200, 0x9230);
43 static const Orthanc::DicomTag DICOM_TAG_PLANE_POSITION_SLIDE_SEQUENCE(0x0048, 0x021a);
44 static const Orthanc::DicomTag DICOM_TAG_ROW_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021f);
45 static const Orthanc::DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_COLUMNS(0x0048, 0x0006);
46 static const Orthanc::DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_ROWS(0x0048, 0x0007);
47
48 static ImageCompression DetectImageCompression(OrthancStone::IOrthancConnection& orthanc,
41 const std::string& instanceId) 49 const std::string& instanceId)
42 { 50 {
43 using namespace OrthancPlugins; 51 using namespace OrthancStone;
44 52
45 FullOrthancDataset dataset(orthanc, "/instances/" + instanceId + "/header"); 53 FullOrthancDataset dataset(orthanc, "/instances/" + instanceId + "/header");
46 DicomDatasetReader header(dataset); 54 DicomDatasetReader header(dataset);
47 55
48 std::string s = Orthanc::Toolbox::StripSpaces 56 std::string s = Orthanc::Toolbox::StripSpaces
49 (header.GetMandatoryStringValue(DICOM_TAG_TRANSFER_SYNTAX_UID)); 57 (header.GetMandatoryStringValue(Orthanc::DICOM_TAG_TRANSFER_SYNTAX_UID));
50 58
51 if (s == "1.2.840.10008.1.2" || 59 if (s == "1.2.840.10008.1.2" ||
52 s == "1.2.840.10008.1.2.1") 60 s == "1.2.840.10008.1.2.1")
53 { 61 {
54 return ImageCompression_None; 62 return ImageCompression_None;
70 } 78 }
71 79
72 80
73 static void DetectPixelFormat(Orthanc::PixelFormat& format, 81 static void DetectPixelFormat(Orthanc::PixelFormat& format,
74 Orthanc::PhotometricInterpretation& photometric, 82 Orthanc::PhotometricInterpretation& photometric,
75 OrthancPlugins::DicomDatasetReader& reader) 83 OrthancStone::DicomDatasetReader& reader)
76 { 84 {
77 using namespace OrthancPlugins; 85 using namespace OrthancStone;
78 86
79 std::string p = Orthanc::Toolbox::StripSpaces 87 std::string p = Orthanc::Toolbox::StripSpaces
80 (reader.GetMandatoryStringValue(DICOM_TAG_PHOTOMETRIC_INTERPRETATION)); 88 (reader.GetMandatoryStringValue(Orthanc::DICOM_TAG_PHOTOMETRIC_INTERPRETATION));
81 89
82 photometric = Orthanc::StringToPhotometricInterpretation(p.c_str()); 90 photometric = Orthanc::StringToPhotometricInterpretation(p.c_str());
83 91
84 if (photometric == Orthanc::PhotometricInterpretation_Palette) 92 if (photometric == Orthanc::PhotometricInterpretation_Palette)
85 { 93 {
87 "Unsupported photometric interpretation: " + p); 95 "Unsupported photometric interpretation: " + p);
88 } 96 }
89 97
90 unsigned int bitsStored, samplesPerPixel, tmp; 98 unsigned int bitsStored, samplesPerPixel, tmp;
91 99
92 if (!reader.GetUnsignedIntegerValue(bitsStored, DICOM_TAG_BITS_STORED) || 100 if (!reader.GetUnsignedIntegerValue(bitsStored, Orthanc::DICOM_TAG_BITS_STORED) ||
93 !reader.GetUnsignedIntegerValue(samplesPerPixel, DICOM_TAG_SAMPLES_PER_PIXEL) || 101 !reader.GetUnsignedIntegerValue(samplesPerPixel, Orthanc::DICOM_TAG_SAMPLES_PER_PIXEL) ||
94 !reader.GetUnsignedIntegerValue(tmp, DICOM_TAG_PIXEL_REPRESENTATION)) 102 !reader.GetUnsignedIntegerValue(tmp, Orthanc::DICOM_TAG_PIXEL_REPRESENTATION))
95 { 103 {
96 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentTag); 104 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentTag);
97 } 105 }
98 106
99 bool isSigned = (tmp != 0); 107 bool isSigned = (tmp != 0);
115 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, "Unsupported pixel format"); 123 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, "Unsupported pixel format");
116 } 124 }
117 } 125 }
118 126
119 127
120 ImageCompression DicomPyramidInstance::GetImageCompression(OrthancPlugins::IOrthancConnection& orthanc) 128 ImageCompression DicomPyramidInstance::GetImageCompression(OrthancStone::IOrthancConnection& orthanc)
121 { 129 {
122 /** 130 /**
123 * Lazy detection of the image compression using the transfer 131 * Lazy detection of the image compression using the transfer
124 * syntax stored inside the DICOM header. Given the fact that 132 * syntax stored inside the DICOM header. Given the fact that
125 * reading the header is a time-consuming operation (it implies 133 * reading the header is a time-consuming operation (it implies
136 144
137 return compression_; 145 return compression_;
138 } 146 }
139 147
140 148
141 void DicomPyramidInstance::Load(OrthancPlugins::IOrthancConnection& orthanc, 149 void DicomPyramidInstance::Load(OrthancStone::IOrthancConnection& orthanc,
142 const std::string& instanceId) 150 const std::string& instanceId)
143 { 151 {
144 using namespace OrthancPlugins; 152 using namespace OrthancStone;
145 153
146 FullOrthancDataset dataset(orthanc, "/instances/" + instanceId + "/tags"); 154 FullOrthancDataset dataset(orthanc, "/instances/" + instanceId + "/tags");
147 DicomDatasetReader reader(dataset); 155 DicomDatasetReader reader(dataset);
148 156
149 if (reader.GetMandatoryStringValue(DICOM_TAG_SOP_CLASS_UID) != "1.2.840.10008.5.1.4.1.1.77.1.6" || 157 if (reader.GetMandatoryStringValue(Orthanc::DICOM_TAG_SOP_CLASS_UID) != "1.2.840.10008.5.1.4.1.1.77.1.6" ||
150 reader.GetMandatoryStringValue(DICOM_TAG_MODALITY) != "SM") 158 reader.GetMandatoryStringValue(Orthanc::DICOM_TAG_MODALITY) != "SM")
151 { 159 {
152 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); 160 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
153 } 161 }
154 162
155 hasCompression_ = false; 163 hasCompression_ = false;
156 DetectPixelFormat(format_, photometric_, reader); 164 DetectPixelFormat(format_, photometric_, reader);
157 165
158 unsigned int tmp; 166 unsigned int tmp;
159 if (!reader.GetUnsignedIntegerValue(tileWidth_, DICOM_TAG_COLUMNS) || 167 if (!reader.GetUnsignedIntegerValue(tileWidth_, Orthanc::DICOM_TAG_COLUMNS) ||
160 !reader.GetUnsignedIntegerValue(tileHeight_, DICOM_TAG_ROWS) || 168 !reader.GetUnsignedIntegerValue(tileHeight_, Orthanc::DICOM_TAG_ROWS) ||
161 !reader.GetUnsignedIntegerValue(totalWidth_, DICOM_TAG_TOTAL_PIXEL_MATRIX_COLUMNS) || 169 !reader.GetUnsignedIntegerValue(totalWidth_, DICOM_TAG_TOTAL_PIXEL_MATRIX_COLUMNS) ||
162 !reader.GetUnsignedIntegerValue(totalHeight_, DICOM_TAG_TOTAL_PIXEL_MATRIX_ROWS) || 170 !reader.GetUnsignedIntegerValue(totalHeight_, DICOM_TAG_TOTAL_PIXEL_MATRIX_ROWS) ||
163 !reader.GetUnsignedIntegerValue(tmp, DICOM_TAG_NUMBER_OF_FRAMES)) 171 !reader.GetUnsignedIntegerValue(tmp, Orthanc::DICOM_TAG_NUMBER_OF_FRAMES))
164 { 172 {
165 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); 173 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
166 } 174 }
167 175
168 size_t countFrames; 176 size_t countFrames;
219 frames_[i].second = y / tileHeight_; 227 frames_[i].second = y / tileHeight_;
220 } 228 }
221 } 229 }
222 230
223 231
224 DicomPyramidInstance::DicomPyramidInstance(OrthancPlugins::IOrthancConnection& orthanc, 232 DicomPyramidInstance::DicomPyramidInstance(OrthancStone::IOrthancConnection& orthanc,
225 const std::string& instanceId, 233 const std::string& instanceId,
226 bool useCache) : 234 bool useCache) :
227 instanceId_(instanceId), 235 instanceId_(instanceId),
228 hasCompression_(false) 236 hasCompression_(false)
229 { 237 {
311 void DicomPyramidInstance::Deserialize(const std::string& s) 319 void DicomPyramidInstance::Deserialize(const std::string& s)
312 { 320 {
313 hasCompression_ = false; 321 hasCompression_ = false;
314 322
315 Json::Value content; 323 Json::Value content;
316 OrthancPlugins::IOrthancConnection::ParseJson(content, s); 324 OrthancStone::IOrthancConnection::ParseJson(content, s);
317 325
318 if (content.type() != Json::objectValue || 326 if (content.type() != Json::objectValue ||
319 !content.isMember("Frames") || 327 !content.isMember("Frames") ||
320 !content.isMember("PixelFormat") || 328 !content.isMember("PixelFormat") ||
321 !content.isMember("TileHeight") || 329 !content.isMember("TileHeight") ||