changeset 2115:a657f7772e69

Handling of private tags/creators in the "Dictionary" configuration option
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 31 Oct 2016 15:23:32 +0100
parents e4f8e377782f
children 2fabd1073728
files NEWS OrthancServer/FromDcmtkBridge.cpp OrthancServer/FromDcmtkBridge.h OrthancServer/Internals/FindScp.cpp OrthancServer/OrthancFindRequestHandler.cpp OrthancServer/OrthancInitialization.cpp OrthancServer/OrthancMoveRequestHandler.cpp OrthancServer/Search/LookupIdentifierQuery.cpp Plugins/Engine/OrthancPlugins.cpp Plugins/Include/orthanc/OrthancCPlugin.h Resources/Configuration.json UnitTestsSources/DicomMapTests.cpp UnitTestsSources/FromDcmtkTests.cpp
diffstat 13 files changed, 213 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Thu Oct 27 12:37:30 2016 +0200
+++ b/NEWS	Mon Oct 31 15:23:32 2016 +0100
@@ -4,6 +4,7 @@
 General
 -------
 
+* Handling of private tags/creators in the "Dictionary" configuration option
 * New configuration options: "DicomScuTimeout" and "DicomScpTimeout"
 
 REST API
@@ -13,6 +14,11 @@
 * "Asynchronous" flag for URIs "/modalities/{...}/store" and "/peers/{...}/store"
   to avoid waiting for the completion of image transfers
 
+Plugins
+-------
+
+* New function: "OrthancPluginRegisterPrivateDictionaryTag()" to register private tags
+
 Maintenance
 -----------
 
--- a/OrthancServer/FromDcmtkBridge.cpp	Thu Oct 27 12:37:30 2016 +0200
+++ b/OrthancServer/FromDcmtkBridge.cpp	Mon Oct 31 15:23:32 2016 +0100
@@ -237,7 +237,8 @@
                                               ValueRepresentation vr,
                                               const std::string& name,
                                               unsigned int minMultiplicity,
-                                              unsigned int maxMultiplicity)
+                                              unsigned int maxMultiplicity,
+                                              const std::string& privateCreator)
   {
     if (minMultiplicity < 1)
     {
@@ -261,14 +262,55 @@
               << name << " (multiplicity: " << minMultiplicity << "-" 
               << (arbitrary ? "n" : boost::lexical_cast<std::string>(maxMultiplicity)) << ")";
 
-    std::auto_ptr<DcmDictEntry>  entry(new DcmDictEntry(tag.GetGroup(),
-                                                        tag.GetElement(),
-                                                        evr, name.c_str(),
-                                                        static_cast<int>(minMultiplicity),
-                                                        static_cast<int>(maxMultiplicity),
-                                                        NULL    /* version */,
-                                                        OFTrue  /* doCopyString */,
-                                                        NULL    /* private creator */));
+    std::auto_ptr<DcmDictEntry>  entry;
+    if (privateCreator.empty())
+    {
+      if (tag.GetGroup() % 2 == 1)
+      {
+        char buf[128];
+        sprintf(buf, "Warning: You are registering a private tag (%04x,%04x), "
+                "but no private creator was associated with it", 
+                tag.GetGroup(), tag.GetElement());
+        LOG(WARNING) << buf;
+      }
+
+      entry.reset(new DcmDictEntry(tag.GetGroup(),
+                                   tag.GetElement(),
+                                   evr, name.c_str(),
+                                   static_cast<int>(minMultiplicity),
+                                   static_cast<int>(maxMultiplicity),
+                                   NULL    /* version */,
+                                   OFTrue  /* doCopyString */,
+                                   NULL    /* private creator */));
+    }
+    else
+    {
+      // "Private Data Elements have an odd Group Number that is not
+      // (0001,eeee), (0003,eeee), (0005,eeee), (0007,eeee), or
+      // (FFFF,eeee)."
+      if (tag.GetGroup() % 2 == 0 /* even */ ||
+          tag.GetGroup() == 0x0001 ||
+          tag.GetGroup() == 0x0003 ||
+          tag.GetGroup() == 0x0005 ||
+          tag.GetGroup() == 0x0007 ||
+          tag.GetGroup() == 0xffff)
+      {
+        char buf[128];
+        sprintf(buf, "Trying to register private tag (%04x,%04x), but it must have an odd group >= 0x0009",
+                tag.GetGroup(), tag.GetElement());
+        LOG(ERROR) << buf;
+        throw OrthancException(ErrorCode_ParameterOutOfRange);
+      }
+
+      entry.reset(new DcmDictEntry(tag.GetGroup(),
+                                   tag.GetElement(),
+                                   evr, name.c_str(),
+                                   static_cast<int>(minMultiplicity),
+                                   static_cast<int>(maxMultiplicity),
+                                   "private" /* version */,
+                                   OFTrue    /* doCopyString */,
+                                   privateCreator.c_str()));
+    }
 
     entry->setGroupRangeRestriction(DcmDictRange_Unspecified);
     entry->setElementRangeRestriction(DcmDictRange_Unspecified);
@@ -429,7 +471,7 @@
         }
     
         /**
-         * Numberic types
+         * Numeric types
          **/ 
       
         case EVR_SL:  // signed long
@@ -571,7 +613,7 @@
     }
 
     // This code gives access to the name of the private tags
