Mercurial > hg > orthanc-stone
comparison Framework/Toolbox/OrthancSlicesLoader.cpp @ 378:814fa32e2fcc
refactoring
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 06 Nov 2018 14:21:02 +0100 |
parents | 8eb4fe74000f |
children | dd4c7e82b4be |
comparison
equal
deleted
inserted
replaced
377:8eb4fe74000f | 378:814fa32e2fcc |
---|---|
171 } | 171 } |
172 | 172 |
173 }; | 173 }; |
174 | 174 |
175 void OrthancSlicesLoader::NotifySliceImageSuccess(const Operation& operation, | 175 void OrthancSlicesLoader::NotifySliceImageSuccess(const Operation& operation, |
176 boost::shared_ptr<Orthanc::ImageAccessor> image) | 176 const Orthanc::ImageAccessor& image) |
177 { | 177 { |
178 if (image.get() == NULL) | 178 OrthancSlicesLoader::SliceImageReadyMessage msg(operation.GetSliceIndex(), operation.GetSlice(), image, operation.GetQuality()); |
179 { | 179 EmitMessage(msg); |
180 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
181 } | |
182 else | |
183 { | |
184 OrthancSlicesLoader::SliceImageReadyMessage msg(operation.GetSliceIndex(), operation.GetSlice(), image, operation.GetQuality()); | |
185 EmitMessage(msg); | |
186 } | |
187 } | 180 } |
188 | 181 |
189 | 182 |
190 void OrthancSlicesLoader::NotifySliceImageError(const Operation& operation) | 183 void OrthancSlicesLoader::NotifySliceImageError(const Operation& operation) |
191 { | 184 { |
339 | 332 |
340 | 333 |
341 void OrthancSlicesLoader::ParseSliceImagePng(const OrthancApiClient::BinaryResponseReadyMessage& message) | 334 void OrthancSlicesLoader::ParseSliceImagePng(const OrthancApiClient::BinaryResponseReadyMessage& message) |
342 { | 335 { |
343 const Operation& operation = dynamic_cast<const OrthancSlicesLoader::Operation&>(message.GetPayload()); | 336 const Operation& operation = dynamic_cast<const OrthancSlicesLoader::Operation&>(message.GetPayload()); |
344 boost::shared_ptr<Orthanc::ImageAccessor> image; | 337 std::auto_ptr<Orthanc::ImageAccessor> image; |
345 | 338 |
346 try | 339 try |
347 { | 340 { |
348 image.reset(new Orthanc::PngReader); | 341 image.reset(new Orthanc::PngReader); |
349 dynamic_cast<Orthanc::PngReader&>(*image).ReadFromMemory(message.GetAnswer(), message.GetAnswerSize()); | 342 dynamic_cast<Orthanc::PngReader&>(*image).ReadFromMemory(message.GetAnswer(), message.GetAnswerSize()); |
373 NotifySliceImageError(operation); | 366 NotifySliceImageError(operation); |
374 return; | 367 return; |
375 } | 368 } |
376 } | 369 } |
377 | 370 |
378 NotifySliceImageSuccess(operation, image); | 371 NotifySliceImageSuccess(operation, *image); |
379 } | 372 } |
380 | 373 |
381 void OrthancSlicesLoader::ParseSliceImagePam(const OrthancApiClient::BinaryResponseReadyMessage& message) | 374 void OrthancSlicesLoader::ParseSliceImagePam(const OrthancApiClient::BinaryResponseReadyMessage& message) |
382 { | 375 { |
383 const Operation& operation = dynamic_cast<const OrthancSlicesLoader::Operation&>(message.GetPayload()); | 376 const Operation& operation = dynamic_cast<const OrthancSlicesLoader::Operation&>(message.GetPayload()); |
384 boost::shared_ptr<Orthanc::ImageAccessor> image; | 377 std::auto_ptr<Orthanc::ImageAccessor> image; |
385 | 378 |
386 try | 379 try |
387 { | 380 { |
388 image.reset(new Orthanc::PamReader); | 381 image.reset(new Orthanc::PamReader); |
389 dynamic_cast<Orthanc::PamReader&>(*image).ReadFromMemory(std::string(reinterpret_cast<const char*>(message.GetAnswer()), message.GetAnswerSize())); | 382 dynamic_cast<Orthanc::PamReader&>(*image).ReadFromMemory(message.GetAnswer(), message.GetAnswerSize()); |
390 } | 383 } |
391 catch (Orthanc::OrthancException&) | 384 catch (Orthanc::OrthancException&) |
392 { | 385 { |
393 NotifySliceImageError(operation); | 386 NotifySliceImageError(operation); |
394 return; | 387 return; |
413 NotifySliceImageError(operation); | 406 NotifySliceImageError(operation); |
414 return; | 407 return; |
415 } | 408 } |
416 } | 409 } |
417 | 410 |
418 NotifySliceImageSuccess(operation, image); | 411 NotifySliceImageSuccess(operation, *image); |
419 } | 412 } |
420 | 413 |
421 | 414 |
422 void OrthancSlicesLoader::ParseSliceImageJpeg(const OrthancApiClient::JsonResponseReadyMessage& message) | 415 void OrthancSlicesLoader::ParseSliceImageJpeg(const OrthancApiClient::JsonResponseReadyMessage& message) |
423 { | 416 { |
459 { | 452 { |
460 isSigned = info["IsSigned"].asBool(); | 453 isSigned = info["IsSigned"].asBool(); |
461 } | 454 } |
462 } | 455 } |
463 | 456 |
464 boost::shared_ptr<Orthanc::ImageAccessor> reader; | 457 std::auto_ptr<Orthanc::ImageAccessor> reader; |
465 | 458 |
466 { | 459 { |
467 std::string jpeg; | 460 std::string jpeg; |
468 //Orthanc::Toolbox::DecodeBase64(jpeg, info["PixelData"].asString()); | 461 //Orthanc::Toolbox::DecodeBase64(jpeg, info["PixelData"].asString()); |
469 jpeg = base64_decode(info["PixelData"].asString()); | 462 jpeg = base64_decode(info["PixelData"].asString()); |
479 return; | 472 return; |
480 } | 473 } |
481 } | 474 } |
482 | 475 |
483 Orthanc::PixelFormat expectedFormat = | 476 Orthanc::PixelFormat expectedFormat = |
484 operation.GetSlice().GetConverter().GetExpectedPixelFormat(); | 477 operation.GetSlice().GetConverter().GetExpectedPixelFormat(); |
485 | 478 |
486 if (reader->GetFormat() == Orthanc::PixelFormat_RGB24) // This is a color image | 479 if (reader->GetFormat() == Orthanc::PixelFormat_RGB24) // This is a color image |
487 { | 480 { |
488 if (expectedFormat != Orthanc::PixelFormat_RGB24) | 481 if (expectedFormat != Orthanc::PixelFormat_RGB24) |
489 { | 482 { |
496 NotifySliceImageError(operation); | 489 NotifySliceImageError(operation); |
497 return; | 490 return; |
498 } | 491 } |
499 else | 492 else |
500 { | 493 { |
501 NotifySliceImageSuccess(operation, reader); | 494 NotifySliceImageSuccess(operation, *reader); |
502 return; | 495 return; |
503 } | 496 } |
504 } | 497 } |
505 | 498 |
506 if (reader->GetFormat() != Orthanc::PixelFormat_Grayscale8) | 499 if (reader->GetFormat() != Orthanc::PixelFormat_Grayscale8) |
516 NotifySliceImageError(operation); | 509 NotifySliceImageError(operation); |
517 return; | 510 return; |
518 } | 511 } |
519 else | 512 else |
520 { | 513 { |
521 NotifySliceImageSuccess(operation, reader); | 514 NotifySliceImageSuccess(operation, *reader); |
522 return; | 515 return; |
523 } | 516 } |
524 } | 517 } |
525 | 518 |
526 int32_t stretchLow = 0; | 519 int32_t stretchLow = 0; |
546 NotifySliceImageError(operation); | 539 NotifySliceImageError(operation); |
547 return; | 540 return; |
548 } | 541 } |
549 | 542 |
550 // Decode a grayscale JPEG 8bpp image coming from the Web viewer | 543 // Decode a grayscale JPEG 8bpp image coming from the Web viewer |
551 boost::shared_ptr<Orthanc::ImageAccessor> image | 544 std::auto_ptr<Orthanc::ImageAccessor> image |
552 (new Orthanc::Image(expectedFormat, reader->GetWidth(), reader->GetHeight(), false)); | 545 (new Orthanc::Image(expectedFormat, reader->GetWidth(), reader->GetHeight(), false)); |
553 | 546 |
554 Orthanc::ImageProcessing::Convert(*image, *reader); | 547 Orthanc::ImageProcessing::Convert(*image, *reader); |
555 reader.reset(); | 548 reader.reset(); |
556 | 549 |
557 float scaling = static_cast<float>(stretchHigh - stretchLow) / 255.0f; | 550 float scaling = static_cast<float>(stretchHigh - stretchLow) / 255.0f; |
560 { | 553 { |
561 float offset = static_cast<float>(stretchLow) / scaling; | 554 float offset = static_cast<float>(stretchLow) / scaling; |
562 Orthanc::ImageProcessing::ShiftScale(*image, offset, scaling, true); | 555 Orthanc::ImageProcessing::ShiftScale(*image, offset, scaling, true); |
563 } | 556 } |
564 | 557 |
565 NotifySliceImageSuccess(operation, image); | 558 NotifySliceImageSuccess(operation, *image); |
566 } | 559 } |
567 | 560 |
568 | 561 |
569 class StringImage : public Orthanc::ImageAccessor | 562 class StringImage : public Orthanc::ImageAccessor |
570 { | 563 { |
609 info.GetPhotometricInterpretation() == Orthanc::PhotometricInterpretation_Monochrome2 && | 602 info.GetPhotometricInterpretation() == Orthanc::PhotometricInterpretation_Monochrome2 && |
610 raw.size() == info.GetWidth() * info.GetHeight() * 4) | 603 raw.size() == info.GetWidth() * info.GetHeight() * 4) |
611 { | 604 { |
612 // This is the case of RT-DOSE (uint32_t values) | 605 // This is the case of RT-DOSE (uint32_t values) |
613 | 606 |
614 boost::shared_ptr<Orthanc::ImageAccessor> image | 607 std::auto_ptr<Orthanc::ImageAccessor> image |
615 (new StringImage(Orthanc::PixelFormat_Grayscale32, info.GetWidth(), | 608 (new StringImage(Orthanc::PixelFormat_Grayscale32, info.GetWidth(), |
616 info.GetHeight(), raw)); | 609 info.GetHeight(), raw)); |
617 | 610 |
618 // TODO - Only for big endian | 611 // TODO - Only for big endian |
619 for (unsigned int y = 0; y < image->GetHeight(); y++) | 612 for (unsigned int y = 0; y < image->GetHeight(); y++) |
620 { | 613 { |
621 uint32_t *p = reinterpret_cast<uint32_t*>(image->GetRow(y)); | 614 uint32_t *p = reinterpret_cast<uint32_t*>(image->GetRow(y)); |
623 { | 616 { |
624 *p = le32toh(*p); | 617 *p = le32toh(*p); |
625 } | 618 } |
626 } | 619 } |
627 | 620 |
628 NotifySliceImageSuccess(operation, image); | 621 NotifySliceImageSuccess(operation, *image); |
629 } | 622 } |
630 else if (info.GetBitsAllocated() == 16 && | 623 else if (info.GetBitsAllocated() == 16 && |
631 info.GetBitsStored() == 16 && | 624 info.GetBitsStored() == 16 && |
632 info.GetHighBit() == 15 && | 625 info.GetHighBit() == 15 && |
633 info.GetChannelCount() == 1 && | 626 info.GetChannelCount() == 1 && |
634 !info.IsSigned() && | 627 !info.IsSigned() && |
635 info.GetPhotometricInterpretation() == Orthanc::PhotometricInterpretation_Monochrome2 && | 628 info.GetPhotometricInterpretation() == Orthanc::PhotometricInterpretation_Monochrome2 && |
636 raw.size() == info.GetWidth() * info.GetHeight() * 2) | 629 raw.size() == info.GetWidth() * info.GetHeight() * 2) |
637 { | 630 { |
638 boost::shared_ptr<Orthanc::ImageAccessor> image | 631 std::auto_ptr<Orthanc::ImageAccessor> image |
639 (new StringImage(Orthanc::PixelFormat_Grayscale16, info.GetWidth(), | 632 (new StringImage(Orthanc::PixelFormat_Grayscale16, info.GetWidth(), |
640 info.GetHeight(), raw)); | 633 info.GetHeight(), raw)); |
641 | 634 |
642 // TODO - Big endian ? | 635 // TODO - Big endian ? |
643 | 636 |
644 NotifySliceImageSuccess(operation, image); | 637 NotifySliceImageSuccess(operation, *image); |
645 } | 638 } |
646 else | 639 else |
647 { | 640 { |
648 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | 641 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
649 } | 642 } |
762 std::string uri = ("/instances/" + slice.GetOrthancInstanceId() + "/frames/" + | 755 std::string uri = ("/instances/" + slice.GetOrthancInstanceId() + "/frames/" + |
763 boost::lexical_cast<std::string>(slice.GetFrame())); | 756 boost::lexical_cast<std::string>(slice.GetFrame())); |
764 | 757 |
765 switch (slice.GetConverter().GetExpectedPixelFormat()) | 758 switch (slice.GetConverter().GetExpectedPixelFormat()) |
766 { | 759 { |
767 case Orthanc::PixelFormat_RGB24: | 760 case Orthanc::PixelFormat_RGB24: |
768 uri += "/preview"; | 761 uri += "/preview"; |
769 break; | 762 break; |
770 | 763 |
771 case Orthanc::PixelFormat_Grayscale16: | 764 case Orthanc::PixelFormat_Grayscale16: |
772 uri += "/image-uint16"; | 765 uri += "/image-uint16"; |
773 break; | 766 break; |
774 | 767 |
775 case Orthanc::PixelFormat_SignedGrayscale16: | 768 case Orthanc::PixelFormat_SignedGrayscale16: |
776 uri += "/image-int16"; | 769 uri += "/image-int16"; |
777 break; | 770 break; |
778 | 771 |
779 default: | 772 default: |
780 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | 773 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
781 } | 774 } |
782 | 775 |
783 orthanc_.GetBinaryAsync(uri, "image/png", | 776 orthanc_.GetBinaryAsync(uri, "image/png", |
784 new Callable<OrthancSlicesLoader, OrthancApiClient::BinaryResponseReadyMessage>(*this, &OrthancSlicesLoader::ParseSliceImagePng), | 777 new Callable<OrthancSlicesLoader, OrthancApiClient::BinaryResponseReadyMessage>(*this, &OrthancSlicesLoader::ParseSliceImagePng), |
785 new Callable<OrthancSlicesLoader, OrthancApiClient::HttpErrorMessage>(*this, &OrthancSlicesLoader::OnSliceImageError), | 778 new Callable<OrthancSlicesLoader, OrthancApiClient::HttpErrorMessage>(*this, &OrthancSlicesLoader::OnSliceImageError), |
792 std::string uri = ("/instances/" + slice.GetOrthancInstanceId() + "/frames/" + | 785 std::string uri = ("/instances/" + slice.GetOrthancInstanceId() + "/frames/" + |
793 boost::lexical_cast<std::string>(slice.GetFrame())); | 786 boost::lexical_cast<std::string>(slice.GetFrame())); |
794 | 787 |
795 switch (slice.GetConverter().GetExpectedPixelFormat()) | 788 switch (slice.GetConverter().GetExpectedPixelFormat()) |
796 { | 789 { |
797 case Orthanc::PixelFormat_RGB24: | 790 case Orthanc::PixelFormat_RGB24: |
798 uri += "/preview"; | 791 uri += "/preview"; |
799 break; | 792 break; |
800 | 793 |
801 case Orthanc::PixelFormat_Grayscale16: | 794 case Orthanc::PixelFormat_Grayscale16: |
802 uri += "/image-uint16"; | 795 uri += "/image-uint16"; |
803 break; | 796 break; |
804 | 797 |
805 case Orthanc::PixelFormat_SignedGrayscale16: | 798 case Orthanc::PixelFormat_SignedGrayscale16: |
806 uri += "/image-int16"; | 799 uri += "/image-int16"; |
807 break; | 800 break; |
808 | 801 |
809 default: | 802 default: |
810 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | 803 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
811 } | 804 } |
812 | 805 |
813 orthanc_.GetBinaryAsync(uri, "image/x-portable-arbitrarymap", | 806 orthanc_.GetBinaryAsync(uri, "image/x-portable-arbitrarymap", |
814 new Callable<OrthancSlicesLoader, OrthancApiClient::BinaryResponseReadyMessage>(*this, &OrthancSlicesLoader::ParseSliceImagePam), | 807 new Callable<OrthancSlicesLoader, OrthancApiClient::BinaryResponseReadyMessage>(*this, &OrthancSlicesLoader::ParseSliceImagePam), |
815 new Callable<OrthancSlicesLoader, OrthancApiClient::HttpErrorMessage>(*this, &OrthancSlicesLoader::OnSliceImageError), | 808 new Callable<OrthancSlicesLoader, OrthancApiClient::HttpErrorMessage>(*this, &OrthancSlicesLoader::OnSliceImageError), |
824 { | 817 { |
825 unsigned int value; | 818 unsigned int value; |
826 | 819 |
827 switch (quality) | 820 switch (quality) |
828 { | 821 { |
829 case SliceImageQuality_Jpeg50: | 822 case SliceImageQuality_Jpeg50: |
830 value = 50; | 823 value = 50; |
831 break; | 824 break; |
832 | 825 |
833 case SliceImageQuality_Jpeg90: | 826 case SliceImageQuality_Jpeg90: |
834 value = 90; | 827 value = 90; |
835 break; | 828 break; |
836 | 829 |
837 case SliceImageQuality_Jpeg95: | 830 case SliceImageQuality_Jpeg95: |
838 value = 95; | 831 value = 95; |
839 break; | 832 break; |
840 | 833 |
841 default: | 834 default: |
842 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | 835 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
843 } | 836 } |
844 | 837 |
845 // This requires the official Web viewer plugin to be installed! | 838 // This requires the official Web viewer plugin to be installed! |
846 std::string uri = ("/web-viewer/instances/jpeg" + | 839 std::string uri = ("/web-viewer/instances/jpeg" + |
847 boost::lexical_cast<std::string>(value) + | 840 boost::lexical_cast<std::string>(value) + |
868 | 861 |
869 if (slice.HasOrthancDecoding()) | 862 if (slice.HasOrthancDecoding()) |
870 { | 863 { |
871 switch (quality) | 864 switch (quality) |
872 { | 865 { |
873 case SliceImageQuality_FullPng: | 866 case SliceImageQuality_FullPng: |
874 ScheduleSliceImagePng(slice, index); | 867 ScheduleSliceImagePng(slice, index); |
875 break; | 868 break; |
876 case SliceImageQuality_FullPam: | 869 case SliceImageQuality_FullPam: |
877 ScheduleSliceImagePam(slice, index); | 870 ScheduleSliceImagePam(slice, index); |
878 break; | 871 break; |
879 default: | 872 default: |
880 ScheduleSliceImageJpeg(slice, index, quality); | 873 ScheduleSliceImageJpeg(slice, index, quality); |
881 } | 874 } |
882 } | 875 } |
883 else | 876 else |
884 { | 877 { |
885 std::string uri = ("/instances/" + slice.GetOrthancInstanceId() + "/frames/" + | 878 std::string uri = ("/instances/" + slice.GetOrthancInstanceId() + "/frames/" + |