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/" +