-    const std::string tagName = FromDcmtkBridge::GetName(tag);
+    std::string tagName = FromDcmtkBridge::GetTagName(element);
     
     switch (format)
     {
@@ -818,19 +860,23 @@
   }
 
 
-  std::string FromDcmtkBridge::GetName(const DicomTag& t)
+
+  static std::string GetTagNameInternal(DcmTag& tag)
   {
-    // Some patches for important tags because of different DICOM
-    // dictionaries between DCMTK versions
-    std::string n = t.GetMainTagsName();
-    if (n.size() != 0)
     {
-      return n;
+      // Some patches for important tags because of different DICOM
+      // dictionaries between DCMTK versions
+      DicomTag tmp(tag.getGroup(), tag.getElement());
+      std::string n = tmp.GetMainTagsName();
+      if (n.size() != 0)
+      {
+        return n;
+      }
+      // End of patches
     }
-    // End of patches
 
 #if 0
-    DcmTagKey tag(t.GetGroup(), t.GetElement());
+    // This version explicitly calls the dictionary
     const DcmDataDictionary& dict = dcmDataDict.rdlock();
     const DcmDictEntry* entry = dict.findEntry(tag, NULL);
 
@@ -843,7 +889,6 @@
     dcmDataDict.unlock();
     return s;
 #else
-    DcmTag tag(t.GetGroup(), t.GetElement());
     const char* name = tag.getTagName();
     if (name == NULL)
     {
@@ -857,6 +902,31 @@
   }
 
 
+  std::string FromDcmtkBridge::GetTagName(const DicomTag& t,
+                                          const std::string& privateCreator)
+  {
+    DcmTag tag(t.GetGroup(), t.GetElement());
+
+    if (!privateCreator.empty())
+    {
+      tag.setPrivateCreator(privateCreator.c_str());
+    }
+
+    return GetTagNameInternal(tag);
+  }
+
+
+  std::string FromDcmtkBridge::GetTagName(const DcmElement& element)
+  {
+    // Copy the tag to ensure const-correctness of DcmElement. Note
+    // that the private creator information is also copied.
+    DcmTag tag(element.getTag());  
+
+    return GetTagNameInternal(tag);
+  }
+
+
+
   DicomTag FromDcmtkBridge::ParseTag(const char* name)
   {
     if (strlen(name) == 9 &&
@@ -941,23 +1011,26 @@
     for (DicomMap::Map::const_iterator 
            it = values.map_.begin(); it != values.map_.end(); ++it)
     {
+      // TODO Inject PrivateCreator if some is available in the DicomMap?
+      const std::string tagName = GetTagName(it->first, "");
+
       if (simplify)
       {
         if (it->second->IsNull())
         {
-          result[GetName(it->first)] = Json::nullValue;
+          result[tagName] = Json::nullValue;
         }
         else
         {
           // TODO IsBinary
-          result[GetName(it->first)] = it->second->GetContent();
+          result[tagName] = it->second->GetContent();
         }
       }
       else
       {
         Json::Value value = Json::objectValue;
 
-        value["Name"] = GetName(it->first);
+        value["Name"] = tagName;
 
         if (it->second->IsNull())
         {
--- a/OrthancServer/FromDcmtkBridge.h	Thu Oct 27 12:37:30 2016 +0200
+++ b/OrthancServer/FromDcmtkBridge.h	Mon Oct 31 15:23:32 2016 +0100
@@ -34,6 +34,7 @@
 
 #include "ServerEnumerations.h"
 
+#include "../Core/DicomFormat/DicomElement.h"
 #include "../Core/DicomFormat/DicomMap.h"
 
 #include <dcmtk/dcmdata/dcdatset.h>
@@ -53,7 +54,8 @@
                                       ValueRepresentation vr,
                                       const std::string& name,
                                       unsigned int minMultiplicity,
-                                      unsigned int maxMultiplicity);
+                                      unsigned int maxMultiplicity,
+                                      const std::string& privateCreator);
 
     static Encoding DetectEncoding(DcmItem& dataset,
                                    Encoding defaultEncoding);
@@ -94,7 +96,15 @@
                        DicomToJsonFlags flags,
                        unsigned int maxStringLength);
 
-    static std::string GetName(const DicomTag& tag);
+    static std::string GetTagName(const DicomTag& tag,
+                                  const std::string& privateCreator);
+
+    static std::string GetTagName(const DcmElement& element);
+
+    static std::string GetTagName(const DicomElement& element)
+    {
+      return GetTagName(element.GetTag(), "");
+    }
 
     static DicomTag ParseTag(const char* name);
 
--- a/OrthancServer/Internals/FindScp.cpp	Thu Oct 27 12:37:30 2016 +0200
+++ b/OrthancServer/Internals/FindScp.cpp	Mon Oct 31 15:23:32 2016 +0100
@@ -171,7 +171,7 @@
                   {
                     LOG(WARNING) << "Orthanc only supports sequence matching on worklists, "
                                  << "ignoring C-FIND SCU constraint on tag (" << tag.Format() 
-                                 << ") " << FromDcmtkBridge::GetName(tag);
+                                 << ") " << FromDcmtkBridge::GetTagName(*element);
                   }
 
                   sequencesToReturn.push_back(tag);
--- a/OrthancServer/OrthancFindRequestHandler.cpp	Thu Oct 27 12:37:30 2016 +0200
+++ b/OrthancServer/OrthancFindRequestHandler.cpp	Mon Oct 31 15:23:32 2016 +0100
@@ -582,7 +582,7 @@
       if (!query.GetElement(i).GetValue().IsNull())
       {
         LOG(INFO) << "  " << query.GetElement(i).GetTag()
-                  << "  " << FromDcmtkBridge::GetName(query.GetElement(i).GetTag())
+                  << "  " << FromDcmtkBridge::GetTagName(query.GetElement(i))
                   << " = " << query.GetElement(i).GetValue().GetContent();
       }
     }
@@ -591,7 +591,7 @@
          it != sequencesToReturn.end(); ++it)
     {
       LOG(INFO) << "  (" << it->Format()
-                << ")  " << FromDcmtkBridge::GetName(*it)
+                << ")  " << FromDcmtkBridge::GetTagName(*it, "")
                 << " : sequence tag whose content will be copied";
     }
 
@@ -604,16 +604,17 @@
 
     for (size_t i = 0; i < query.GetSize(); i++)
     {
-      const DicomTag tag = query.GetElement(i).GetTag();
+      const DicomElement& element = query.GetElement(i);
+      const DicomTag tag = element.GetTag();
 
-      if (query.GetElement(i).GetValue().IsNull() ||
+      if (element.GetValue().IsNull() ||
           tag == DICOM_TAG_QUERY_RETRIEVE_LEVEL ||
           tag == DICOM_TAG_SPECIFIC_CHARACTER_SET)
       {
         continue;
       }
 
-      std::string value = query.GetElement(i).GetValue().GetContent();
+      std::string value = element.GetValue().GetContent();
       if (value.size() == 0)
       {
         // An empty string corresponds to a "*" wildcard constraint, so we ignore it
@@ -637,7 +638,7 @@
       else
       {
         LOG(INFO) << "Because of a patch for the manufacturer of the remote modality, " 
-                  << "ignoring constraint on tag (" << tag.Format() << ") " << FromDcmtkBridge::GetName(tag);
+                  << "ignoring constraint on tag (" << tag.Format() << ") " << FromDcmtkBridge::GetTagName(element);
       }
     }
 
--- a/OrthancServer/OrthancInitialization.cpp	Thu Oct 27 12:37:30 2016 +0200
+++ b/OrthancServer/OrthancInitialization.cpp	Mon Oct 31 15:23:32 2016 +0100
@@ -394,11 +394,12 @@
       const Json::Value& content = configuration["Dictionary"][tags[i]];
       if (content.type() != Json::arrayValue ||
           content.size() < 2 ||
-          content.size() > 4 ||
+          content.size() > 5 ||
           content[0].type() != Json::stringValue ||
           content[1].type() != Json::stringValue ||
           (content.size() >= 3 && content[2].type() != Json::intValue) ||
-          (content.size() >= 4 && content[3].type() != Json::intValue))
+          (content.size() >= 4 && content[3].type() != Json::intValue) ||
+          (content.size() >= 5 && content[4].type() != Json::stringValue))
       {
         throw OrthancException(ErrorCode_BadFileFormat);
       }
@@ -408,8 +409,9 @@
       std::string name = content[1].asString();
       unsigned int minMultiplicity = (content.size() >= 2) ? content[2].asUInt() : 1;
       unsigned int maxMultiplicity = (content.size() >= 3) ? content[3].asUInt() : 1;
+      std::string privateCreator = (content.size() >= 4) ? content[4].asString() : "";
 
-      FromDcmtkBridge::RegisterDictionaryTag(tag, vr, name, minMultiplicity, maxMultiplicity);
+      FromDcmtkBridge::RegisterDictionaryTag(tag, vr, name, minMultiplicity, maxMultiplicity, privateCreator);
     }
   }
 
