changeset 5318:68e15471b408

added ParsedDicomFile::InjectEmptyPixelData()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 23 Jun 2023 18:01:55 +0200
parents 9875e1f24394
children f2e1ad71e49c
files OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp
diffstat 3 files changed, 135 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp	Thu Jun 22 21:30:45 2023 +0200
+++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp	Fri Jun 23 18:01:55 2023 +0200
@@ -2121,6 +2121,41 @@
     }
   }
 
+  
+  void ParsedDicomFile::InjectEmptyPixelData(ValueRepresentation vr)
+  {
+    DcmTag k(DICOM_TAG_PIXEL_DATA.GetGroup(),
+             DICOM_TAG_PIXEL_DATA.GetElement());
+
+    DcmItem& dataset = *GetDcmtkObjectConst().getDataset();
+
+    DcmElement *element = NULL;
+    if (!dataset.findAndGetElement(k, element).good() ||
+        element == NULL)
+    {
+      // The pixel data is indeed nonexistent, insert it now
+      switch (vr)
+      {
+        case ValueRepresentation_OtherByte:
+          if (!dataset.putAndInsertUint8Array(k, NULL, 0).good())
+          {
+            throw OrthancException(ErrorCode_InternalError);
+          }
+          break;
+
+        case ValueRepresentation_OtherWord:
+          if (!dataset.putAndInsertUint16Array(k, NULL, 0).good())
+          {
+            throw OrthancException(ErrorCode_InternalError);
+          }
+          break;
+
+        default:
+          throw OrthancException(ErrorCode_ParameterOutOfRange);
+      }
+    }
+  }
+
 
 #if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1
   // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore
--- a/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h	Thu Jun 22 21:30:45 2023 +0200
+++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h	Fri Jun 23 18:01:55 2023 +0200
@@ -309,5 +309,7 @@
 
     ImageAccessor* DecodeAllOverlays(int& originX,
                                      int& originY) const;
+
+    void InjectEmptyPixelData(ValueRepresentation vr);
   };
 }
--- a/OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp	Thu Jun 22 21:30:45 2023 +0200
+++ b/OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp	Fri Jun 23 18:01:55 2023 +0200
@@ -3221,6 +3221,98 @@
 }
 
 
+TEST(ParsedDicomFile, InjectEmptyPixelData)
+{
+  static const char* PIXEL_DATA = "7FE00010";
+
+  {
+    ParsedDicomFile dicom(true);
+
+    DicomWebJsonVisitor visitor;
+    dicom.Apply(visitor);
+
+    ASSERT_FALSE(visitor.GetResult().isMember(PIXEL_DATA));
+  }
+
+  {
+    ParsedDicomFile dicom(true);
+    dicom.InjectEmptyPixelData(ValueRepresentation_OtherByte);
+    dicom.InjectEmptyPixelData(ValueRepresentation_OtherWord); // Must be ignored
+
+    DicomWebJsonVisitor visitor;
+    dicom.Apply(visitor);
+
+    ASSERT_TRUE(visitor.GetResult().isMember(PIXEL_DATA));
+    ASSERT_EQ(2u, visitor.GetResult() [PIXEL_DATA].size());
+    ASSERT_EQ("", visitor.GetResult() [PIXEL_DATA]["InlineBinary"].asString());
+    ASSERT_EQ("OB", visitor.GetResult() [PIXEL_DATA]["vr"].asString());
+  }
+
+  {
+    ParsedDicomFile dicom(true);
+    dicom.InjectEmptyPixelData(ValueRepresentation_OtherWord);
+    dicom.InjectEmptyPixelData(ValueRepresentation_OtherByte); // Must be ignored
+
+    DicomWebJsonVisitor visitor;
+    dicom.Apply(visitor);
+
+    ASSERT_TRUE(visitor.GetResult().isMember(PIXEL_DATA));
+    ASSERT_EQ(2u, visitor.GetResult() [PIXEL_DATA].size());
+    ASSERT_EQ("", visitor.GetResult() [PIXEL_DATA]["InlineBinary"].asString());
+    ASSERT_EQ("OW", visitor.GetResult() [PIXEL_DATA]["vr"].asString());
+  }
+}
+
+
+TEST(ParsedDicomFile, DISABLED_InjectEmptyPixelData2)
+{
+  static const char* PIXEL_DATA = "7FE00010";
+
+  for (int i = 0; i <= DicomTransferSyntax_XML; i++)
+  {
+    DicomTransferSyntax a = (DicomTransferSyntax) i;
+
+    std::string path = (std::string(getenv("HOME")) +
+                        "/Subversion/orthanc-tests/Database/TransferSyntaxes/" +
+                        std::string(GetTransferSyntaxUid(a)) + ".dcm");
+    if (Orthanc::SystemToolbox::IsRegularFile(path))
+    {
+      printf("\n======= %s\n", GetTransferSyntaxUid(a));
+
+      std::string source;
+      Orthanc::SystemToolbox::ReadFile(source, path);
+
+      ParsedDicomFile dicom(source);
+      std::unique_ptr<DcmElement> removal(dicom.GetDcmtkObject().getDataset()->remove(DCM_PixelData));
+
+      {
+        DicomWebJsonVisitor visitor;
+        dicom.Apply(visitor);
+        ASSERT_FALSE(visitor.GetResult().isMember(PIXEL_DATA));
+      }
+
+      {
+        DicomWebJsonVisitor visitor;
+        dicom.InjectEmptyPixelData(ValueRepresentation_OtherByte);
+        dicom.Apply(visitor);
+        ASSERT_TRUE(visitor.GetResult().isMember(PIXEL_DATA));
+        ASSERT_EQ("OB", visitor.GetResult() [PIXEL_DATA]["vr"].asString());
+      }
+
+      removal.reset(dicom.GetDcmtkObject().getDataset()->remove(DCM_PixelData));
+
+      {
+        DicomWebJsonVisitor visitor;
+        dicom.InjectEmptyPixelData(ValueRepresentation_OtherWord);
+        dicom.Apply(visitor);
+        ASSERT_TRUE(visitor.GetResult().isMember(PIXEL_DATA));
+        ASSERT_EQ("OW", visitor.GetResult() [PIXEL_DATA]["vr"].asString());
+      }
+    }
+  }
+}
+
+
 
 
 #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1
@@ -3240,11 +3332,13 @@
   DcmtkTranscoder transcoder;
 
   for (int j = 0; j < 2; j++)
+  {
     for (int i = 0; i <= DicomTransferSyntax_XML; i++)
     {
       DicomTransferSyntax a = (DicomTransferSyntax) i;
 
-      std::string path = ("/home/jodogne/Subversion/orthanc-tests/Database/TransferSyntaxes/" +
+      std::string path = (std::string(getenv("HOME")) +
+                          "/Subversion/orthanc-tests/Database/TransferSyntaxes/" +
                           std::string(GetTransferSyntaxUid(a)) + ".dcm");
       if (Orthanc::SystemToolbox::IsRegularFile(path))
       {
@@ -3272,6 +3366,7 @@
         }
       }
     }
+  }
 }
 
 
@@ -3281,7 +3376,8 @@
 
   {
     std::string source;
-    Orthanc::SystemToolbox::ReadFile(source, "/home/jodogne/Subversion/orthanc-tests/Database/KarstenHilbertRF.dcm");
+    Orthanc::SystemToolbox::ReadFile(source, std::string(getenv("HOME")) +
+                                     "/Subversion/orthanc-tests/Database/KarstenHilbertRF.dcm");
     toto.reset(FromDcmtkBridge::LoadFromMemoryBuffer(source.c_str(), source.size()));
   }