Mercurial > hg > orthanc-stone
comparison OrthancStone/Sources/Loaders/OrthancMultiframeVolumeLoader.cpp @ 1640:52b8b96cb55f
cleaning namespaces
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 10 Nov 2020 16:55:22 +0100 |
parents | a4418a489e86 |
children | 9ac2a65d4172 |
comparison
equal
deleted
inserted
replaced
1639:5cdc5b98f14d | 1640:52b8b96cb55f |
---|---|
43 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | 43 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); |
44 } | 44 } |
45 | 45 |
46 } | 46 } |
47 | 47 |
48 virtual void Handle(const OrthancStone::OrthancRestApiCommand::SuccessMessage& message) ORTHANC_OVERRIDE | 48 virtual void Handle(const OrthancRestApiCommand::SuccessMessage& message) ORTHANC_OVERRIDE |
49 { | 49 { |
50 // Complete the DICOM tags with just-received "Grid Frame Offset Vector" | 50 // Complete the DICOM tags with just-received "Grid Frame Offset Vector" |
51 std::string s = Orthanc::Toolbox::StripSpaces(message.GetAnswer()); | 51 std::string s = Orthanc::Toolbox::StripSpaces(message.GetAnswer()); |
52 dicom_->SetValue(Orthanc::DICOM_TAG_GRID_FRAME_OFFSET_VECTOR, s, false); | 52 dicom_->SetValue(Orthanc::DICOM_TAG_GRID_FRAME_OFFSET_VECTOR, s, false); |
53 | 53 |
77 explicit LoadGeometry(OrthancMultiframeVolumeLoader& that) : | 77 explicit LoadGeometry(OrthancMultiframeVolumeLoader& that) : |
78 State(that) | 78 State(that) |
79 { | 79 { |
80 } | 80 } |
81 | 81 |
82 virtual void Handle(const OrthancStone::OrthancRestApiCommand::SuccessMessage& message) | 82 virtual void Handle(const OrthancRestApiCommand::SuccessMessage& message) |
83 { | 83 { |
84 OrthancMultiframeVolumeLoader& loader = GetLoader<OrthancMultiframeVolumeLoader>(); | 84 OrthancMultiframeVolumeLoader& loader = GetLoader<OrthancMultiframeVolumeLoader>(); |
85 | 85 |
86 Json::Value body; | 86 Json::Value body; |
87 message.ParseJsonBody(body); | 87 message.ParseJsonBody(body); |
92 } | 92 } |
93 | 93 |
94 std::unique_ptr<Orthanc::DicomMap> dicom(new Orthanc::DicomMap); | 94 std::unique_ptr<Orthanc::DicomMap> dicom(new Orthanc::DicomMap); |
95 dicom->FromDicomAsJson(body); | 95 dicom->FromDicomAsJson(body); |
96 | 96 |
97 if (OrthancStone::StringToSopClassUid(GetSopClassUid(*dicom)) == OrthancStone::SopClassUid_RTDose) | 97 if (StringToSopClassUid(GetSopClassUid(*dicom)) == SopClassUid_RTDose) |
98 { | 98 { |
99 // Download the "Grid Frame Offset Vector" DICOM tag, that is | 99 // Download the "Grid Frame Offset Vector" DICOM tag, that is |
100 // mandatory for RT-DOSE, but is too long to be returned by default | 100 // mandatory for RT-DOSE, but is too long to be returned by default |
101 | 101 |
102 std::unique_ptr<OrthancStone::OrthancRestApiCommand> command(new OrthancStone::OrthancRestApiCommand); | 102 std::unique_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand); |
103 command->SetUri("/instances/" + loader.GetInstanceId() + "/content/" + | 103 command->SetUri("/instances/" + loader.GetInstanceId() + "/content/" + |
104 Orthanc::DICOM_TAG_GRID_FRAME_OFFSET_VECTOR.Format()); | 104 Orthanc::DICOM_TAG_GRID_FRAME_OFFSET_VECTOR.Format()); |
105 command->AcquirePayload(new LoadRTDoseGeometry(loader, dicom.release())); | 105 command->AcquirePayload(new LoadRTDoseGeometry(loader, dicom.release())); |
106 | 106 |
107 Schedule(command.release()); | 107 Schedule(command.release()); |
119 explicit LoadTransferSyntax(OrthancMultiframeVolumeLoader& that) : | 119 explicit LoadTransferSyntax(OrthancMultiframeVolumeLoader& that) : |
120 State(that) | 120 State(that) |
121 { | 121 { |
122 } | 122 } |
123 | 123 |
124 virtual void Handle(const OrthancStone::OrthancRestApiCommand::SuccessMessage& message) | 124 virtual void Handle(const OrthancRestApiCommand::SuccessMessage& message) |
125 { | 125 { |
126 GetLoader<OrthancMultiframeVolumeLoader>().SetTransferSyntax(message.GetAnswer()); | 126 GetLoader<OrthancMultiframeVolumeLoader>().SetTransferSyntax(message.GetAnswer()); |
127 } | 127 } |
128 }; | 128 }; |
129 | 129 |
133 explicit LoadUncompressedPixelData(OrthancMultiframeVolumeLoader& that) : | 133 explicit LoadUncompressedPixelData(OrthancMultiframeVolumeLoader& that) : |
134 State(that) | 134 State(that) |
135 { | 135 { |
136 } | 136 } |
137 | 137 |
138 virtual void Handle(const OrthancStone::OrthancRestApiCommand::SuccessMessage& message) | 138 virtual void Handle(const OrthancRestApiCommand::SuccessMessage& message) |
139 { | 139 { |
140 GetLoader<OrthancMultiframeVolumeLoader>().SetUncompressedPixelData(message.GetAnswer()); | 140 GetLoader<OrthancMultiframeVolumeLoader>().SetUncompressedPixelData(message.GetAnswer()); |
141 } | 141 } |
142 }; | 142 }; |
143 | 143 |
170 */ | 170 */ |
171 if (transferSyntaxUid_ == "1.2.840.10008.1.2" || | 171 if (transferSyntaxUid_ == "1.2.840.10008.1.2" || |
172 transferSyntaxUid_ == "1.2.840.10008.1.2.1" || | 172 transferSyntaxUid_ == "1.2.840.10008.1.2.1" || |
173 transferSyntaxUid_ == "1.2.840.10008.1.2.2") | 173 transferSyntaxUid_ == "1.2.840.10008.1.2.2") |
174 { | 174 { |
175 std::unique_ptr<OrthancStone::OrthancRestApiCommand> command(new OrthancStone::OrthancRestApiCommand); | 175 std::unique_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand); |
176 command->SetHttpHeader("Accept-Encoding", "gzip"); | 176 command->SetHttpHeader("Accept-Encoding", "gzip"); |
177 command->SetUri("/instances/" + instanceId_ + "/content/" + | 177 command->SetUri("/instances/" + instanceId_ + "/content/" + |
178 Orthanc::DICOM_TAG_PIXEL_DATA.Format() + "/0"); | 178 Orthanc::DICOM_TAG_PIXEL_DATA.Format() + "/0"); |
179 command->AcquirePayload(new LoadUncompressedPixelData(*this)); | 179 command->AcquirePayload(new LoadUncompressedPixelData(*this)); |
180 Schedule(command.release()); | 180 Schedule(command.release()); |
193 ScheduleFrameDownloads(); | 193 ScheduleFrameDownloads(); |
194 } | 194 } |
195 | 195 |
196 void OrthancMultiframeVolumeLoader::SetGeometry(const Orthanc::DicomMap& dicom) | 196 void OrthancMultiframeVolumeLoader::SetGeometry(const Orthanc::DicomMap& dicom) |
197 { | 197 { |
198 OrthancStone::DicomInstanceParameters parameters(dicom); | 198 DicomInstanceParameters parameters(dicom); |
199 volume_->SetDicomParameters(parameters); | 199 volume_->SetDicomParameters(parameters); |
200 | 200 |
201 Orthanc::PixelFormat format; | 201 Orthanc::PixelFormat format; |
202 if (!parameters.GetImageInformation().ExtractPixelFormat(format, true)) | 202 if (!parameters.GetImageInformation().ExtractPixelFormat(format, true)) |
203 { | 203 { |
205 } | 205 } |
206 | 206 |
207 double spacingZ; | 207 double spacingZ; |
208 switch (parameters.GetSopClassUid()) | 208 switch (parameters.GetSopClassUid()) |
209 { | 209 { |
210 case OrthancStone::SopClassUid_RTDose: | 210 case SopClassUid_RTDose: |
211 spacingZ = parameters.GetSliceThickness(); | 211 spacingZ = parameters.GetSliceThickness(); |
212 break; | 212 break; |
213 | 213 |
214 default: | 214 default: |
215 throw Orthanc::OrthancException( | 215 throw Orthanc::OrthancException( |
220 const unsigned int width = parameters.GetImageInformation().GetWidth(); | 220 const unsigned int width = parameters.GetImageInformation().GetWidth(); |
221 const unsigned int height = parameters.GetImageInformation().GetHeight(); | 221 const unsigned int height = parameters.GetImageInformation().GetHeight(); |
222 const unsigned int depth = parameters.GetImageInformation().GetNumberOfFrames(); | 222 const unsigned int depth = parameters.GetImageInformation().GetNumberOfFrames(); |
223 | 223 |
224 { | 224 { |
225 OrthancStone::VolumeImageGeometry geometry; | 225 VolumeImageGeometry geometry; |
226 geometry.SetSizeInVoxels(width, height, depth); | 226 geometry.SetSizeInVoxels(width, height, depth); |
227 geometry.SetAxialGeometry(parameters.GetGeometry()); | 227 geometry.SetAxialGeometry(parameters.GetGeometry()); |
228 geometry.SetVoxelDimensions(parameters.GetPixelSpacingX(), | 228 geometry.SetVoxelDimensions(parameters.GetPixelSpacingX(), |
229 parameters.GetPixelSpacingY(), spacingZ); | 229 parameters.GetPixelSpacingY(), spacingZ); |
230 volume_->Initialize(geometry, format, true /* Do compute range */); | 230 volume_->Initialize(geometry, format, true /* Do compute range */); |
234 | 234 |
235 ScheduleFrameDownloads(); | 235 ScheduleFrameDownloads(); |
236 | 236 |
237 | 237 |
238 | 238 |
239 BroadcastMessage(OrthancStone::DicomVolumeImage::GeometryReadyMessage(*volume_)); | 239 BroadcastMessage(DicomVolumeImage::GeometryReadyMessage(*volume_)); |
240 } | 240 } |
241 | 241 |
242 | 242 |
243 ORTHANC_FORCE_INLINE | 243 ORTHANC_FORCE_INLINE |
244 static void CopyPixel(uint32_t& target, const void* source) | 244 static void CopyPixel(uint32_t& target, const void* source) |
265 | 265 |
266 template <typename T> | 266 template <typename T> |
267 void OrthancMultiframeVolumeLoader::CopyPixelDataAndComputeDistribution( | 267 void OrthancMultiframeVolumeLoader::CopyPixelDataAndComputeDistribution( |
268 const std::string& pixelData, std::map<T,uint64_t>& distribution) | 268 const std::string& pixelData, std::map<T,uint64_t>& distribution) |
269 { | 269 { |
270 OrthancStone::ImageBuffer3D& target = volume_->GetPixelData(); | 270 ImageBuffer3D& target = volume_->GetPixelData(); |
271 | 271 |
272 const unsigned int bpp = target.GetBytesPerPixel(); | 272 const unsigned int bpp = target.GetBytesPerPixel(); |
273 const unsigned int width = target.GetWidth(); | 273 const unsigned int width = target.GetWidth(); |
274 const unsigned int height = target.GetHeight(); | 274 const unsigned int height = target.GetHeight(); |
275 const unsigned int depth = target.GetDepth(); | 275 const unsigned int depth = target.GetDepth(); |
307 { | 307 { |
308 const uint8_t* source = reinterpret_cast<const uint8_t*>(pixelData.c_str()); | 308 const uint8_t* source = reinterpret_cast<const uint8_t*>(pixelData.c_str()); |
309 | 309 |
310 for (unsigned int z = 0; z < depth; z++) | 310 for (unsigned int z = 0; z < depth; z++) |
311 { | 311 { |
312 OrthancStone::ImageBuffer3D::SliceWriter writer(target, OrthancStone::VolumeProjection_Axial, z); | 312 ImageBuffer3D::SliceWriter writer(target, VolumeProjection_Axial, z); |
313 | 313 |
314 assert(writer.GetAccessor().GetWidth() == width && | 314 assert(writer.GetAccessor().GetWidth() == width && |
315 writer.GetAccessor().GetHeight() == height); | 315 writer.GetAccessor().GetHeight() == height); |
316 #if 0 | 316 #if 0 |
317 for (unsigned int y = 0; y < height; y++) | 317 for (unsigned int y = 0; y < height; y++) |
364 { | 364 { |
365 LOG(ERROR) << "ComputeMinMaxWithOutlierRejection -- Volume image empty."; | 365 LOG(ERROR) << "ComputeMinMaxWithOutlierRejection -- Volume image empty."; |
366 } | 366 } |
367 else | 367 else |
368 { | 368 { |
369 OrthancStone::ImageBuffer3D& target = volume_->GetPixelData(); | 369 ImageBuffer3D& target = volume_->GetPixelData(); |
370 | 370 |
371 const uint64_t width = target.GetWidth(); | 371 const uint64_t width = target.GetWidth(); |
372 const uint64_t height = target.GetHeight(); | 372 const uint64_t height = target.GetHeight(); |
373 const uint64_t depth = target.GetDepth(); | 373 const uint64_t depth = target.GetDepth(); |
374 const uint64_t voxelCount = width * height * depth; | 374 const uint64_t voxelCount = width * height * depth; |
515 } | 515 } |
516 | 516 |
517 volume_->IncrementRevision(); | 517 volume_->IncrementRevision(); |
518 | 518 |
519 pixelDataLoaded_ = true; | 519 pixelDataLoaded_ = true; |
520 BroadcastMessage(OrthancStone::DicomVolumeImage::ContentUpdatedMessage(*volume_)); | 520 BroadcastMessage(DicomVolumeImage::ContentUpdatedMessage(*volume_)); |
521 } | 521 } |
522 | 522 |
523 bool OrthancMultiframeVolumeLoader::HasGeometry() const | 523 bool OrthancMultiframeVolumeLoader::HasGeometry() const |
524 { | 524 { |
525 return volume_->HasGeometry(); | 525 return volume_->HasGeometry(); |
526 } | 526 } |
527 | 527 |
528 const OrthancStone::VolumeImageGeometry& OrthancMultiframeVolumeLoader::GetImageGeometry() const | 528 const VolumeImageGeometry& OrthancMultiframeVolumeLoader::GetImageGeometry() const |
529 { | 529 { |
530 return volume_->GetGeometry(); | 530 return volume_->GetGeometry(); |
531 } | 531 } |
532 | 532 |
533 OrthancMultiframeVolumeLoader::OrthancMultiframeVolumeLoader( | 533 OrthancMultiframeVolumeLoader::OrthancMultiframeVolumeLoader( |
534 OrthancStone::ILoadersContext& loadersContext, | 534 ILoadersContext& loadersContext, |
535 boost::shared_ptr<OrthancStone::DicomVolumeImage> volume, | 535 boost::shared_ptr<DicomVolumeImage> volume, |
536 float outliersHalfRejectionRate) | 536 float outliersHalfRejectionRate) |
537 : LoaderStateMachine(loadersContext) | 537 : LoaderStateMachine(loadersContext) |
538 , volume_(volume) | 538 , volume_(volume) |
539 , pixelDataLoaded_(false) | 539 , pixelDataLoaded_(false) |
540 , outliersHalfRejectionRate_(outliersHalfRejectionRate) | 540 , outliersHalfRejectionRate_(outliersHalfRejectionRate) |
550 } | 550 } |
551 | 551 |
552 | 552 |
553 boost::shared_ptr<OrthancMultiframeVolumeLoader> | 553 boost::shared_ptr<OrthancMultiframeVolumeLoader> |
554 OrthancMultiframeVolumeLoader::Create( | 554 OrthancMultiframeVolumeLoader::Create( |
555 OrthancStone::ILoadersContext& loadersContext, | 555 ILoadersContext& loadersContext, |
556 boost::shared_ptr<OrthancStone::DicomVolumeImage> volume, | 556 boost::shared_ptr<DicomVolumeImage> volume, |
557 float outliersHalfRejectionRate /*= 0.0005*/) | 557 float outliersHalfRejectionRate /*= 0.0005*/) |
558 { | 558 { |
559 boost::shared_ptr<OrthancMultiframeVolumeLoader> obj( | 559 boost::shared_ptr<OrthancMultiframeVolumeLoader> obj( |
560 new OrthancMultiframeVolumeLoader( | 560 new OrthancMultiframeVolumeLoader( |
561 loadersContext, | 561 loadersContext, |
597 Start(); | 597 Start(); |
598 | 598 |
599 instanceId_ = instanceId; | 599 instanceId_ = instanceId; |
600 | 600 |
601 { | 601 { |
602 std::unique_ptr<OrthancStone::OrthancRestApiCommand> command(new OrthancStone::OrthancRestApiCommand); | 602 std::unique_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand); |
603 command->SetHttpHeader("Accept-Encoding", "gzip"); | 603 command->SetHttpHeader("Accept-Encoding", "gzip"); |
604 command->SetUri("/instances/" + instanceId + "/tags"); | 604 command->SetUri("/instances/" + instanceId + "/tags"); |
605 command->AcquirePayload(new LoadGeometry(*this)); | 605 command->AcquirePayload(new LoadGeometry(*this)); |
606 Schedule(command.release()); | 606 Schedule(command.release()); |
607 } | 607 } |
608 | 608 |
609 { | 609 { |
610 std::unique_ptr<OrthancStone::OrthancRestApiCommand> command(new OrthancStone::OrthancRestApiCommand); | 610 std::unique_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand); |
611 command->SetUri("/instances/" + instanceId + "/metadata/TransferSyntax"); | 611 command->SetUri("/instances/" + instanceId + "/metadata/TransferSyntax"); |
612 command->AcquirePayload(new LoadTransferSyntax(*this)); | 612 command->AcquirePayload(new LoadTransferSyntax(*this)); |
613 Schedule(command.release()); | 613 Schedule(command.release()); |
614 } | 614 } |
615 } | 615 } |