Mercurial > hg > orthanc
comparison Plugins/Engine/OrthancPlugins.cpp @ 3916:0e3849268a55 transcoding
new plugin SDK primitives related to OrthancPluginDicomInstance
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 11 May 2020 21:07:36 +0200 |
parents | f0dd5ded8927 |
children | 6f11b3233a06 |
comparison
equal
deleted
inserted
replaced
3915:7e33516965f8 | 3916:0e3849268a55 |
---|---|
1759 pluginOutput.Close(error, GetErrorDictionary()); | 1759 pluginOutput.Close(error, GetErrorDictionary()); |
1760 return true; | 1760 return true; |
1761 } | 1761 } |
1762 | 1762 |
1763 | 1763 |
1764 class OrthancPlugins::IDicomInstance : public boost::noncopyable | |
1765 { | |
1766 public: | |
1767 virtual ~IDicomInstance() | |
1768 { | |
1769 } | |
1770 | |
1771 virtual bool CanBeFreed() const = 0; | |
1772 | |
1773 virtual const DicomInstanceToStore& GetInstance() const = 0; | |
1774 }; | |
1775 | |
1776 | |
1777 class OrthancPlugins::DicomInstanceFromCallback : public IDicomInstance | |
1778 { | |
1779 private: | |
1780 const DicomInstanceToStore& instance_; | |
1781 | |
1782 public: | |
1783 DicomInstanceFromCallback(const DicomInstanceToStore& instance) : | |
1784 instance_(instance) | |
1785 { | |
1786 } | |
1787 | |
1788 virtual bool CanBeFreed() const ORTHANC_OVERRIDE | |
1789 { | |
1790 return false; | |
1791 } | |
1792 | |
1793 virtual const DicomInstanceToStore& GetInstance() const ORTHANC_OVERRIDE | |
1794 { | |
1795 return instance_; | |
1796 }; | |
1797 }; | |
1798 | |
1799 | |
1800 class OrthancPlugins::DicomInstanceFromBuffer : public IDicomInstance | |
1801 { | |
1802 private: | |
1803 std::string buffer_; | |
1804 DicomInstanceToStore instance_; | |
1805 | |
1806 public: | |
1807 DicomInstanceFromBuffer(const void* buffer, | |
1808 size_t size) | |
1809 { | |
1810 buffer_.assign(reinterpret_cast<const char*>(buffer), size); | |
1811 instance_.SetBuffer(buffer_.empty() ? NULL : buffer_.c_str(), buffer_.size()); | |
1812 instance_.SetOrigin(DicomInstanceOrigin::FromPlugins()); | |
1813 } | |
1814 | |
1815 virtual bool CanBeFreed() const ORTHANC_OVERRIDE | |
1816 { | |
1817 return true; | |
1818 } | |
1819 | |
1820 virtual const DicomInstanceToStore& GetInstance() const ORTHANC_OVERRIDE | |
1821 { | |
1822 return instance_; | |
1823 }; | |
1824 }; | |
1825 | |
1826 | |
1764 void OrthancPlugins::SignalStoredInstance(const std::string& instanceId, | 1827 void OrthancPlugins::SignalStoredInstance(const std::string& instanceId, |
1765 DicomInstanceToStore& instance, | 1828 const DicomInstanceToStore& instance, |
1766 const Json::Value& simplifiedTags) | 1829 const Json::Value& simplifiedTags) |
1767 { | 1830 { |
1831 DicomInstanceFromCallback wrapped(instance); | |
1832 | |
1768 boost::recursive_mutex::scoped_lock lock(pimpl_->storedCallbackMutex_); | 1833 boost::recursive_mutex::scoped_lock lock(pimpl_->storedCallbackMutex_); |
1769 | 1834 |
1770 for (PImpl::OnStoredCallbacks::const_iterator | 1835 for (PImpl::OnStoredCallbacks::const_iterator |
1771 callback = pimpl_->onStoredCallbacks_.begin(); | 1836 callback = pimpl_->onStoredCallbacks_.begin(); |
1772 callback != pimpl_->onStoredCallbacks_.end(); ++callback) | 1837 callback != pimpl_->onStoredCallbacks_.end(); ++callback) |
1773 { | 1838 { |
1774 OrthancPluginErrorCode error = (*callback) | 1839 OrthancPluginErrorCode error = (*callback) ( |
1775 (reinterpret_cast<OrthancPluginDicomInstance*>(&instance), | 1840 reinterpret_cast<OrthancPluginDicomInstance*>(&wrapped), |
1776 instanceId.c_str()); | 1841 instanceId.c_str()); |
1777 | 1842 |
1778 if (error != OrthancPluginErrorCode_Success) | 1843 if (error != OrthancPluginErrorCode_Success) |
1779 { | 1844 { |
1780 GetErrorDictionary().LogError(error, true); | 1845 GetErrorDictionary().LogError(error, true); |
1781 throw OrthancException(static_cast<ErrorCode>(error)); | 1846 throw OrthancException(static_cast<ErrorCode>(error)); |
1785 | 1850 |
1786 | 1851 |
1787 bool OrthancPlugins::FilterIncomingInstance(const DicomInstanceToStore& instance, | 1852 bool OrthancPlugins::FilterIncomingInstance(const DicomInstanceToStore& instance, |
1788 const Json::Value& simplified) | 1853 const Json::Value& simplified) |
1789 { | 1854 { |
1855 DicomInstanceFromCallback wrapped(instance); | |
1856 | |
1790 boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_); | 1857 boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_); |
1791 | 1858 |
1792 for (PImpl::IncomingDicomInstanceFilters::const_iterator | 1859 for (PImpl::IncomingDicomInstanceFilters::const_iterator |
1793 filter = pimpl_->incomingDicomInstanceFilters_.begin(); | 1860 filter = pimpl_->incomingDicomInstanceFilters_.begin(); |
1794 filter != pimpl_->incomingDicomInstanceFilters_.end(); ++filter) | 1861 filter != pimpl_->incomingDicomInstanceFilters_.end(); ++filter) |
1795 { | 1862 { |
1796 int32_t allowed = (*filter) ( | 1863 int32_t allowed = (*filter) (reinterpret_cast<const OrthancPluginDicomInstance*>(&wrapped)); |
1797 reinterpret_cast<const OrthancPluginDicomInstance*>(&instance)); | |
1798 | 1864 |
1799 if (allowed == 0) | 1865 if (allowed == 0) |
1800 { | 1866 { |
1801 return false; | 1867 return false; |
1802 } | 1868 } |
2449 } | 2515 } |
2450 } | 2516 } |
2451 } | 2517 } |
2452 | 2518 |
2453 | 2519 |
2454 static void AccessDicomInstance(_OrthancPluginService service, | 2520 void OrthancPlugins::AccessDicomInstance(_OrthancPluginService service, |
2455 const void* parameters) | 2521 const void* parameters) |
2456 { | 2522 { |
2457 const _OrthancPluginAccessDicomInstance& p = | 2523 const _OrthancPluginAccessDicomInstance& p = |
2458 *reinterpret_cast<const _OrthancPluginAccessDicomInstance*>(parameters); | 2524 *reinterpret_cast<const _OrthancPluginAccessDicomInstance*>(parameters); |
2459 | 2525 |
2526 if (p.instance == NULL) | |
2527 { | |
2528 throw OrthancException(ErrorCode_NullPointer); | |
2529 } | |
2530 | |
2460 const DicomInstanceToStore& instance = | 2531 const DicomInstanceToStore& instance = |
2461 *reinterpret_cast<const DicomInstanceToStore*>(p.instance); | 2532 reinterpret_cast<const IDicomInstance*>(p.instance)->GetInstance(); |
2462 | 2533 |
2463 switch (service) | 2534 switch (service) |
2464 { | 2535 { |
2465 case _OrthancPluginService_GetInstanceRemoteAet: | 2536 case _OrthancPluginService_GetInstanceRemoteAet: |
2466 *p.resultString = instance.GetOrigin().GetRemoteAetC(); | 2537 *p.resultString = instance.GetOrigin().GetRemoteAetC(); |
2521 | 2592 |
2522 case _OrthancPluginService_HasInstancePixelData: // New in Orthanc 1.6.1 | 2593 case _OrthancPluginService_HasInstancePixelData: // New in Orthanc 1.6.1 |
2523 *p.resultInt64 = instance.HasPixelData(); | 2594 *p.resultInt64 = instance.HasPixelData(); |
2524 return; | 2595 return; |
2525 | 2596 |
2597 case _OrthancPluginService_GetInstanceFramesCount: // New in Orthanc 1.7.0 | |
2598 *p.resultInt64 = instance.GetParsedDicomFile().GetFramesCount(); | |
2599 return; | |
2600 | |
2526 default: | 2601 default: |
2527 throw OrthancException(ErrorCode_InternalError); | 2602 throw OrthancException(ErrorCode_InternalError); |
2528 } | 2603 } |
2529 } | 2604 } |
2530 | 2605 |
2600 return reinterpret_cast<OrthancPluginImage*>(copy.release()); | 2675 return reinterpret_cast<OrthancPluginImage*>(copy.release()); |
2601 } | 2676 } |
2602 else | 2677 else |
2603 { | 2678 { |
2604 return reinterpret_cast<OrthancPluginImage*>(image.release()); | 2679 return reinterpret_cast<OrthancPluginImage*>(image.release()); |
2680 } | |
2681 } | |
2682 | |
2683 | |
2684 void OrthancPlugins::AccessDicomInstance2(_OrthancPluginService service, | |
2685 const void* parameters) | |
2686 { | |
2687 const _OrthancPluginAccessDicomInstance2& p = | |
2688 *reinterpret_cast<const _OrthancPluginAccessDicomInstance2*>(parameters); | |
2689 | |
2690 if (p.instance == NULL) | |
2691 { | |
2692 throw OrthancException(ErrorCode_NullPointer); | |
2693 } | |
2694 | |
2695 const DicomInstanceToStore& instance = | |
2696 reinterpret_cast<const IDicomInstance*>(p.instance)->GetInstance(); | |
2697 | |
2698 switch (service) | |
2699 { | |
2700 case _OrthancPluginService_GetInstanceFramesCount: | |
2701 *p.targetUint32 = instance.GetParsedDicomFile().GetFramesCount(); | |
2702 return; | |
2703 | |
2704 case _OrthancPluginService_GetInstanceRawFrame: | |
2705 { | |
2706 if (p.targetBuffer == NULL) | |
2707 { | |
2708 throw OrthancException(ErrorCode_NullPointer); | |
2709 } | |
2710 | |
2711 p.targetBuffer->data = NULL; | |
2712 p.targetBuffer->size = 0; | |
2713 | |
2714 MimeType mime; | |
2715 std::string frame; | |
2716 instance.GetParsedDicomFile().GetRawFrame(frame, mime, p.frameIndex); | |
2717 CopyToMemoryBuffer(*p.targetBuffer, frame); | |
2718 return; | |
2719 } | |
2720 | |
2721 case _OrthancPluginService_GetInstanceDecodedFrame: | |
2722 { | |
2723 bool hasDecoderPlugin; | |
2724 | |
2725 { | |
2726 boost::mutex::scoped_lock lock(pimpl_->decodeImageCallbackMutex_); | |
2727 hasDecoderPlugin = !pimpl_->decodeImageCallbacks_.empty(); | |
2728 } | |
2729 | |
2730 std::unique_ptr<ImageAccessor> decoded; | |
2731 if (p.targetImage == NULL) | |
2732 { | |
2733 throw OrthancException(ErrorCode_NullPointer); | |
2734 } | |
2735 else if (hasDecoderPlugin) | |
2736 { | |
2737 // TODO - This call could be speeded up the future, if a | |
2738 // "decoding context" gets introduced in the decoder plugins | |
2739 | |
2740 decoded.reset(Decode(instance.GetBufferData(), instance.GetBufferSize(), p.frameIndex)); | |
2741 } | |
2742 else | |
2743 { | |
2744 decoded.reset(DicomImageDecoder::Decode(instance.GetParsedDicomFile(), p.frameIndex)); | |
2745 } | |
2746 | |
2747 *(p.targetImage) = ReturnImage(decoded); | |
2748 return; | |
2749 } | |
2750 | |
2751 default: | |
2752 throw OrthancException(ErrorCode_InternalError); | |
2605 } | 2753 } |
2606 } | 2754 } |
2607 | 2755 |
2608 | 2756 |
2609 void OrthancPlugins::UncompressImage(const void* parameters) | 2757 void OrthancPlugins::UncompressImage(const void* parameters) |
3479 case _OrthancPluginService_GetInstanceTransferSyntaxUid: | 3627 case _OrthancPluginService_GetInstanceTransferSyntaxUid: |
3480 case _OrthancPluginService_HasInstancePixelData: | 3628 case _OrthancPluginService_HasInstancePixelData: |
3481 AccessDicomInstance(service, parameters); | 3629 AccessDicomInstance(service, parameters); |
3482 return true; | 3630 return true; |
3483 | 3631 |
3632 case _OrthancPluginService_GetInstanceFramesCount: | |
3633 case _OrthancPluginService_GetInstanceRawFrame: | |
3634 case _OrthancPluginService_GetInstanceDecodedFrame: | |
3635 AccessDicomInstance2(service, parameters); | |
3636 return true; | |
3637 | |
3484 case _OrthancPluginService_SetGlobalProperty: | 3638 case _OrthancPluginService_SetGlobalProperty: |
3485 { | 3639 { |
3486 const _OrthancPluginGlobalProperty& p = | 3640 const _OrthancPluginGlobalProperty& p = |
3487 *reinterpret_cast<const _OrthancPluginGlobalProperty*>(parameters); | 3641 *reinterpret_cast<const _OrthancPluginGlobalProperty*>(parameters); |
3488 if (p.property < 1024) | 3642 if (p.property < 1024) |
4025 | 4179 |
4026 case _OrthancPluginService_GetTagName: | 4180 case _OrthancPluginService_GetTagName: |
4027 GetTagName(parameters); | 4181 GetTagName(parameters); |
4028 return true; | 4182 return true; |
4029 | 4183 |
4184 case _OrthancPluginService_CreateDicomInstance: | |
4185 { | |
4186 const _OrthancPluginCreateDicomInstance& p = | |
4187 *reinterpret_cast<const _OrthancPluginCreateDicomInstance*>(parameters); | |
4188 *(p.target) = reinterpret_cast<OrthancPluginDicomInstance*>( | |
4189 new DicomInstanceFromBuffer(p.buffer, p.size)); | |
4190 return true; | |
4191 } | |
4192 | |
4193 case _OrthancPluginService_FreeDicomInstance: | |
4194 { | |
4195 const _OrthancPluginFreeDicomInstance& p = | |
4196 *reinterpret_cast<const _OrthancPluginFreeDicomInstance*>(parameters); | |
4197 | |
4198 if (p.dicom != NULL) | |
4199 { | |
4200 IDicomInstance* obj = reinterpret_cast<IDicomInstance*>(p.dicom); | |
4201 | |
4202 if (obj->CanBeFreed()) | |
4203 { | |
4204 delete obj; | |
4205 } | |
4206 else | |
4207 { | |
4208 throw OrthancException(ErrorCode_Plugin, "Cannot free a DICOM instance provided to a callback"); | |
4209 } | |
4210 } | |
4211 | |
4212 return true; | |
4213 } | |
4214 | |
4030 default: | 4215 default: |
4031 return false; | 4216 return false; |
4032 } | 4217 } |
4033 } | 4218 } |
4034 | 4219 |