changeset 1861:a7bea843a7bc

"OrthancPluginLookupDictionary()" to get information about some DICOM tag
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 02 Dec 2015 13:00:18 +0100
parents c7d70f659190
children 90e8606c62a0 f13be15a22b6
files NEWS OrthancServer/FromDcmtkBridge.cpp Plugins/Engine/OrthancPlugins.cpp Plugins/Engine/OrthancPlugins.h Plugins/Engine/PluginsEnumerations.cpp Plugins/Engine/PluginsEnumerations.h Plugins/Include/orthanc/OrthancCPlugin.h Plugins/Samples/Basic/Plugin.c
diffstat 8 files changed, 223 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Wed Dec 02 11:26:52 2015 +0100
+++ b/NEWS	Wed Dec 02 13:00:18 2015 +0100
@@ -43,6 +43,7 @@
   - "OrthancPluginDicomBufferToJson()" to convert DICOM to JSON
   - "OrthancPluginRegisterErrorCode()" to declare custom error codes
   - "OrthancPluginRegisterDictionaryTag()" to declare custom DICOM tags
+  - "OrthancPluginLookupDictionary()" to get information about some DICOM tag
   - "OrthancPluginRestApiGet2()" to provide HTTP headers when calling Orthanc API
   - "OrthancPluginGetInstanceOrigin()" to know through which mechanism an instance was received
   - "OrthancPluginCreateImage()" and "OrthancPluginCreateImageAccessor()" to create images
--- a/OrthancServer/FromDcmtkBridge.cpp	Wed Dec 02 11:26:52 2015 +0100
+++ b/OrthancServer/FromDcmtkBridge.cpp	Wed Dec 02 13:00:18 2015 +0100
@@ -880,6 +880,21 @@
       return DicomTag(group, element);
     }
 
+    if (strlen(name) == 8 &&
+        isxdigit(name[0]) &&
+        isxdigit(name[1]) &&
+        isxdigit(name[2]) &&
+        isxdigit(name[3]) &&
+        isxdigit(name[4]) &&
+        isxdigit(name[5]) &&
+        isxdigit(name[6]) &&
+        isxdigit(name[7]))        
+    {
+      uint16_t group = GetTagValue(name);
+      uint16_t element = GetTagValue(name + 4);
+      return DicomTag(group, element);
+    }
+
 #if 0
     const DcmDataDictionary& dict = dcmDataDict.rdlock();
     const DcmDictEntry* entry = dict.findEntry(name);
--- a/Plugins/Engine/OrthancPlugins.cpp	Wed Dec 02 11:26:52 2015 +0100
+++ b/Plugins/Engine/OrthancPlugins.cpp	Wed Dec 02 13:00:18 2015 +0100
@@ -44,6 +44,7 @@
 #include "../../Core/OrthancException.h"
 #include "../../Core/Toolbox.h"
 #include "../../OrthancServer/FromDcmtkBridge.h"
+#include "../../OrthancServer/ToDcmtkBridge.h"
 #include "../../OrthancServer/OrthancInitialization.h"
 #include "../../OrthancServer/ServerContext.h"
 #include "../../OrthancServer/ServerToolbox.h"
@@ -60,6 +61,8 @@
 #include "PluginsEnumerations.h"
 
 #include <boost/regex.hpp> 
+#include <dcmtk/dcmdata/dcdict.h>
+#include <dcmtk/dcmdata/dcdicent.h>
 
 namespace Orthanc
 {
@@ -1590,6 +1593,59 @@
   }
 
 
+
+  namespace
+  {
+    class DictionaryReadLocker
+    {
+    private:
+      const DcmDataDictionary& dictionary_;
+
+    public:
+      DictionaryReadLocker() : dictionary_(dcmDataDict.rdlock())
+      {
+      }
+
+      ~DictionaryReadLocker()
+      {
+        dcmDataDict.unlock();
+      }
+
+      const DcmDataDictionary* operator->()
+      {
+        return &dictionary_;
+      }
+    };
+  }
+
+
+  void OrthancPlugins::ApplyLookupDictionary(const void* parameters)
+  {
+    const _OrthancPluginLookupDictionary& p =
+      *reinterpret_cast<const _OrthancPluginLookupDictionary*>(parameters);
+
+    DicomTag tag(FromDcmtkBridge::ParseTag(p.name));
+    DcmTagKey tag2(tag.GetGroup(), tag.GetElement());
+
+    DictionaryReadLocker locker;
+    const DcmDictEntry* entry = locker->findEntry(tag2, NULL);
+
+    if (entry == NULL)
+    {
+      throw OrthancException(ErrorCode_UnknownDicomTag);
+    }
+    else
+    {
+      p.target->group = entry->getKey().getGroup();
+      p.target->element = entry->getKey().getElement();
+      p.target->vr = Plugins::Convert(entry->getEVR());
+      p.target->minMultiplicity = static_cast<uint32_t>(entry->getVMMin());
+      p.target->maxMultiplicity = (entry->getVMMax() == DcmVariableVM ? 0 : static_cast<uint32_t>(entry->getVMMax()));
+    }
+  }
+
+
+
   bool OrthancPlugins::InvokeService(SharedLibrary& plugin,
                                      _OrthancPluginService service,
                                      const void* parameters)
