Mercurial > hg > orthanc
diff OrthancServer/ServerJobs/ArchiveJob.cpp @ 3913:6ddad3e0b569 transcoding
transcoding ZIP archive and media
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 08 May 2020 19:15:28 +0200 |
parents | 56f2397f027a |
children | b99acc213937 |
line wrap: on
line diff
--- a/OrthancServer/ServerJobs/ArchiveJob.cpp Fri May 08 13:43:50 2020 +0200 +++ b/OrthancServer/ServerJobs/ArchiveJob.cpp Fri May 08 19:15:28 2020 +0200 @@ -37,6 +37,7 @@ #include "../../Core/Cache/SharedArchive.h" #include "../../Core/Compression/HierarchicalZipWriter.h" #include "../../Core/DicomParsing/DicomDirWriter.h" +#include "../../Core/DicomParsing/FromDcmtkBridge.h" #include "../../Core/Logging.h" #include "../../Core/OrthancException.h" #include "../OrthancConfiguration.h" @@ -55,6 +56,7 @@ static const char* const KEY_DESCRIPTION = "Description"; static const char* const KEY_INSTANCES_COUNT = "InstancesCount"; static const char* const KEY_UNCOMPRESSED_SIZE_MB = "UncompressedSizeMB"; +static const char* const KEY_TRANSCODE = "Transcode"; namespace Orthanc @@ -399,7 +401,9 @@ void Apply(HierarchicalZipWriter& writer, ServerContext& context, DicomDirWriter* dicomDir, - const std::string& dicomDirFolder) const + const std::string& dicomDirFolder, + bool transcode, + DicomTransferSyntax transferSyntax) const { switch (type_) { @@ -426,14 +430,65 @@ } //boost::this_thread::sleep(boost::posix_time::milliseconds(300)); - + writer.OpenFile(filename_.c_str()); - writer.Write(content); + + bool transcodeSuccess = false; + + std::unique_ptr<ParsedDicomFile> parsed; + + if (transcode) + { + // New in Orthanc 1.7.0 + std::set<DicomTransferSyntax> syntaxes; + syntaxes.insert(transferSyntax); + + parsed.reset(new ParsedDicomFile(content)); + const char* data = content.empty() ? NULL : content.c_str(); + + std::unique_ptr<IDicomTranscoder::TranscodedDicom> transcodedDicom( + context.GetTranscoder().TranscodeToParsed( + parsed->GetDcmtkObject(), data, content.size(), + syntaxes, true /* allow new SOP instance UID */)); + + if (transcodedDicom.get() != NULL && + transcodedDicom->GetDicom().getDataset() != NULL) + { + std::string transcoded; + FromDcmtkBridge::SaveToMemoryBuffer( + transcoded, *transcodedDicom->GetDicom().getDataset()); + + writer.Write(transcoded); - if (dicomDir != NULL) + if (dicomDir != NULL) + { + std::unique_ptr<ParsedDicomFile> tmp( + ParsedDicomFile::AcquireDcmtkObject(transcodedDicom->ReleaseDicom())); + dicomDir->Add(dicomDirFolder, filename_, *tmp); + } + + transcodeSuccess = true; + } + else + { + LOG(INFO) << "Cannot transcode instance " << instanceId_ + << " to transfer syntax: " << GetTransferSyntaxUid(transferSyntax); + } + } + + if (!transcodeSuccess) { - ParsedDicomFile parsed(content); - dicomDir->Add(dicomDirFolder, filename_, parsed); + writer.Write(content); + + if (dicomDir != NULL) + { + if (parsed.get() == NULL) + { + parsed.reset(new ParsedDicomFile(content)); + } + + dicomDir->Add(dicomDirFolder, filename_, *parsed); + } } break; @@ -454,14 +509,16 @@ ServerContext& context, size_t index, DicomDirWriter* dicomDir, - const std::string& dicomDirFolder) const + const std::string& dicomDirFolder, + bool transcode, + DicomTransferSyntax transferSyntax) const { if (index >= commands_.size()) { throw OrthancException(ErrorCode_ParameterOutOfRange); } - commands_[index]->Apply(writer, context, dicomDir, dicomDirFolder); + commands_[index]->Apply(writer, context, dicomDir, dicomDirFolder, transcode, transferSyntax); } public: @@ -496,20 +553,26 @@ return uncompressedSize_; } + // "media" flavor (with DICOMDIR) void Apply(HierarchicalZipWriter& writer, ServerContext& context, size_t index, DicomDirWriter& dicomDir, - const std::string& dicomDirFolder) const + const std::string& dicomDirFolder, + bool transcode, + DicomTransferSyntax transferSyntax) const { - ApplyInternal(writer, context, index, &dicomDir, dicomDirFolder); + ApplyInternal(writer, context, index, &dicomDir, dicomDirFolder, transcode, transferSyntax); } + // "archive" flavor (without DICOMDIR) void Apply(HierarchicalZipWriter& writer, ServerContext& context, - size_t index) const + size_t index, + bool transcode, + DicomTransferSyntax transferSyntax) const { - ApplyInternal(writer, context, index, NULL, ""); + ApplyInternal(writer, context, index, NULL, "", transcode, transferSyntax); } void AddOpenDirectory(const std::string& filename) @@ -740,7 +803,9 @@ return commands_.GetSize() + 1; } - void RunStep(size_t index) + void RunStep(size_t index, + bool transcode, + DicomTransferSyntax transferSyntax) { if (index > commands_.GetSize()) { @@ -764,12 +829,13 @@ if (isMedia_) { assert(dicomDir_.get() != NULL); - commands_.Apply(*zip_, context_, index, *dicomDir_, MEDIA_IMAGES_FOLDER); + commands_.Apply(*zip_, context_, index, *dicomDir_, + MEDIA_IMAGES_FOLDER, transcode, transferSyntax); } else { assert(dicomDir_.get() == NULL); - commands_.Apply(*zip_, context_, index); + commands_.Apply(*zip_, context_, index, transcode, transferSyntax); } } } @@ -795,7 +861,9 @@ enableExtendedSopClass_(enableExtendedSopClass), currentStep_(0), instancesCount_(0), - uncompressedSize_(0) + uncompressedSize_(0), + transcode_(false), + transferSyntax_(DicomTransferSyntax_LittleEndianImplicit) { } @@ -854,6 +922,20 @@ } } + + void ArchiveJob::SetTranscode(DicomTransferSyntax transferSyntax) + { + if (writer_.get() != NULL) // Already started + { + throw OrthancException(ErrorCode_BadSequenceOfCalls); + } + else + { + transcode_ = true; + transferSyntax_ = transferSyntax; + } + } + void ArchiveJob::Reset() { @@ -954,7 +1036,7 @@ } else { - writer_->RunStep(currentStep_); + writer_->RunStep(currentStep_, transcode_, transferSyntax_); currentStep_ ++; @@ -1006,6 +1088,11 @@ value[KEY_INSTANCES_COUNT] = instancesCount_; value[KEY_UNCOMPRESSED_SIZE_MB] = static_cast<unsigned int>(uncompressedSize_ / MEGA_BYTES); + + if (transcode_) + { + value[KEY_TRANSCODE] = GetTransferSyntaxUid(transferSyntax_); + } }