Mercurial > hg > orthanc
diff 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 |
line wrap: on
line diff
--- a/OrthancServer/ServerContext.cpp Tue May 12 07:50:38 2020 +0200 +++ b/OrthancServer/ServerContext.cpp Tue May 12 14:58:24 2020 +0200 @@ -35,6 +35,7 @@ #include "ServerContext.h" #include "../Core/Cache/SharedArchive.h" +#include "../Core/DicomParsing/DcmtkTranscoder.h" #include "../Core/DicomParsing/FromDcmtkBridge.h" #include "../Core/FileStorage/StorageAccessor.h" #include "../Core/HttpServer/FilesystemHttpSender.h" @@ -242,7 +243,9 @@ isJobsEngineUnserialized_(false), metricsRegistry_(new MetricsRegistry), isHttpServerSecure_(true), - isExecuteLuaEnabled_(false) + isExecuteLuaEnabled_(false), + overwriteInstances_(false), + dcmtkTranscoder_(new DcmtkTranscoder) { { OrthancConfiguration::ReaderLock lock; @@ -263,6 +266,9 @@ // New configuration option in Orthanc 1.6.0 storageCommitmentReports_.reset(new StorageCommitmentReports(lock.GetConfiguration().GetUnsignedIntegerParameter("StorageCommitmentReportsSize", 100))); + + // New option in Orthanc 1.7.0 + transcodeDicomProtocol_ = lock.GetConfiguration().GetBooleanParameter("TranscodeDicomProtocol", true); } jobsEngine_.SetThreadSleep(unitTesting ? 20 : 200); @@ -338,9 +344,29 @@ } - StoreStatus ServerContext::Store(std::string& resultPublicId, - DicomInstanceToStore& dicom) + StoreStatus ServerContext::StoreAfterTranscoding(std::string& resultPublicId, + DicomInstanceToStore& dicom, + StoreInstanceMode mode) { + bool overwrite; + switch (mode) + { + case StoreInstanceMode_Default: + overwrite = overwriteInstances_; + break; + + case StoreInstanceMode_OverwriteDuplicate: + overwrite = true; + break; + + case StoreInstanceMode_IgnoreDuplicate: + overwrite = false; + break; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + try { MetricsRegistry::Timer timer(GetMetricsRegistry(), "orthanc_store_dicom_duration_ms"); @@ -404,7 +430,8 @@ typedef std::map<MetadataType, std::string> InstanceMetadata; InstanceMetadata instanceMetadata; - StoreStatus status = index_.Store(instanceMetadata, dicom, attachments); + StoreStatus status = index_.Store( + instanceMetadata, dicom, attachments, overwrite); // Only keep the metadata for the "instance" level dicom.GetMetadata().clear(); @@ -475,6 +502,62 @@ } + StoreStatus ServerContext::Store(std::string& resultPublicId, + DicomInstanceToStore& dicom, + StoreInstanceMode mode) + { + //const DicomTransferSyntax option = DicomTransferSyntax_JPEGProcess1; + const DicomTransferSyntax option = DicomTransferSyntax_LittleEndianExplicit; + + if (1) + { + return StoreAfterTranscoding(resultPublicId, dicom, mode); + } + else + { + // TODO => Automated transcoding of incoming DICOM files + + DicomTransferSyntax sourceSyntax; + if (!FromDcmtkBridge::LookupOrthancTransferSyntax( + sourceSyntax, dicom.GetParsedDicomFile().GetDcmtkObject()) || + sourceSyntax == option) + { + // No transcoding + return StoreAfterTranscoding(resultPublicId, dicom, mode); + } + else + { + std::set<DicomTransferSyntax> syntaxes; + syntaxes.insert(option); + + std::unique_ptr<IDicomTranscoder::TranscodedDicom> transcoded( + GetTranscoder().TranscodeToParsed(dicom.GetParsedDicomFile().GetDcmtkObject(), + dicom.GetBufferData(), dicom.GetBufferSize(), + syntaxes, true /* allow new SOP instance UID */)); + + if (transcoded.get() == NULL) + { + // Cannot transcode => store the original file + return StoreAfterTranscoding(resultPublicId, dicom, mode); + } + else + { + std::unique_ptr<ParsedDicomFile> tmp( + ParsedDicomFile::AcquireDcmtkObject(transcoded->ReleaseDicom())); + + DicomInstanceToStore toStore; + toStore.SetParsedDicomFile(*tmp); + toStore.SetOrigin(dicom.GetOrigin()); + + StoreStatus ok = StoreAfterTranscoding(resultPublicId, toStore, mode); + printf(">> %s\n", resultPublicId.c_str()); + return ok; + } + } + } + } + + void ServerContext::AnswerAttachment(RestApiOutput& output, const std::string& resourceId, FileContentType content) @@ -1086,4 +1169,50 @@ return NULL; } + + + IDicomTranscoder& ServerContext::GetTranscoder() + { + IDicomTranscoder* transcoder = dcmtkTranscoder_.get(); + +#if ORTHANC_ENABLE_PLUGINS == 1 + if (HasPlugins()) + { + transcoder = &GetPlugins(); + } +#endif + + if (transcoder == NULL) + { + throw OrthancException(ErrorCode_InternalError); + } + else + { + return *transcoder; + } + } + + + void ServerContext::StoreWithTranscoding(std::string& sopClassUid, + std::string& sopInstanceUid, + DicomStoreUserConnection& connection, + const std::string& dicom, + bool hasMoveOriginator, + const std::string& moveOriginatorAet, + uint16_t moveOriginatorId) + { + const void* data = dicom.empty() ? NULL : dicom.c_str(); + + if (!transcodeDicomProtocol_ || + !connection.GetParameters().GetRemoteModality().IsTranscodingAllowed()) + { + connection.Store(sopClassUid, sopInstanceUid, data, dicom.size(), + hasMoveOriginator, moveOriginatorAet, moveOriginatorId); + } + else + { + connection.Transcode(sopClassUid, sopInstanceUid, GetTranscoder(), data, dicom.size(), + hasMoveOriginator, moveOriginatorAet, moveOriginatorId); + } + } }