changeset 5299:c9ea57d73603 am-experimental

New URI /instances/{id}/file-until-pixel-data
author Alain Mazy <am@osimis.io>
date Tue, 23 May 2023 17:38:26 +0200
parents c04230962098
children 7d913ee2f665
files NEWS OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp OrthancServer/Sources/ServerContext.cpp
diffstat 3 files changed, 59 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Fri Apr 28 10:42:27 2023 +0200
+++ b/NEWS	Tue May 23 17:38:26 2023 +0200
@@ -1,6 +1,11 @@
 Pending changes in the mainline
 ===============================
 
+REST API
+--------
+
+* New URI /instances/{id}/file-until-pixel-data
+
 Maintenance
 -----------
 
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp	Fri Apr 28 10:42:27 2023 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp	Tue May 23 17:38:26 2023 +0200
@@ -421,6 +421,30 @@
   }
 
 
+  static void GetInstanceFileUntiPixelData(RestApiGetCall& call)
+  {
+    if (call.IsDocumentation())
+    {
+      call.GetDocumentation()
+        .SetTag("Instances")
+        .SetSummary("Download DICOM Header (without the pixel data)")
+        .SetDescription("Download one DICOM instance header")
+        .SetUriArgument("id", "Orthanc identifier of the DICOM instance of interest")
+        .SetHttpHeader("Accept", "This HTTP header can be set to retrieve the DICOM instance in DICOMweb format")
+        .AddAnswerType(MimeType_Dicom, "The DICOM instance");
+      return;
+    }
+
+    ServerContext& context = OrthancRestApi::GetContext(call);
+
+    std::string publicId = call.GetUriComponent("id", "");
+
+    std::string buffer;
+    context.ReadDicomUntilPixelData(buffer, publicId);
+    call.GetOutput().AnswerBuffer(buffer, MimeType_Binary);
+  }
+
+
   static void ExportInstanceFile(RestApiPostCall& call)
   {
     if (call.IsDocumentation())
@@ -4011,6 +4035,7 @@
     Register("/studies/{id}/module-patient", GetModule<ResourceType_Study, DicomModule_Patient>);
 
     Register("/instances/{id}/file", GetInstanceFile);
+    Register("/instances/{id}/file-until-pixel-data", GetInstanceFileUntiPixelData);
     Register("/instances/{id}/export", ExportInstanceFile);
     Register("/instances/{id}/tags", GetInstanceTags);
     Register("/instances/{id}/simplified-tags", GetInstanceSimplifiedTags);
--- a/OrthancServer/Sources/ServerContext.cpp	Fri Apr 28 10:42:27 2023 +0200
+++ b/OrthancServer/Sources/ServerContext.cpp	Tue May 23 17:38:26 2023 +0200
@@ -1129,32 +1129,47 @@
   void ServerContext::ReadDicomForHeader(std::string& dicom,
                                          const std::string& instancePublicId)
   {
-    if (!ReadDicomUntilPixelData(dicom, instancePublicId))
-    {
-      ReadDicom(dicom, instancePublicId);
-    }
+    ReadDicomUntilPixelData(dicom, instancePublicId);
   }
 
   bool ServerContext::ReadDicomUntilPixelData(std::string& dicom,
                                               const std::string& instancePublicId)
   {
+    FileInfo attachment;
+    int64_t revision;  // Ignored
+
+    // if the attachment exists as such return it directly
+    if (index_.LookupAttachment(attachment, revision, instancePublicId, FileContentType_DicomUntilPixelData))
+    {
+      StorageAccessor accessor(area_, storageCache_, GetMetricsRegistry());
+      accessor.Read(dicom, attachment);
+      return true;
+    }
+
+    // if the storage area can not read part of files, return the whole file
     if (!area_.HasReadRange())
     {
-      return false;
+      ReadDicom(dicom, instancePublicId);
+      return true;
     }
-    
-    FileInfo attachment;
-    int64_t revision;  // Ignored
+
+    // else, read the start of the dicom file
+
     if (!index_.LookupAttachment(attachment, revision, instancePublicId, FileContentType_Dicom))
     {
       throw OrthancException(ErrorCode_InternalError,
-                             "Unable to read the DICOM file of instance " + instancePublicId);
+                            "Unable to read the DICOM file of instance " + instancePublicId);
+    }
+
+    // if the attachment is compressed, return the whole file
+    if (attachment.GetCompressionType() != CompressionType_None)
+    {
+      ReadDicom(dicom, instancePublicId);
+      return true;
     }
 
     std::string s;
-
-    if (attachment.GetCompressionType() == CompressionType_None &&
-        index_.LookupMetadata(s, revision, instancePublicId, ResourceType_Instance,
+    if (index_.LookupMetadata(s, revision, instancePublicId, ResourceType_Instance,
                               MetadataType_Instance_PixelDataOffset) &&
         !s.empty())
     {
@@ -1175,7 +1190,8 @@
       }
     }
 
-    return false;
+    ReadDicom(dicom, instancePublicId);
+    return true;
   }