Mercurial > hg > orthanc-stone
comparison Framework/Toolbox/OrthancSlicesLoader.cpp @ 119:ba83e38cf3ff wasm
rendering of rt-dose
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 02 Oct 2017 22:01:41 +0200 |
parents | a4d0b6c82b29 |
children | 063f7f3d9f14 |
comparison
equal
deleted
inserted
replaced
118:a4d0b6c82b29 | 119:ba83e38cf3ff |
---|---|
88 return mode_; | 88 return mode_; |
89 } | 89 } |
90 | 90 |
91 SliceImageQuality GetQuality() const | 91 SliceImageQuality GetQuality() const |
92 { | 92 { |
93 assert(mode_ == Mode_LoadImage); | 93 assert(mode_ == Mode_LoadImage || |
94 mode_ == Mode_LoadRawImage); | |
94 return quality_; | 95 return quality_; |
95 } | 96 } |
96 | 97 |
97 unsigned int GetSliceIndex() const | 98 unsigned int GetSliceIndex() const |
98 { | 99 { |
158 const Slice& slice) | 159 const Slice& slice) |
159 { | 160 { |
160 std::auto_ptr<Operation> tmp(new Operation(Mode_LoadRawImage)); | 161 std::auto_ptr<Operation> tmp(new Operation(Mode_LoadRawImage)); |
161 tmp->sliceIndex_ = sliceIndex; | 162 tmp->sliceIndex_ = sliceIndex; |
162 tmp->slice_ = &slice; | 163 tmp->slice_ = &slice; |
164 tmp->quality_ = SliceImageQuality_Full; | |
163 return tmp.release(); | 165 return tmp.release(); |
164 } | 166 } |
165 }; | 167 }; |
166 | 168 |
167 | 169 |
304 frames = 1; | 306 frames = 1; |
305 } | 307 } |
306 | 308 |
307 for (unsigned int frame = 0; frame < frames; frame++) | 309 for (unsigned int frame = 0; frame < frames; frame++) |
308 { | 310 { |
309 Slice slice; | 311 std::auto_ptr<Slice> slice(new Slice); |
310 if (slice.ParseOrthancFrame(dicom, instances[i], frame)) | 312 if (slice->ParseOrthancFrame(dicom, instances[i], frame)) |
311 { | 313 { |
312 slices_.AddSlice(slice); | 314 slices_.AddSlice(slice.release()); |
313 } | 315 } |
314 else | 316 else |
315 { | 317 { |
316 LOG(WARNING) << "Skipping invalid frame " << frame << " within instance " << instances[i]; | 318 LOG(WARNING) << "Skipping invalid frame " << frame << " within instance " << instances[i]; |
317 } | 319 } |
374 | 376 |
375 state_ = State_GeometryReady; | 377 state_ = State_GeometryReady; |
376 | 378 |
377 for (unsigned int frame = 0; frame < frames; frame++) | 379 for (unsigned int frame = 0; frame < frames; frame++) |
378 { | 380 { |
379 Slice slice; | 381 std::auto_ptr<Slice> slice(new Slice); |
380 if (slice.ParseOrthancFrame(dicom, instanceId, frame)) | 382 if (slice->ParseOrthancFrame(dicom, instanceId, frame)) |
381 { | 383 { |
382 slices_.AddSlice(slice); | 384 slices_.AddSlice(slice.release()); |
383 } | 385 } |
384 else | 386 else |
385 { | 387 { |
386 LOG(WARNING) << "Skipping invalid multi-frame instance " << instanceId; | 388 LOG(WARNING) << "Skipping invalid multi-frame instance " << instanceId; |
387 userCallback_.NotifyGeometryError(*this); | 389 userCallback_.NotifyGeometryError(*this); |
411 state_ = State_GeometryReady; | 413 state_ = State_GeometryReady; |
412 | 414 |
413 Orthanc::DicomMap dicom; | 415 Orthanc::DicomMap dicom; |
414 MessagingToolbox::ConvertDataset(dicom, dataset); | 416 MessagingToolbox::ConvertDataset(dicom, dataset); |
415 | 417 |
416 Slice slice; | 418 std::auto_ptr<Slice> slice(new Slice); |
417 if (slice.ParseOrthancFrame(dicom, instanceId, frame)) | 419 if (slice->ParseOrthancFrame(dicom, instanceId, frame)) |
418 { | 420 { |
419 LOG(INFO) << "Loaded instance " << instanceId; | 421 LOG(INFO) << "Loaded instance " << instanceId; |
420 slices_.AddSlice(slice); | 422 slices_.AddSlice(slice.release()); |
421 userCallback_.NotifyGeometryReady(*this); | 423 userCallback_.NotifyGeometryReady(*this); |
422 } | 424 } |
423 else | 425 else |
424 { | 426 { |
425 LOG(WARNING) << "Skipping invalid instance " << instanceId; | 427 LOG(WARNING) << "Skipping invalid instance " << instanceId; |
611 | 613 |
612 Orthanc::ImageProcessing::ShiftScale(*image, offset, scaling); | 614 Orthanc::ImageProcessing::ShiftScale(*image, offset, scaling); |
613 | 615 |
614 NotifySliceImageSuccess(operation, image); | 616 NotifySliceImageSuccess(operation, image); |
615 } | 617 } |
618 | |
619 | |
620 class StringImage : | |
621 public Orthanc::ImageAccessor, | |
622 public boost::noncopyable | |
623 { | |
624 private: | |
625 std::string buffer_; | |
616 | 626 |
617 | 627 public: |
628 StringImage(Orthanc::PixelFormat format, | |
629 unsigned int width, | |
630 unsigned int height, | |
631 std::string& buffer) | |
632 { | |
633 if (buffer.size() != Orthanc::GetBytesPerPixel(format) * width * height) | |
634 { | |
635 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); | |
636 } | |
637 | |
638 buffer_.swap(buffer); // The source buffer is now empty | |
639 | |
640 void* data = (buffer_.empty() ? NULL : &buffer_[0]); | |
641 | |
642 AssignWritable(format, width, height, | |
643 Orthanc::GetBytesPerPixel(format) * width, data); | |
644 } | |
645 }; | |
646 | |
647 | |
618 void OrthancSlicesLoader::ParseSliceRawImage(const Operation& operation, | 648 void OrthancSlicesLoader::ParseSliceRawImage(const Operation& operation, |
619 const void* answer, | 649 const void* answer, |
620 size_t size) | 650 size_t size) |
621 { | 651 { |
622 Orthanc::GzipCompressor compressor; | 652 Orthanc::GzipCompressor compressor; |
623 | 653 |
624 std::string raw; | 654 std::string raw; |
625 compressor.Uncompress(raw, answer, size); | 655 compressor.Uncompress(raw, answer, size); |
626 | 656 |
627 printf("[%d => %d]\n", size, raw.size()); | 657 const Orthanc::DicomImageInformation& info = operation.GetSlice().GetImageInformation(); |
658 unsigned int frame = operation.GetSlice().GetFrame(); | |
659 | |
660 if (info.GetBitsAllocated() == 32 && | |
661 info.GetBitsStored() == 32 && | |
662 info.GetHighBit() == 31 && | |
663 info.GetChannelCount() == 1 && | |
664 !info.IsSigned() && | |
665 info.GetPhotometricInterpretation() == Orthanc::PhotometricInterpretation_Monochrome2 && | |
666 raw.size() == info.GetWidth() * info.GetHeight() * 4) | |
667 { | |
668 // This is the case of RT-DOSE (uint32_t values) | |
669 | |
670 std::auto_ptr<Orthanc::ImageAccessor> image | |
671 (new StringImage(Orthanc::PixelFormat_Grayscale32, info.GetWidth(), | |
672 info.GetHeight(), raw)); | |
673 | |
674 for (unsigned int y = 0; y < image->GetHeight(); y++) | |
675 { | |
676 uint32_t *p = reinterpret_cast<uint32_t*>(image->GetRow(y)); | |
677 for (unsigned int x = 0; x < image->GetWidth(); x++, p++) | |
678 { | |
679 *p = le32toh(*p); | |
680 } | |
681 } | |
682 | |
683 NotifySliceImageSuccess(operation, image); | |
684 } | |
685 else | |
686 { | |
687 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | |
688 } | |
689 | |
628 } | 690 } |
629 | 691 |
630 | 692 |
631 OrthancSlicesLoader::OrthancSlicesLoader(ICallback& callback, | 693 OrthancSlicesLoader::OrthancSlicesLoader(ICallback& callback, |
632 IWebService& orthanc) : | 694 IWebService& orthanc) : |