Mercurial > hg > orthanc
comparison Plugins/Engine/OrthancPlugins.cpp @ 3930:b99acc213937 transcoding
transcoder plugins and GDCM transcoding are working
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 14 May 2020 19:20:40 +0200 |
parents | 7dc5e7e0045d |
children | e6606d3ec892 |
comparison
equal
deleted
inserted
replaced
3929:7dc5e7e0045d | 3930:b99acc213937 |
---|---|
888 typedef std::list<OrthancPluginOnChangeCallback> OnChangeCallbacks; | 888 typedef std::list<OrthancPluginOnChangeCallback> OnChangeCallbacks; |
889 typedef std::list<OrthancPluginIncomingHttpRequestFilter> IncomingHttpRequestFilters; | 889 typedef std::list<OrthancPluginIncomingHttpRequestFilter> IncomingHttpRequestFilters; |
890 typedef std::list<OrthancPluginIncomingHttpRequestFilter2> IncomingHttpRequestFilters2; | 890 typedef std::list<OrthancPluginIncomingHttpRequestFilter2> IncomingHttpRequestFilters2; |
891 typedef std::list<OrthancPluginIncomingDicomInstanceFilter> IncomingDicomInstanceFilters; | 891 typedef std::list<OrthancPluginIncomingDicomInstanceFilter> IncomingDicomInstanceFilters; |
892 typedef std::list<OrthancPluginDecodeImageCallback> DecodeImageCallbacks; | 892 typedef std::list<OrthancPluginDecodeImageCallback> DecodeImageCallbacks; |
893 typedef std::list<OrthancPluginTranscoderCallback> TranscoderCallbacks; | |
893 typedef std::list<OrthancPluginJobsUnserializer> JobsUnserializers; | 894 typedef std::list<OrthancPluginJobsUnserializer> JobsUnserializers; |
894 typedef std::list<OrthancPluginRefreshMetricsCallback> RefreshMetricsCallbacks; | 895 typedef std::list<OrthancPluginRefreshMetricsCallback> RefreshMetricsCallbacks; |
895 typedef std::list<StorageCommitmentScp*> StorageCommitmentScpCallbacks; | 896 typedef std::list<StorageCommitmentScp*> StorageCommitmentScpCallbacks; |
896 typedef std::map<Property, std::string> Properties; | 897 typedef std::map<Property, std::string> Properties; |
897 | 898 |
902 OnStoredCallbacks onStoredCallbacks_; | 903 OnStoredCallbacks onStoredCallbacks_; |
903 OnChangeCallbacks onChangeCallbacks_; | 904 OnChangeCallbacks onChangeCallbacks_; |
904 OrthancPluginFindCallback findCallback_; | 905 OrthancPluginFindCallback findCallback_; |
905 OrthancPluginWorklistCallback worklistCallback_; | 906 OrthancPluginWorklistCallback worklistCallback_; |
906 DecodeImageCallbacks decodeImageCallbacks_; | 907 DecodeImageCallbacks decodeImageCallbacks_; |
908 TranscoderCallbacks transcoderCallbacks_; | |
907 JobsUnserializers jobsUnserializers_; | 909 JobsUnserializers jobsUnserializers_; |
908 _OrthancPluginMoveCallback moveCallbacks_; | 910 _OrthancPluginMoveCallback moveCallbacks_; |
909 IncomingHttpRequestFilters incomingHttpRequestFilters_; | 911 IncomingHttpRequestFilters incomingHttpRequestFilters_; |
910 IncomingHttpRequestFilters2 incomingHttpRequestFilters2_; | 912 IncomingHttpRequestFilters2 incomingHttpRequestFilters2_; |
911 IncomingDicomInstanceFilters incomingDicomInstanceFilters_; | 913 IncomingDicomInstanceFilters incomingDicomInstanceFilters_; |
916 boost::recursive_mutex restCallbackMutex_; | 918 boost::recursive_mutex restCallbackMutex_; |
917 boost::recursive_mutex storedCallbackMutex_; | 919 boost::recursive_mutex storedCallbackMutex_; |
918 boost::recursive_mutex changeCallbackMutex_; | 920 boost::recursive_mutex changeCallbackMutex_; |
919 boost::mutex findCallbackMutex_; | 921 boost::mutex findCallbackMutex_; |
920 boost::mutex worklistCallbackMutex_; | 922 boost::mutex worklistCallbackMutex_; |
921 boost::shared_mutex decodeImageCallbackMutex_; // Changed from "boost::mutex" in Orthanc 1.7.0 | 923 boost::shared_mutex decoderTranscoderMutex_; // Changed from "boost::mutex" in Orthanc 1.7.0 |
922 boost::mutex jobsUnserializersMutex_; | 924 boost::mutex jobsUnserializersMutex_; |
923 boost::mutex refreshMetricsMutex_; | 925 boost::mutex refreshMetricsMutex_; |
924 boost::mutex storageCommitmentScpMutex_; | 926 boost::mutex storageCommitmentScpMutex_; |
925 boost::recursive_mutex invokeServiceMutex_; | 927 boost::recursive_mutex invokeServiceMutex_; |
926 | 928 |
2107 void OrthancPlugins::RegisterDecodeImageCallback(const void* parameters) | 2109 void OrthancPlugins::RegisterDecodeImageCallback(const void* parameters) |
2108 { | 2110 { |
2109 const _OrthancPluginDecodeImageCallback& p = | 2111 const _OrthancPluginDecodeImageCallback& p = |
2110 *reinterpret_cast<const _OrthancPluginDecodeImageCallback*>(parameters); | 2112 *reinterpret_cast<const _OrthancPluginDecodeImageCallback*>(parameters); |
2111 | 2113 |
2112 boost::unique_lock<boost::shared_mutex> lock(pimpl_->decodeImageCallbackMutex_); | 2114 boost::unique_lock<boost::shared_mutex> lock(pimpl_->decoderTranscoderMutex_); |
2113 | 2115 |
2114 pimpl_->decodeImageCallbacks_.push_back(p.callback); | 2116 pimpl_->decodeImageCallbacks_.push_back(p.callback); |
2115 LOG(INFO) << "Plugin has registered a callback to decode DICOM images (" | 2117 LOG(INFO) << "Plugin has registered a callback to decode DICOM images (" |
2116 << pimpl_->decodeImageCallbacks_.size() << " decoder(s) now active)"; | 2118 << pimpl_->decodeImageCallbacks_.size() << " decoder(s) now active)"; |
2119 } | |
2120 | |
2121 | |
2122 void OrthancPlugins::RegisterTranscoderCallback(const void* parameters) | |
2123 { | |
2124 const _OrthancPluginTranscoderCallback& p = | |
2125 *reinterpret_cast<const _OrthancPluginTranscoderCallback*>(parameters); | |
2126 | |
2127 boost::unique_lock<boost::shared_mutex> lock(pimpl_->decoderTranscoderMutex_); | |
2128 | |
2129 pimpl_->transcoderCallbacks_.push_back(p.callback); | |
2130 LOG(INFO) << "Plugin has registered a callback to transcode DICOM images (" | |
2131 << pimpl_->transcoderCallbacks_.size() << " transcoder(s) now active)"; | |
2117 } | 2132 } |
2118 | 2133 |
2119 | 2134 |
2120 void OrthancPlugins::RegisterJobsUnserializer(const void* parameters) | 2135 void OrthancPlugins::RegisterJobsUnserializer(const void* parameters) |
2121 { | 2136 { |
4361 | 4376 |
4362 std::unique_ptr<IDicomTranscoder::TranscodedDicom> transcoded; | 4377 std::unique_ptr<IDicomTranscoder::TranscodedDicom> transcoded; |
4363 | 4378 |
4364 { | 4379 { |
4365 PImpl::ServerContextLock lock(*pimpl_); | 4380 PImpl::ServerContextLock lock(*pimpl_); |
4366 transcoded.reset(lock.GetContext().GetTranscoder().TranscodeToParsed( | 4381 transcoded.reset(lock.GetContext().TranscodeToParsed( |
4367 dicom.GetDcmtkObject(), p.buffer, p.size, | 4382 dicom.GetDcmtkObject(), p.buffer, p.size, |
4368 syntaxes, true /* allow new sop */)); | 4383 syntaxes, true /* allow new sop */)); |
4369 } | 4384 } |
4370 | 4385 |
4371 if (transcoded.get() == NULL) | 4386 if (transcoded.get() == NULL) |
4378 new DicomInstanceFromTranscoded(*transcoded)); | 4393 new DicomInstanceFromTranscoded(*transcoded)); |
4379 return true; | 4394 return true; |
4380 } | 4395 } |
4381 } | 4396 } |
4382 } | 4397 } |
4398 | |
4399 case _OrthancPluginService_CreateMemoryBuffer: | |
4400 { | |
4401 const _OrthancPluginCreateMemoryBuffer& p = | |
4402 *reinterpret_cast<const _OrthancPluginCreateMemoryBuffer*>(parameters); | |
4403 | |
4404 p.target->size = p.size; | |
4405 | |
4406 if (p.size == 0) | |
4407 { | |
4408 p.target->data = NULL; | |
4409 } | |
4410 else | |
4411 { | |
4412 p.target->data = malloc(p.size); | |
4413 } | |
4414 | |
4415 return true; | |
4416 } | |
4383 | 4417 |
4384 default: | 4418 default: |
4385 return false; | 4419 return false; |
4386 } | 4420 } |
4387 } | 4421 } |
4430 RegisterMoveCallback(parameters); | 4464 RegisterMoveCallback(parameters); |
4431 return true; | 4465 return true; |
4432 | 4466 |
4433 case _OrthancPluginService_RegisterDecodeImageCallback: | 4467 case _OrthancPluginService_RegisterDecodeImageCallback: |
4434 RegisterDecodeImageCallback(parameters); | 4468 RegisterDecodeImageCallback(parameters); |
4469 return true; | |
4470 | |
4471 case _OrthancPluginService_RegisterTranscoderCallback: | |
4472 RegisterTranscoderCallback(parameters); | |
4435 return true; | 4473 return true; |
4436 | 4474 |
4437 case _OrthancPluginService_RegisterJobsUnserializer: | 4475 case _OrthancPluginService_RegisterJobsUnserializer: |
4438 RegisterJobsUnserializer(parameters); | 4476 RegisterJobsUnserializer(parameters); |
4439 return true; | 4477 return true; |
4816 } | 4854 } |
4817 | 4855 |
4818 | 4856 |
4819 bool OrthancPlugins::HasCustomImageDecoder() | 4857 bool OrthancPlugins::HasCustomImageDecoder() |
4820 { | 4858 { |
4821 boost::shared_lock<boost::shared_mutex> lock(pimpl_->decodeImageCallbackMutex_); | 4859 boost::shared_lock<boost::shared_mutex> lock(pimpl_->decoderTranscoderMutex_); |
4822 return !pimpl_->decodeImageCallbacks_.empty(); | 4860 return !pimpl_->decodeImageCallbacks_.empty(); |
4823 } | 4861 } |
4824 | 4862 |
4825 | 4863 |
4826 ImageAccessor* OrthancPlugins::Decode(const void* dicom, | 4864 ImageAccessor* OrthancPlugins::Decode(const void* dicom, |
4827 size_t size, | 4865 size_t size, |
4828 unsigned int frame) | 4866 unsigned int frame) |
4829 { | 4867 { |
4830 boost::shared_lock<boost::shared_mutex> lock(pimpl_->decodeImageCallbackMutex_); | 4868 boost::shared_lock<boost::shared_mutex> lock(pimpl_->decoderTranscoderMutex_); |
4831 | 4869 |
4832 for (PImpl::DecodeImageCallbacks::const_iterator | 4870 for (PImpl::DecodeImageCallbacks::const_iterator |
4833 decoder = pimpl_->decodeImageCallbacks_.begin(); | 4871 decoder = pimpl_->decodeImageCallbacks_.begin(); |
4834 decoder != pimpl_->decodeImageCallbacks_.end(); ++decoder) | 4872 decoder != pimpl_->decodeImageCallbacks_.end(); ++decoder) |
4835 { | 4873 { |
5128 | 5166 |
5129 return NULL; | 5167 return NULL; |
5130 } | 5168 } |
5131 | 5169 |
5132 | 5170 |
5171 class MemoryBufferRaii : public boost::noncopyable | |
5172 { | |
5173 private: | |
5174 OrthancPluginMemoryBuffer buffer_; | |
5175 | |
5176 public: | |
5177 MemoryBufferRaii() | |
5178 { | |
5179 buffer_.size = 0; | |
5180 buffer_.data = NULL; | |
5181 } | |
5182 | |
5183 ~MemoryBufferRaii() | |
5184 { | |
5185 if (buffer_.size != 0) | |
5186 { | |
5187 free(buffer_.data); | |
5188 } | |
5189 } | |
5190 | |
5191 OrthancPluginMemoryBuffer* GetObject() | |
5192 { | |
5193 return &buffer_; | |
5194 } | |
5195 | |
5196 void ToString(std::string& target) const | |
5197 { | |
5198 target.resize(buffer_.size); | |
5199 | |
5200 if (buffer_.size != 0) | |
5201 { | |
5202 memcpy(&target[0], buffer_.data, buffer_.size); | |
5203 } | |
5204 } | |
5205 }; | |
5206 | |
5207 | |
5133 bool OrthancPlugins::Transcode(std::string& target, | 5208 bool OrthancPlugins::Transcode(std::string& target, |
5134 bool& hasSopInstanceUidChanged /* out */, | 5209 bool& hasSopInstanceUidChanged /* out */, |
5135 const void* buffer, | 5210 const void* buffer, |
5136 size_t size, | 5211 size_t size, |
5137 const std::set<DicomTransferSyntax>& allowedSyntaxes, | 5212 const std::set<DicomTransferSyntax>& allowedSyntaxes, |
5138 bool allowNewSopInstanceUid) | 5213 bool allowNewSopInstanceUid) |
5139 { | 5214 { |
5140 // TODO | 5215 boost::shared_lock<boost::shared_mutex> lock(pimpl_->decoderTranscoderMutex_); |
5216 | |
5217 if (pimpl_->transcoderCallbacks_.empty()) | |
5218 { | |
5219 return NULL; | |
5220 } | |
5221 | |
5222 std::vector<const char*> uids; | |
5223 uids.reserve(allowedSyntaxes.size()); | |
5224 for (std::set<DicomTransferSyntax>::const_iterator | |
5225 it = allowedSyntaxes.begin(); it != allowedSyntaxes.end(); ++it) | |
5226 { | |
5227 uids.push_back(GetTransferSyntaxUid(*it)); | |
5228 } | |
5229 | |
5230 for (PImpl::TranscoderCallbacks::const_iterator | |
5231 transcoder = pimpl_->transcoderCallbacks_.begin(); | |
5232 transcoder != pimpl_->transcoderCallbacks_.end(); ++transcoder) | |
5233 { | |
5234 MemoryBufferRaii a; | |
5235 uint8_t b; | |
5236 | |
5237 if ((*transcoder) (a.GetObject(), &b, buffer, size, uids.empty() ? NULL : &uids[0], | |
5238 static_cast<uint32_t>(uids.size()), allowNewSopInstanceUid) == | |
5239 OrthancPluginErrorCode_Success) | |
5240 { | |
5241 a.ToString(target); | |
5242 return true; | |
5243 } | |
5244 } | |
5245 | |
5141 return false; | 5246 return false; |
5142 } | 5247 } |
5143 } | 5248 } |