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 }