Mercurial > hg > orthanc
comparison OrthancServer/ServerContext.cpp @ 3920:82e88ff003d7 c-get
merge default -> c-get
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Tue, 12 May 2020 14:58:24 +0200 |
parents | 6ddad3e0b569 |
children | 4cdc875510d1 |
comparison
equal
deleted
inserted
replaced
3918:dba48c162b7b | 3920:82e88ff003d7 |
---|---|
33 | 33 |
34 #include "PrecompiledHeadersServer.h" | 34 #include "PrecompiledHeadersServer.h" |
35 #include "ServerContext.h" | 35 #include "ServerContext.h" |
36 | 36 |
37 #include "../Core/Cache/SharedArchive.h" | 37 #include "../Core/Cache/SharedArchive.h" |
38 #include "../Core/DicomParsing/DcmtkTranscoder.h" | |
38 #include "../Core/DicomParsing/FromDcmtkBridge.h" | 39 #include "../Core/DicomParsing/FromDcmtkBridge.h" |
39 #include "../Core/FileStorage/StorageAccessor.h" | 40 #include "../Core/FileStorage/StorageAccessor.h" |
40 #include "../Core/HttpServer/FilesystemHttpSender.h" | 41 #include "../Core/HttpServer/FilesystemHttpSender.h" |
41 #include "../Core/HttpServer/HttpStreamTranscoder.h" | 42 #include "../Core/HttpServer/HttpStreamTranscoder.h" |
42 #include "../Core/JobsEngine/SetOfInstancesJob.h" | 43 #include "../Core/JobsEngine/SetOfInstancesJob.h" |
240 done_(false), | 241 done_(false), |
241 haveJobsChanged_(false), | 242 haveJobsChanged_(false), |
242 isJobsEngineUnserialized_(false), | 243 isJobsEngineUnserialized_(false), |
243 metricsRegistry_(new MetricsRegistry), | 244 metricsRegistry_(new MetricsRegistry), |
244 isHttpServerSecure_(true), | 245 isHttpServerSecure_(true), |
245 isExecuteLuaEnabled_(false) | 246 isExecuteLuaEnabled_(false), |
247 overwriteInstances_(false), | |
248 dcmtkTranscoder_(new DcmtkTranscoder) | |
246 { | 249 { |
247 { | 250 { |
248 OrthancConfiguration::ReaderLock lock; | 251 OrthancConfiguration::ReaderLock lock; |
249 | 252 |
250 queryRetrieveArchive_.reset( | 253 queryRetrieveArchive_.reset( |
261 limitFindInstances_ = lock.GetConfiguration().GetUnsignedIntegerParameter("LimitFindInstances", 0); | 264 limitFindInstances_ = lock.GetConfiguration().GetUnsignedIntegerParameter("LimitFindInstances", 0); |
262 limitFindResults_ = lock.GetConfiguration().GetUnsignedIntegerParameter("LimitFindResults", 0); | 265 limitFindResults_ = lock.GetConfiguration().GetUnsignedIntegerParameter("LimitFindResults", 0); |
263 | 266 |
264 // New configuration option in Orthanc 1.6.0 | 267 // New configuration option in Orthanc 1.6.0 |
265 storageCommitmentReports_.reset(new StorageCommitmentReports(lock.GetConfiguration().GetUnsignedIntegerParameter("StorageCommitmentReportsSize", 100))); | 268 storageCommitmentReports_.reset(new StorageCommitmentReports(lock.GetConfiguration().GetUnsignedIntegerParameter("StorageCommitmentReportsSize", 100))); |
269 | |
270 // New option in Orthanc 1.7.0 | |
271 transcodeDicomProtocol_ = lock.GetConfiguration().GetBooleanParameter("TranscodeDicomProtocol", true); | |
266 } | 272 } |
267 | 273 |
268 jobsEngine_.SetThreadSleep(unitTesting ? 20 : 200); | 274 jobsEngine_.SetThreadSleep(unitTesting ? 20 : 200); |
269 | 275 |
270 listeners_.push_back(ServerListener(luaListener_, "Lua")); | 276 listeners_.push_back(ServerListener(luaListener_, "Lua")); |
336 StorageAccessor accessor(area_, GetMetricsRegistry()); | 342 StorageAccessor accessor(area_, GetMetricsRegistry()); |
337 accessor.Remove(fileUuid, type); | 343 accessor.Remove(fileUuid, type); |
338 } | 344 } |
339 | 345 |
340 | 346 |
341 StoreStatus ServerContext::Store(std::string& resultPublicId, | 347 StoreStatus ServerContext::StoreAfterTranscoding(std::string& resultPublicId, |
342 DicomInstanceToStore& dicom) | 348 DicomInstanceToStore& dicom, |
343 { | 349 StoreInstanceMode mode) |
350 { | |
351 bool overwrite; | |
352 switch (mode) | |
353 { | |
354 case StoreInstanceMode_Default: | |
355 overwrite = overwriteInstances_; | |
356 break; | |
357 | |
358 case StoreInstanceMode_OverwriteDuplicate: | |
359 overwrite = true; | |
360 break; | |
361 | |
362 case StoreInstanceMode_IgnoreDuplicate: | |
363 overwrite = false; | |
364 break; | |
365 | |
366 default: | |
367 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
368 } | |
369 | |
344 try | 370 try |
345 { | 371 { |
346 MetricsRegistry::Timer timer(GetMetricsRegistry(), "orthanc_store_dicom_duration_ms"); | 372 MetricsRegistry::Timer timer(GetMetricsRegistry(), "orthanc_store_dicom_duration_ms"); |
347 StorageAccessor accessor(area_, GetMetricsRegistry()); | 373 StorageAccessor accessor(area_, GetMetricsRegistry()); |
348 | 374 |
402 attachments.push_back(dicomInfo); | 428 attachments.push_back(dicomInfo); |
403 attachments.push_back(jsonInfo); | 429 attachments.push_back(jsonInfo); |
404 | 430 |
405 typedef std::map<MetadataType, std::string> InstanceMetadata; | 431 typedef std::map<MetadataType, std::string> InstanceMetadata; |
406 InstanceMetadata instanceMetadata; | 432 InstanceMetadata instanceMetadata; |
407 StoreStatus status = index_.Store(instanceMetadata, dicom, attachments); | 433 StoreStatus status = index_.Store( |
434 instanceMetadata, dicom, attachments, overwrite); | |
408 | 435 |
409 // Only keep the metadata for the "instance" level | 436 // Only keep the metadata for the "instance" level |
410 dicom.GetMetadata().clear(); | 437 dicom.GetMetadata().clear(); |
411 | 438 |
412 for (InstanceMetadata::const_iterator it = instanceMetadata.begin(); | 439 for (InstanceMetadata::const_iterator it = instanceMetadata.begin(); |
473 throw; | 500 throw; |
474 } | 501 } |
475 } | 502 } |
476 | 503 |
477 | 504 |
505 StoreStatus ServerContext::Store(std::string& resultPublicId, | |
506 DicomInstanceToStore& dicom, | |
507 StoreInstanceMode mode) | |
508 { | |
509 //const DicomTransferSyntax option = DicomTransferSyntax_JPEGProcess1; | |
510 const DicomTransferSyntax option = DicomTransferSyntax_LittleEndianExplicit; | |
511 | |
512 if (1) | |
513 { | |
514 return StoreAfterTranscoding(resultPublicId, dicom, mode); | |
515 } | |
516 else | |
517 { | |
518 // TODO => Automated transcoding of incoming DICOM files | |
519 | |
520 DicomTransferSyntax sourceSyntax; | |
521 if (!FromDcmtkBridge::LookupOrthancTransferSyntax( | |
522 sourceSyntax, dicom.GetParsedDicomFile().GetDcmtkObject()) || | |
523 sourceSyntax == option) | |
524 { | |
525 // No transcoding | |
526 return StoreAfterTranscoding(resultPublicId, dicom, mode); | |
527 } | |
528 else | |
529 { | |
530 std::set<DicomTransferSyntax> syntaxes; | |
531 syntaxes.insert(option); | |
532 | |
533 std::unique_ptr<IDicomTranscoder::TranscodedDicom> transcoded( | |
534 GetTranscoder().TranscodeToParsed(dicom.GetParsedDicomFile().GetDcmtkObject(), | |
535 dicom.GetBufferData(), dicom.GetBufferSize(), | |
536 syntaxes, true /* allow new SOP instance UID */)); | |
537 | |
538 if (transcoded.get() == NULL) | |
539 { | |
540 // Cannot transcode => store the original file | |
541 return StoreAfterTranscoding(resultPublicId, dicom, mode); | |
542 } | |
543 else | |
544 { | |
545 std::unique_ptr<ParsedDicomFile> tmp( | |
546 ParsedDicomFile::AcquireDcmtkObject(transcoded->ReleaseDicom())); | |
547 | |
548 DicomInstanceToStore toStore; | |
549 toStore.SetParsedDicomFile(*tmp); | |
550 toStore.SetOrigin(dicom.GetOrigin()); | |
551 | |
552 StoreStatus ok = StoreAfterTranscoding(resultPublicId, toStore, mode); | |
553 printf(">> %s\n", resultPublicId.c_str()); | |
554 return ok; | |
555 } | |
556 } | |
557 } | |
558 } | |
559 | |
560 | |
478 void ServerContext::AnswerAttachment(RestApiOutput& output, | 561 void ServerContext::AnswerAttachment(RestApiOutput& output, |
479 const std::string& resourceId, | 562 const std::string& resourceId, |
480 FileContentType content) | 563 FileContentType content) |
481 { | 564 { |
482 FileInfo attachment; | 565 FileInfo attachment; |
1084 } | 1167 } |
1085 #endif | 1168 #endif |
1086 | 1169 |
1087 return NULL; | 1170 return NULL; |
1088 } | 1171 } |
1172 | |
1173 | |
1174 IDicomTranscoder& ServerContext::GetTranscoder() | |
1175 { | |
1176 IDicomTranscoder* transcoder = dcmtkTranscoder_.get(); | |
1177 | |
1178 #if ORTHANC_ENABLE_PLUGINS == 1 | |
1179 if (HasPlugins()) | |
1180 { | |
1181 transcoder = &GetPlugins(); | |
1182 } | |
1183 #endif | |
1184 | |
1185 if (transcoder == NULL) | |
1186 { | |
1187 throw OrthancException(ErrorCode_InternalError); | |
1188 } | |
1189 else | |
1190 { | |
1191 return *transcoder; | |
1192 } | |
1193 } | |
1194 | |
1195 | |
1196 void ServerContext::StoreWithTranscoding(std::string& sopClassUid, | |
1197 std::string& sopInstanceUid, | |
1198 DicomStoreUserConnection& connection, | |
1199 const std::string& dicom, | |
1200 bool hasMoveOriginator, | |
1201 const std::string& moveOriginatorAet, | |
1202 uint16_t moveOriginatorId) | |
1203 { | |
1204 const void* data = dicom.empty() ? NULL : dicom.c_str(); | |
1205 | |
1206 if (!transcodeDicomProtocol_ || | |
1207 !connection.GetParameters().GetRemoteModality().IsTranscodingAllowed()) | |
1208 { | |
1209 connection.Store(sopClassUid, sopInstanceUid, data, dicom.size(), | |
1210 hasMoveOriginator, moveOriginatorAet, moveOriginatorId); | |
1211 } | |
1212 else | |
1213 { | |
1214 connection.Transcode(sopClassUid, sopInstanceUid, GetTranscoder(), data, dicom.size(), | |
1215 hasMoveOriginator, moveOriginatorAet, moveOriginatorId); | |
1216 } | |
1217 } | |
1089 } | 1218 } |