Mercurial > hg > orthanc-stone
diff Framework/Loaders/OrthancMultiframeVolumeLoader.cpp @ 1381:f4a06ad1580b
Branch broker is now the new default
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Wed, 22 Apr 2020 14:05:47 +0200 |
parents | 8a0a62189f46 104e0b0f2316 |
children | 30deba7bc8e2 75ac66d5f4b2 |
line wrap: on
line diff
--- a/Framework/Loaders/OrthancMultiframeVolumeLoader.cpp Mon Apr 20 18:26:32 2020 +0200 +++ b/Framework/Loaders/OrthancMultiframeVolumeLoader.cpp Wed Apr 22 14:05:47 2020 +0200 @@ -44,7 +44,7 @@ } - virtual void Handle(const OrthancRestApiCommand::SuccessMessage& message) + virtual void Handle(const OrthancStone::OrthancRestApiCommand::SuccessMessage& message) { // Complete the DICOM tags with just-received "Grid Frame Offset Vector" std::string s = Orthanc::Toolbox::StripSpaces(message.GetAnswer()); @@ -78,7 +78,7 @@ { } - virtual void Handle(const OrthancRestApiCommand::SuccessMessage& message) + virtual void Handle(const OrthancStone::OrthancRestApiCommand::SuccessMessage& message) { OrthancMultiframeVolumeLoader& loader = GetLoader<OrthancMultiframeVolumeLoader>(); @@ -93,15 +93,15 @@ std::unique_ptr<Orthanc::DicomMap> dicom(new Orthanc::DicomMap); dicom->FromDicomAsJson(body); - if (StringToSopClassUid(GetSopClassUid(*dicom)) == SopClassUid_RTDose) + if (OrthancStone::StringToSopClassUid(GetSopClassUid(*dicom)) == OrthancStone::SopClassUid_RTDose) { // Download the "Grid Frame Offset Vector" DICOM tag, that is // mandatory for RT-DOSE, but is too long to be returned by default - std::unique_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand); + std::unique_ptr<OrthancStone::OrthancRestApiCommand> command(new OrthancStone::OrthancRestApiCommand); command->SetUri("/instances/" + loader.GetInstanceId() + "/content/" + Orthanc::DICOM_TAG_GRID_FRAME_OFFSET_VECTOR.Format()); - command->SetPayload(new LoadRTDoseGeometry(loader, dicom.release())); + command->AcquirePayload(new LoadRTDoseGeometry(loader, dicom.release())); Schedule(command.release()); } @@ -120,7 +120,7 @@ { } - virtual void Handle(const OrthancRestApiCommand::SuccessMessage& message) + virtual void Handle(const OrthancStone::OrthancRestApiCommand::SuccessMessage& message) { GetLoader<OrthancMultiframeVolumeLoader>().SetTransferSyntax(message.GetAnswer()); } @@ -134,7 +134,7 @@ { } - virtual void Handle(const OrthancRestApiCommand::SuccessMessage& message) + virtual void Handle(const OrthancStone::OrthancRestApiCommand::SuccessMessage& message) { GetLoader<OrthancMultiframeVolumeLoader>().SetUncompressedPixelData(message.GetAnswer()); } @@ -171,11 +171,11 @@ transferSyntaxUid_ == "1.2.840.10008.1.2.1" || transferSyntaxUid_ == "1.2.840.10008.1.2.2") { - std::unique_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand); + std::unique_ptr<OrthancStone::OrthancRestApiCommand> command(new OrthancStone::OrthancRestApiCommand); command->SetHttpHeader("Accept-Encoding", "gzip"); command->SetUri("/instances/" + instanceId_ + "/content/" + Orthanc::DICOM_TAG_PIXEL_DATA.Format() + "/0"); - command->SetPayload(new LoadUncompressedPixelData(*this)); + command->AcquirePayload(new LoadUncompressedPixelData(*this)); Schedule(command.release()); } else @@ -194,7 +194,7 @@ void OrthancMultiframeVolumeLoader::SetGeometry(const Orthanc::DicomMap& dicom) { - DicomInstanceParameters parameters(dicom); + OrthancStone::DicomInstanceParameters parameters(dicom); volume_->SetDicomParameters(parameters); Orthanc::PixelFormat format; @@ -206,7 +206,7 @@ double spacingZ; switch (parameters.GetSopClassUid()) { - case SopClassUid_RTDose: + case OrthancStone::SopClassUid_RTDose: spacingZ = parameters.GetThickness(); break; @@ -221,7 +221,7 @@ const unsigned int depth = parameters.GetImageInformation().GetNumberOfFrames(); { - VolumeImageGeometry geometry; + OrthancStone::VolumeImageGeometry geometry; geometry.SetSizeInVoxels(width, height, depth); geometry.SetAxialGeometry(parameters.GetGeometry()); geometry.SetVoxelDimensions(parameters.GetPixelSpacingX(), @@ -235,7 +235,7 @@ - BroadcastMessage(DicomVolumeImage::GeometryReadyMessage(*volume_)); + BroadcastMessage(OrthancStone::DicomVolumeImage::GeometryReadyMessage(*volume_)); } @@ -266,7 +266,7 @@ void OrthancMultiframeVolumeLoader::CopyPixelDataAndComputeDistribution( const std::string& pixelData, std::map<T,uint64_t>& distribution) { - ImageBuffer3D& target = volume_->GetPixelData(); + OrthancStone::ImageBuffer3D& target = volume_->GetPixelData(); const unsigned int bpp = target.GetBytesPerPixel(); const unsigned int width = target.GetWidth(); @@ -308,11 +308,11 @@ for (unsigned int z = 0; z < depth; z++) { - ImageBuffer3D::SliceWriter writer(target, VolumeProjection_Axial, z); + OrthancStone::ImageBuffer3D::SliceWriter writer(target, OrthancStone::VolumeProjection_Axial, z); assert(writer.GetAccessor().GetWidth() == width && writer.GetAccessor().GetHeight() == height); - +#if 0 for (unsigned int y = 0; y < height; y++) { assert(sizeof(T) == Orthanc::GetBytesPerPixel(target.GetFormat())); @@ -329,6 +329,28 @@ source += bpp; } } +#else + // optimized version (fixed) as of 2020-04-15 + unsigned int pitch = writer.GetAccessor().GetPitch(); + T* targetAddrLine = reinterpret_cast<T*>(writer.GetAccessor().GetRow(0)); + assert(sizeof(T) == Orthanc::GetBytesPerPixel(target.GetFormat())); + + for (unsigned int y = 0; y < height; y++) + { + T* targetAddrPix = targetAddrLine; + for (unsigned int x = 0; x < width; x++) + { + CopyPixel(*targetAddrPix, source); + + distribution[*targetAddrPix] += 1; + + targetAddrPix++; + source += bpp; + } + uint8_t* targetAddrLineBytes = reinterpret_cast<uint8_t*>(targetAddrLine) + pitch; + targetAddrLine = reinterpret_cast<T*>(targetAddrLineBytes); + } +#endif } } } @@ -343,7 +365,7 @@ } else { - ImageBuffer3D& target = volume_->GetPixelData(); + OrthancStone::ImageBuffer3D& target = volume_->GetPixelData(); const uint64_t width = target.GetWidth(); const uint64_t height = target.GetHeight(); @@ -494,7 +516,7 @@ volume_->IncrementRevision(); pixelDataLoaded_ = true; - BroadcastMessage(DicomVolumeImage::ContentUpdatedMessage(*volume_)); + BroadcastMessage(OrthancStone::DicomVolumeImage::ContentUpdatedMessage(*volume_)); } bool OrthancMultiframeVolumeLoader::HasGeometry() const @@ -508,19 +530,17 @@ } OrthancMultiframeVolumeLoader::OrthancMultiframeVolumeLoader( - boost::shared_ptr<DicomVolumeImage> volume, - IOracle& oracle, - IObservable& oracleObservable, - float outliersHalfRejectionRate) : - LoaderStateMachine(oracle, oracleObservable), - IObservable(oracleObservable.GetBroker()), - volume_(volume), - pixelDataLoaded_(false), - outliersHalfRejectionRate_(outliersHalfRejectionRate), - distributionRawMin_(0), - distributionRawMax_(0), - computedDistributionMin_(0), - computedDistributionMax_(0) + OrthancStone::ILoadersContext& loadersContext, + boost::shared_ptr<OrthancStone::DicomVolumeImage> volume, + float outliersHalfRejectionRate) + : LoaderStateMachine(loadersContext) + , volume_(volume) + , pixelDataLoaded_(false) + , outliersHalfRejectionRate_(outliersHalfRejectionRate) + , distributionRawMin_(0) + , distributionRawMax_(0) + , computedDistributionMin_(0) + , computedDistributionMax_(0) { if (volume.get() == NULL) { @@ -528,12 +548,27 @@ } } + + boost::shared_ptr<OrthancMultiframeVolumeLoader> + OrthancMultiframeVolumeLoader::Create( + OrthancStone::ILoadersContext& loadersContext, + boost::shared_ptr<OrthancStone::DicomVolumeImage> volume, + float outliersHalfRejectionRate /*= 0.0005*/) + { + boost::shared_ptr<OrthancMultiframeVolumeLoader> obj( + new OrthancMultiframeVolumeLoader( + loadersContext, + volume, + outliersHalfRejectionRate)); + obj->LoaderStateMachine::PostConstructor(); + return obj; + } + OrthancMultiframeVolumeLoader::~OrthancMultiframeVolumeLoader() { LOG(TRACE) << "OrthancMultiframeVolumeLoader::~OrthancMultiframeVolumeLoader()"; } - - + void OrthancMultiframeVolumeLoader::GetDistributionMinMax (float& minValue, float& maxValue) const { @@ -563,17 +598,17 @@ instanceId_ = instanceId; { - std::unique_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand); + std::unique_ptr<OrthancStone::OrthancRestApiCommand> command(new OrthancStone::OrthancRestApiCommand); command->SetHttpHeader("Accept-Encoding", "gzip"); command->SetUri("/instances/" + instanceId + "/tags"); - command->SetPayload(new LoadGeometry(*this)); + command->AcquirePayload(new LoadGeometry(*this)); Schedule(command.release()); } { - std::unique_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand); + std::unique_ptr<OrthancStone::OrthancRestApiCommand> command(new OrthancStone::OrthancRestApiCommand); command->SetUri("/instances/" + instanceId + "/metadata/TransferSyntax"); - command->SetPayload(new LoadTransferSyntax(*this)); + command->AcquirePayload(new LoadTransferSyntax(*this)); Schedule(command.release()); } }