changeset 1906:d7c1cb559431

optimization for multi-frame images
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 05 Jan 2016 17:45:27 +0100
parents 8b1baa2315b8
children 5011a597b6ce
files OrthancServer/OrthancRestApi/OrthancRestResources.cpp Plugins/Engine/OrthancPlugins.cpp Plugins/Engine/OrthancPlugins.h
diffstat 3 files changed, 36 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/OrthancRestApi/OrthancRestResources.cpp	Tue Jan 05 17:25:01 2016 +0100
+++ b/OrthancServer/OrthancRestApi/OrthancRestResources.cpp	Tue Jan 05 17:45:27 2016 +0100
@@ -374,29 +374,28 @@
       return;
     }
 
-    std::string publicId = call.GetUriComponent("id", "");
-    std::string dicomContent;
-    context.ReadFile(dicomContent, publicId, FileContentType_Dicom);
+    std::auto_ptr<ImageAccessor> decoded;
 
     try
     {
+      std::string publicId = call.GetUriComponent("id", "");
+
 #if ORTHANC_PLUGINS_ENABLED == 1
-      IDicomImageDecoder& decoder = context.GetPlugins();
-#else
-      DefaultDicomImageDecoder decoder;  // This is Orthanc's built-in decoder
+      if (context.GetPlugins().HasCustomImageDecoder())
+      {
+        // TODO create a cache of file
+        std::string dicomContent;
+        context.ReadFile(dicomContent, publicId, FileContentType_Dicom);
+        decoded.reset(context.GetPlugins().Decode(dicomContent.c_str(), dicomContent.size(), frame));
+      }
 #endif
 
-      std::auto_ptr<ImageAccessor> decoded(decoder.Decode(dicomContent.c_str(), dicomContent.size(), frame));
-
-      ImageToEncode image(decoded, mode);
-
-      HttpContentNegociation negociation;
-      EncodePng png(image);          negociation.Register("image/png", png);
-      EncodeJpeg jpeg(image, call);  negociation.Register("image/jpeg", jpeg);
-
-      if (negociation.Apply(call.GetHttpHeaders()))
+      if (decoded.get() == NULL)
       {
-        image.Answer(call.GetOutput());
+        // Use Orthanc's built-in decoder, using the cache to speed-up
+        // things on multi-frame images
+        ServerContext::DicomCacheLocker locker(OrthancRestApi::GetContext(call), publicId);
+        decoded.reset(DicomImageDecoder::Decode(locker.GetDicom(), frame));
       }
     }
     catch (OrthancException& e)
@@ -417,6 +416,17 @@
         call.GetOutput().Redirect(root + "app/images/unsupported.png");
       }
     }
+
+    ImageToEncode image(decoded, mode);
+
+    HttpContentNegociation negociation;
+    EncodePng png(image);          negociation.Register("image/png", png);
+    EncodeJpeg jpeg(image, call);  negociation.Register("image/jpeg", jpeg);
+
+    if (negociation.Apply(call.GetHttpHeaders()))
+    {
+      image.Answer(call.GetOutput());
+    }
   }
 
 
--- a/Plugins/Engine/OrthancPlugins.cpp	Tue Jan 05 17:25:01 2016 +0100
+++ b/Plugins/Engine/OrthancPlugins.cpp	Tue Jan 05 17:45:27 2016 +0100
@@ -2375,6 +2375,13 @@
   }
 
 
+  bool OrthancPlugins::HasCustomImageDecoder()
+  {
+    boost::mutex::scoped_lock lock(pimpl_->decodeImageCallbackMutex_);
+    return (pimpl_->decodeImageCallback_ != NULL);
+  }
+
+
   ImageAccessor*  OrthancPlugins::Decode(const void* dicom,
                                          size_t size,
                                          unsigned int frame)
@@ -2395,6 +2402,6 @@
     }
 
     DefaultDicomImageDecoder defaultDecoder;
-    return defaultDecoder.Decode(dicom, size, frame);
+    return defaultDecoder.Decode(dicom, size, frame);  // TODO RETURN NULL ???
   }
 }
--- a/Plugins/Engine/OrthancPlugins.h	Tue Jan 05 17:25:01 2016 +0100
+++ b/Plugins/Engine/OrthancPlugins.h	Tue Jan 05 17:45:27 2016 +0100
@@ -234,6 +234,8 @@
 
     virtual IWorklistRequestHandler* ConstructWorklistRequestHandler();
 
+    bool HasCustomImageDecoder();
+
     virtual ImageAccessor* Decode(const void* dicom,
                                   size_t size,
                                   unsigned int frame);