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 }