--- a/OrthancServer/OrthancMoveRequestHandler.cpp	Thu Oct 27 12:37:30 2016 +0200
+++ b/OrthancServer/OrthancMoveRequestHandler.cpp	Mon Oct 31 15:23:32 2016 +0100
@@ -181,7 +181,7 @@
         if (!query.GetElement(i).GetValue().IsNull())
         {
           LOG(INFO) << "  " << query.GetElement(i).GetTag()
-                    << "  " << FromDcmtkBridge::GetName(query.GetElement(i).GetTag())
+                    << "  " << FromDcmtkBridge::GetTagName(query.GetElement(i))
                     << " = " << query.GetElement(i).GetValue().GetContent();
         }
       }
--- a/OrthancServer/Search/LookupIdentifierQuery.cpp	Thu Oct 27 12:37:30 2016 +0200
+++ b/OrthancServer/Search/LookupIdentifierQuery.cpp	Mon Oct 31 15:23:32 2016 +0100
@@ -264,7 +264,7 @@
       for (size_t j = 0; j < (*it)->GetSize(); j++)
       {
         const Constraint& c = (*it)->GetConstraint(j);
-        s << FromDcmtkBridge::GetName(c.GetTag());
+        s << FromDcmtkBridge::GetTagName(c.GetTag(), "");
 
         switch (c.GetType())
         {
--- a/Plugins/Engine/OrthancPlugins.cpp	Thu Oct 27 12:37:30 2016 +0200
+++ b/Plugins/Engine/OrthancPlugins.cpp	Mon Oct 31 15:23:32 2016 +0100
@@ -563,8 +563,8 @@
 
         case _OrthancPluginService_GetFindQueryTagName:
         {
-          const DicomTag& tag = currentQuery_->GetElement(operation.index).GetTag();
-          *operation.resultString = CopyString(FromDcmtkBridge::GetName(tag));
+          const DicomElement& element = currentQuery_->GetElement(operation.index);
+          *operation.resultString = CopyString(FromDcmtkBridge::GetTagName(element));
           break;
         }
 
@@ -2758,7 +2758,17 @@
           *reinterpret_cast<const _OrthancPluginRegisterDictionaryTag*>(parameters);
         FromDcmtkBridge::RegisterDictionaryTag(DicomTag(p.group, p.element),
                                                Plugins::Convert(p.vr), p.name,
-                                               p.minMultiplicity, p.maxMultiplicity);
+                                               p.minMultiplicity, p.maxMultiplicity, "");
+        return true;
+      }
+
+      case _OrthancPluginService_RegisterPrivateDictionaryTag:
+      {
+        const _OrthancPluginRegisterPrivateDictionaryTag& p =
+          *reinterpret_cast<const _OrthancPluginRegisterPrivateDictionaryTag*>(parameters);
+        FromDcmtkBridge::RegisterDictionaryTag(DicomTag(p.group, p.element),
+                                               Plugins::Convert(p.vr), p.name,
+                                               p.minMultiplicity, p.maxMultiplicity, p.privateCreator);
         return true;
       }
 