@@ -2148,6 +2204,10 @@
         ComputeHash(service, parameters);
         return true;
 
+      case _OrthancPluginService_LookupDictionary:
+        ApplyLookupDictionary(parameters);
+        return true;
+
       default:
       {
         // This service is unknown to the Orthanc plugin engine
--- a/Plugins/Engine/OrthancPlugins.h	Wed Dec 02 11:26:52 2015 +0100
+++ b/Plugins/Engine/OrthancPlugins.h	Wed Dec 02 13:00:18 2015 +0100
@@ -150,6 +150,8 @@
     void ApplyCreateImage(_OrthancPluginService service,
                           const void* parameters);
 
+    void ApplyLookupDictionary(const void* parameters);
+
     void ComputeHash(_OrthancPluginService service,
                      const void* parameters);
 
--- a/Plugins/Engine/PluginsEnumerations.cpp	Wed Dec 02 11:26:52 2015 +0100
+++ b/Plugins/Engine/PluginsEnumerations.cpp	Wed Dec 02 13:00:18 2015 +0100
@@ -394,6 +394,95 @@
           throw OrthancException(ErrorCode_ParameterOutOfRange);
       }
     }
+
+
+    OrthancPluginValueRepresentation Convert(DcmEVR vr)
+    {
+      switch (vr)
+      {
+        case EVR_AE:
+          return OrthancPluginValueRepresentation_AE;
+
+        case EVR_AS:
+          return OrthancPluginValueRepresentation_AS;
+
+        case EVR_AT:
+          return OrthancPluginValueRepresentation_AT;
+
+        case EVR_CS:
+          return OrthancPluginValueRepresentation_CS;
+
+        case EVR_DA:
+          return OrthancPluginValueRepresentation_DA;
+
+        case EVR_DS:
+          return OrthancPluginValueRepresentation_DS;
+
+        case EVR_DT:
+          return OrthancPluginValueRepresentation_DT;
+
+        case EVR_FD:
+          return OrthancPluginValueRepresentation_FD;
+
+        case EVR_FL:
+          return OrthancPluginValueRepresentation_FL;
+
+        case EVR_IS:
+          return OrthancPluginValueRepresentation_IS;
+
+        case EVR_LO:
+          return OrthancPluginValueRepresentation_LO;
+
+        case EVR_LT:
+          return OrthancPluginValueRepresentation_LT;
+
+        case EVR_OB:
+          return OrthancPluginValueRepresentation_OB;
+
+        case EVR_OF:
+          return OrthancPluginValueRepresentation_OF;
+
+        case EVR_OW:
+          return OrthancPluginValueRepresentation_OW;
+
+        case EVR_PN:
+          return OrthancPluginValueRepresentation_PN;
+
+        case EVR_SH:
+          return OrthancPluginValueRepresentation_SH;
+
+        case EVR_SL:
+          return OrthancPluginValueRepresentation_SL;
+
+        case EVR_SQ:
+          return OrthancPluginValueRepresentation_SQ;
+
+        case EVR_SS:
+          return OrthancPluginValueRepresentation_SS;
+
+        case EVR_ST:
+          return OrthancPluginValueRepresentation_ST;
+
+        case EVR_TM:
+          return OrthancPluginValueRepresentation_TM;
+
+        case EVR_UI:
+          return OrthancPluginValueRepresentation_UI;
+
+        case EVR_UL:
+          return OrthancPluginValueRepresentation_UL;
+
+        case EVR_US:
+          return OrthancPluginValueRepresentation_US;
+
+        case EVR_UT:
+          return OrthancPluginValueRepresentation_UT;
+
+        case EVR_UN:
+        default:
+          return OrthancPluginValueRepresentation_UN;  // Unknown
+      }
+    }
 #endif
   }
 }
