# HG changeset patch # User Sebastien Jodogne # Date 1613066789 -3600 # Node ID 1ec156a0da38d12fb1423ae129111bf2fa51177f # Parent a3635a01a945366898421f7f4c873d2a539e8532 ServerContext::ReadDicomUntilPixelData() diff -r a3635a01a945 -r 1ec156a0da38 OrthancServer/Sources/ServerContext.cpp --- a/OrthancServer/Sources/ServerContext.cpp Thu Feb 11 17:51:04 2021 +0100 +++ b/OrthancServer/Sources/ServerContext.cpp Thu Feb 11 19:06:29 2021 +0100 @@ -584,7 +584,7 @@ attachments.push_back(dicomInfo); FileInfo jsonInfo; - if (true /* TODO - !area_.HasReadRange() || !hasPixelDataOffset */) + if (true /* TODO - !area_.HasReadRange() || !hasPixelDataOffset || compression != CompressionType_DicomAsJson */) { jsonInfo = accessor.Write(dicomAsJson.toStyledString(), FileContentType_DicomAsJson, compression, storeMD5_); @@ -807,8 +807,8 @@ } - void ServerContext::ReadDicomAsJsonInternal(std::string& result, - const std::string& instancePublicId) + void ServerContext::ReadDicomAsJson(std::string& result, + const std::string& instancePublicId) { FileInfo attachment; if (index_.LookupAttachment(attachment, instancePublicId, FileContentType_DicomAsJson)) @@ -843,23 +843,6 @@ } - void ServerContext::ReadDicomAsJson(std::string& result, - const std::string& instancePublicId, - const std::set& ignoreTagLength) - { - if (ignoreTagLength.empty()) - { - ReadDicomAsJsonInternal(result, instancePublicId); - } - else - { - Json::Value tmp; - ReadDicomAsJson(tmp, instancePublicId, ignoreTagLength); - result = tmp.toStyledString(); - } - } - - void ServerContext::ReadDicomAsJson(Json::Value& result, const std::string& instancePublicId, const std::set& ignoreTagLength) @@ -867,7 +850,7 @@ if (ignoreTagLength.empty()) { std::string tmp; - ReadDicomAsJsonInternal(tmp, instancePublicId); + ReadDicomAsJson(tmp, instancePublicId); if (!Toolbox::ReadJson(result, tmp)) { @@ -887,6 +870,14 @@ } + void ServerContext::ReadDicomAsJson(Json::Value& result, + const std::string& instancePublicId) + { + std::set ignoreTagLength; + ReadDicomAsJson(result, instancePublicId, ignoreTagLength); + } + + void ServerContext::ReadDicom(std::string& dicom, const std::string& instancePublicId) { @@ -894,6 +885,47 @@ } + bool ServerContext::ReadDicomUntilPixelData(std::string& dicom, + const std::string& instancePublicId) + { + if (!area_.HasReadRange()) + { + return false; + } + + FileInfo attachment; + if (!index_.LookupAttachment(attachment, instancePublicId, FileContentType_Dicom)) + { + throw OrthancException(ErrorCode_InternalError, + "Unable to read the DICOM file of instance " + instancePublicId); + } + + std::string s; + + if (attachment.GetCompressionType() == CompressionType_None && + index_.LookupMetadata(s, instancePublicId, ResourceType_Instance, + MetadataType_Instance_PixelDataOffset) && + !s.empty()) + { + try + { + uint64_t pixelDataOffset = boost::lexical_cast(s); + + std::unique_ptr buffer( + area_.ReadRange(attachment.GetUuid(), attachment.GetContentType(), 0, pixelDataOffset)); + buffer->MoveToString(dicom); + return true; // Success + } + catch (boost::bad_lexical_cast&) + { + LOG(ERROR) << "Metadata \"PixelDataOffset\" is corrupted for instance: " << instancePublicId; + } + } + + return false; + } + + void ServerContext::ReadAttachment(std::string& result, const std::string& instancePublicId, FileContentType content, diff -r a3635a01a945 -r 1ec156a0da38 OrthancServer/Sources/ServerContext.h --- a/OrthancServer/Sources/ServerContext.h Thu Feb 11 17:51:04 2021 +0100 +++ b/OrthancServer/Sources/ServerContext.h Thu Feb 11 19:06:29 2021 +0100 @@ -159,9 +159,6 @@ static void SaveJobsThread(ServerContext* that, unsigned int sleepDelay); - void ReadDicomAsJsonInternal(std::string& result, - const std::string& instancePublicId); - void SaveJobsEngine(); virtual void SignalJobSubmitted(const std::string& jobId) ORTHANC_OVERRIDE; @@ -316,36 +313,27 @@ CompressionType compression); void ReadDicomAsJson(std::string& result, - const std::string& instancePublicId, - const std::set& ignoreTagLength); + const std::string& instancePublicId); void ReadDicomAsJson(Json::Value& result, const std::string& instancePublicId, const std::set& ignoreTagLength); - void ReadDicomAsJson(std::string& result, - const std::string& instancePublicId) - { - std::set ignoreTagLength; - ReadDicomAsJson(result, instancePublicId, ignoreTagLength); - } - void ReadDicomAsJson(Json::Value& result, - const std::string& instancePublicId) - { - std::set ignoreTagLength; - ReadDicomAsJson(result, instancePublicId, ignoreTagLength); - } + const std::string& instancePublicId); void ReadDicom(std::string& dicom, const std::string& instancePublicId); - // TODO CACHING MECHANISM AT THIS POINT + bool ReadDicomUntilPixelData(std::string& dicom, + const std::string& instancePublicId); + + // This method is for low-level operations on "/instances/.../attachments/..." void ReadAttachment(std::string& result, const std::string& instancePublicId, FileContentType content, bool uncompressIfNeeded); - + void SetStoreMD5ForAttachments(bool storeMD5); bool IsStoreMD5ForAttachments() const