--- a/Plugins/Include/orthanc/OrthancCPlugin.h	Thu Oct 27 12:37:30 2016 +0200
+++ b/Plugins/Include/orthanc/OrthancCPlugin.h	Mon Oct 31 15:23:32 2016 +0100
@@ -116,7 +116,7 @@
 #endif
 
 #define ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER     1
-#define ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER     1
+#define ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER     2
 #define ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER  0
 
 
@@ -407,6 +407,7 @@
     _OrthancPluginService_LookupDictionary = 26,
     _OrthancPluginService_CallHttpClient2 = 27,
     _OrthancPluginService_GenerateUuid = 28,
+    _OrthancPluginService_RegisterPrivateDictionaryTag = 29,
 
     /* Registration of callbacks */
     _OrthancPluginService_RegisterRestCallback = 1000,
@@ -4091,9 +4092,9 @@
   /**
    * @brief Register a new tag into the DICOM dictionary.
    *
-   * This function declares a new tag in the dictionary of DICOM tags
-   * that are known to Orthanc. This function should be used in the
-   * OrthancPluginInitialize() callback.
+   * This function declares a new public tag in the dictionary of
+   * DICOM tags that are known to Orthanc. This function should be
+   * used in the OrthancPluginInitialize() callback.
    *
    * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
    * @param group The group of the tag.
@@ -4104,6 +4105,7 @@
    * @param maxMultiplicity The maximum multiplicity of the tag. A value of 0 means
    * an arbitrary multiplicity ("<tt>n</tt>").
    * @return 0 if success, other value if error.
+   * @see OrthancPluginRegisterPrivateDictionaryTag()
    * @ingroup Toolbox
    **/
   ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode  OrthancPluginRegisterDictionaryTag(
@@ -4128,6 +4130,60 @@
 
 
 
+  typedef struct
+  {
+    uint16_t                          group;
+    uint16_t                          element;
+    OrthancPluginValueRepresentation  vr;
+    const char*                       name;
+    uint32_t                          minMultiplicity;
+    uint32_t                          maxMultiplicity;
+    const char*                       privateCreator;
+  } _OrthancPluginRegisterPrivateDictionaryTag;
+  
+  /**
+   * @brief Register a new private tag into the DICOM dictionary.
+   *
+   * This function declares a new private tag in the dictionary of
+   * DICOM tags that are known to Orthanc. This function should be
+   * used in the OrthancPluginInitialize() callback.
+   *
+   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+   * @param group The group of the tag.
+   * @param element The element of the tag.
+   * @param vr The value representation of the tag.
+   * @param name The nickname of the tag.
+   * @param minMultiplicity The minimum multiplicity of the tag (must be above 0).
+   * @param maxMultiplicity The maximum multiplicity of the tag. A value of 0 means
+   * an arbitrary multiplicity ("<tt>n</tt>").
+   * @param privateCreator The private creator of this private tag.
+   * @return 0 if success, other value if error.
+   * @see OrthancPluginRegisterDictionaryTag()
+   * @ingroup Toolbox
+   **/
+  ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode  OrthancPluginRegisterPrivateDictionaryTag(
+    OrthancPluginContext*             context,
+    uint16_t                          group,
+    uint16_t                          element,
+    OrthancPluginValueRepresentation  vr,
+    const char*                       name,
+    uint32_t                          minMultiplicity,
+    uint32_t                          maxMultiplicity,
+    const char*                       privateCreator)
+  {
+    _OrthancPluginRegisterPrivateDictionaryTag params;
+    params.group = group;
+    params.element = element;
+    params.vr = vr;
+    params.name = name;
+    params.minMultiplicity = minMultiplicity;
+    params.maxMultiplicity = maxMultiplicity;
+    params.privateCreator = privateCreator;
+
+    return context->InvokeService(context, _OrthancPluginService_RegisterPrivateDictionaryTag, &params);
+  }
+
+
 
   typedef struct
   {
--- a/Resources/Configuration.json	Thu Oct 27 12:37:30 2016 +0200
+++ b/Resources/Configuration.json	Mon Oct 31 15:23:32 2016 +0100
@@ -321,9 +321,11 @@
   // to Orthanc. Each line must contain the tag (formatted as 2
   // hexadecimal numbers), the value representation (2 upcase
   // characters), a nickname for the tag, possibly the minimum
-  // multiplicity (> 0 with defaults to 1), and possibly the maximum
-  // multiplicity (0 means arbitrary multiplicity, defaults to 1).
+  // multiplicity (> 0 with defaults to 1), possibly the maximum
+  // multiplicity (0 means arbitrary multiplicity, defaults to 1), and
+  // possibly the Private Creator (for private tags).
   "Dictionary" : {
     // "0014,1020" : [ "DA", "ValidationExpiryDate", 1, 1 ]
+    // "00e1,10c2" : [ "UI", "PET-CT Multi Modality Name", 1, 1, "ELSCINT1" ]
   }
 }
--- a/UnitTestsSources/DicomMapTests.cpp	Thu Oct 27 12:37:30 2016 +0200
+++ b/UnitTestsSources/DicomMapTests.cpp	Mon Oct 31 15:23:32 2016 +0100
@@ -204,7 +204,7 @@
 
     if (!ok)
     {
-      std::cout << it->Format() << ": " << FromDcmtkBridge::GetName(*it)
+      std::cout << it->Format() << ": " << FromDcmtkBridge::GetTagName(*it, "")
                 << " not expected at level " << EnumerationToString(level) << std::endl;
     }
 
--- a/UnitTestsSources/FromDcmtkTests.cpp	Thu Oct 27 12:37:30 2016 +0200
+++ b/UnitTestsSources/FromDcmtkTests.cpp	Mon Oct 31 15:23:32 2016 +0100
@@ -57,7 +57,7 @@
 
 TEST(DicomFormat, Tag)
 {
-  ASSERT_EQ("PatientName", FromDcmtkBridge::GetName(DicomTag(0x0010, 0x0010)));
+  ASSERT_EQ("PatientName", FromDcmtkBridge::GetTagName(DicomTag(0x0010, 0x0010), ""));
 
   DicomTag t = FromDcmtkBridge::ParseTag("SeriesDescription");
   ASSERT_EQ(0x0008, t.GetGroup());
@@ -576,8 +576,8 @@
 
 TEST(ParsedDicomFile, ToJsonFlags1)
 {
-  FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7053, 0x1000), ValueRepresentation_PersonName, "MyPrivateTag", 1, 1);
-  FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7050, 0x1000), ValueRepresentation_PersonName, "Declared public tag", 1, 1);
+  FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7053, 0x1000), ValueRepresentation_PersonName, "MyPrivateTag", 1, 1, "");
+  FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7050, 0x1000), ValueRepresentation_PersonName, "Declared public tag", 1, 1, "");
 
   ParsedDicomFile f(true);
   f.Insert(DicomTag(0x7050, 0x1000), "Some public tag", false);  // Even group => public tag
@@ -717,9 +717,9 @@
 
 TEST(ParsedDicomFile, FromJson)
 {
-  FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7057, 0x1000), ValueRepresentation_OtherByte, "MyPrivateTag", 1, 1);
-  FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7059, 0x1000), ValueRepresentation_OtherByte, "MyPrivateTag", 1, 1);
-  FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7050, 0x1000), ValueRepresentation_PersonName, "Declared public tag", 1, 1);
+  FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7057, 0x1000), ValueRepresentation_OtherByte, "MyPrivateTag", 1, 1, "");
+  FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7059, 0x1000), ValueRepresentation_OtherByte, "MyPrivateTag", 1, 1, "");
+  FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7050, 0x1000), ValueRepresentation_PersonName, "Declared public tag", 1, 1, "");
 
   Json::Value v;
   const std::string sopClassUid = "1.2.840.10008.5.1.4.1.1.1";  // CR Image Storage: