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) :