--- a/Plugins/Engine/PluginsEnumerations.h	Wed Dec 02 11:26:52 2015 +0100
+++ b/Plugins/Engine/PluginsEnumerations.h	Wed Dec 02 13:00:18 2015 +0100
@@ -69,6 +69,8 @@
 
 #if !defined(ORTHANC_ENABLE_DCMTK) || ORTHANC_ENABLE_DCMTK != 0
     DcmEVR Convert(OrthancPluginValueRepresentation vr);
+
+    OrthancPluginValueRepresentation Convert(DcmEVR vr);
 #endif
   }
 }
--- a/Plugins/Include/orthanc/OrthancCPlugin.h	Wed Dec 02 11:26:52 2015 +0100
+++ b/Plugins/Include/orthanc/OrthancCPlugin.h	Wed Dec 02 13:00:18 2015 +0100
@@ -400,6 +400,7 @@
     _OrthancPluginService_CreateDicom = 23,
     _OrthancPluginService_ComputeMd5 = 24,
     _OrthancPluginService_ComputeSha1 = 25,
+    _OrthancPluginService_LookupDictionary = 26,
 
     /* Registration of callbacks */
     _OrthancPluginService_RegisterRestCallback = 1000,
@@ -962,6 +963,20 @@
   } OrthancPluginContext;
 
 
+  
+  /**
+   * @brief An entry in the dictionary of DICOM tags.
+   **/
+  typedef struct
+  {
+    uint16_t                          group;            /*!< The group of the tag */
+    uint16_t                          element;          /*!< The element of the tag */
+    OrthancPluginValueRepresentation  vr;               /*!< The value representation of the tag */
+    uint32_t                          minMultiplicity;  /*!< The minimum multiplicity of the tag */
+    uint32_t                          maxMultiplicity;  /*!< The maximum multiplicity of the tag (0 means arbitrary) */
+  } OrthancPluginDictionaryEntry;
+
+
 
   /**
    * @brief Free a string.
@@ -4627,6 +4642,41 @@
     }
   }
 
+
+
+  typedef struct
+  {
+    OrthancPluginDictionaryEntry* target;
+    const char*                   name;
+  } _OrthancPluginLookupDictionary;
+
+  /**
+   * @brief Get information about the given DICOM tag.
+   *
+   * This functions makes a lookup in the dictionary of DICOM tags
+   * that are known to Orthanc, and returns information about this
+   * tag. The tag can be specified using its human-readable name
+   * (e.g. "PatientName") or a set of two hexadecimal numbers
+   * (e.g. "0010-0020").
+   * 
+   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+   * @param target Where to store the information about the tag.
+   * @param name The name of the DICOM tag.
+   * @return 0 if success, other value if error.
+   * @ingroup Toolbox
+   **/
+  ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode  OrthancPluginLookupDictionary(
+    OrthancPluginContext*          context,
+    OrthancPluginDictionaryEntry*  target,
+    const char*                    name)
+  {
+    _OrthancPluginLookupDictionary params;
+    params.target = target;
+    params.name = name;
+    return context->InvokeService(context, _OrthancPluginService_LookupDictionary, &params);
+  }
+
+
 #ifdef  __cplusplus
 }
 #endif
--- a/Plugins/Samples/Basic/Plugin.c	Wed Dec 02 11:26:52 2015 +0100
+++ b/Plugins/Samples/Basic/Plugin.c	Wed Dec 02 13:00:18 2015 +0100
@@ -327,6 +327,7 @@
   OrthancPluginMemoryBuffer tmp;
   char info[1024], *s;
   int counter, i;
+  OrthancPluginDictionaryEntry entry;
 
   context = c;
   OrthancPluginLogWarning(context, "Sample plugin is initializing");
@@ -407,6 +408,9 @@
   OrthancPluginRegisterDictionaryTag(context, 0x0014, 0x1020, OrthancPluginValueRepresentation_DA,
                                      "ValidationExpiryDate", 1, 1);
 
+  OrthancPluginLookupDictionary(context, &entry, "ValidationExpiryDate");
+  OrthancPluginLookupDictionary(context, &entry, "0010-0010");
+
   return 0;
 }