changeset 215:02cb86d07966

Allow images without "Per frame functional groups sequence" tag (0x5200,0x9230)
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 11 Jan 2021 17:12:24 +0100
parents 1e864138f0da
children c35a3a0627b9
files Framework/Inputs/DicomPyramidInstance.cpp NEWS
diffstat 2 files changed, 75 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Inputs/DicomPyramidInstance.cpp	Wed Jan 06 18:10:07 2021 +0100
+++ b/Framework/Inputs/DicomPyramidInstance.cpp	Mon Jan 11 17:12:24 2021 +0100
@@ -173,57 +173,85 @@
     }
 
     size_t countFrames;
-    if (!reader.GetDataset().GetSequenceSize(countFrames, OrthancStone::DicomPath(DICOM_TAG_PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE)))
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
-    }
-
-    if (countFrames != tmp)
-    {
-      LOG(ERROR) << "Mismatch between the number of frames in instance: " << instanceId;
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
-    }
-
-    frames_.resize(countFrames);
-
-    for (size_t i = 0; i < countFrames; i++)
+    if (reader.GetDataset().GetSequenceSize(countFrames, OrthancStone::DicomPath(DICOM_TAG_PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE)))
     {
-      DicomPath pathX(DICOM_TAG_PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE, i,
-                      DICOM_TAG_PLANE_POSITION_SLIDE_SEQUENCE, 0,
-                      DICOM_TAG_COLUMN_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX);
-
-      DicomPath pathY(DICOM_TAG_PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE, i,
-                      DICOM_TAG_PLANE_POSITION_SLIDE_SEQUENCE, 0,
-                      DICOM_TAG_ROW_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX);
-
-      int xx, yy;
-      if (!reader.GetIntegerValue(xx, pathX) ||
-          !reader.GetIntegerValue(yy, pathY))
+      if (countFrames != tmp)
       {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentTag);
-      }
-
-      // "-1", because coordinates are shifted by 1 in DICOM
-      xx -= 1;
-      yy -= 1;
-
-      unsigned int x = static_cast<unsigned int>(xx);
-      unsigned int y = static_cast<unsigned int>(yy);
-
-      if (xx < 0 || 
-          yy < 0 ||
-          x % tileWidth_ != 0 ||
-          y % tileHeight_ != 0 ||
-          x >= totalWidth_ ||
-          y >= totalHeight_)
-      {
-        LOG(ERROR) << "Frame " << i << " with unexpected tile location (" 
-                   << x << "," << y << ") in instance: " << instanceId;
+        LOG(ERROR) << "Mismatch between the number of frames in instance: " << instanceId;
         throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
       }
 
-      frames_[i].first = x / tileWidth_;
-      frames_[i].second = y / tileHeight_;
+      frames_.resize(countFrames);
+
+      for (size_t i = 0; i < countFrames; i++)
+      {
+        DicomPath pathX(DICOM_TAG_PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE, i,
+                        DICOM_TAG_PLANE_POSITION_SLIDE_SEQUENCE, 0,
+                        DICOM_TAG_COLUMN_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX);
+
+        DicomPath pathY(DICOM_TAG_PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE, i,
+                        DICOM_TAG_PLANE_POSITION_SLIDE_SEQUENCE, 0,
+                        DICOM_TAG_ROW_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX);
+
+        int xx, yy;
+        if (!reader.GetIntegerValue(xx, pathX) ||
+            !reader.GetIntegerValue(yy, pathY))
+        {
+          throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentTag);
+        }
+
+        // "-1", because coordinates are shifted by 1 in DICOM
+        xx -= 1;
+        yy -= 1;
+
+        unsigned int x = static_cast<unsigned int>(xx);
+        unsigned int y = static_cast<unsigned int>(yy);
+
+        if (xx < 0 || 
+            yy < 0 ||
+            x % tileWidth_ != 0 ||
+            y % tileHeight_ != 0 ||
+            x >= totalWidth_ ||
+            y >= totalHeight_)
+        {
+          LOG(ERROR) << "Frame " << i << " with unexpected tile location (" 
+                     << x << "," << y << ") in instance: " << instanceId;
+          throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
+        }
+
+        frames_[i].first = x / tileWidth_;
+        frames_[i].second = y / tileHeight_;
+      }
+    }
+    else
+    {
+      // No "Per frame functional groups sequence" tag. Assume regular grid.
+      frames_.resize(tmp);
+      
+      // Compute "ceiling(totalWidth_ / tileWidth_)
+      unsigned int w = totalWidth_ / tileWidth_;
+      if (totalWidth_ % tileWidth_ != 0)
+      {
+        w += 1;
+      }
+
+      unsigned int h = totalHeight_ / tileHeight_;
+      if (totalHeight_ % tileHeight_ != 0)
+      {
+        h += 1;
+      }
+
+      if (w * h != tmp)
+      {
+        LOG(ERROR) << "Mismatch between the number of frames in instance: " << instanceId;
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
+      }
+
+      for (size_t i = 0; i < frames_.size(); i++)
+      {
+        frames_[i].first = i % w;
+        frames_[i].second = i / w;
+      }
     }
   }
 
--- a/NEWS	Wed Jan 06 18:10:07 2021 +0100
+++ b/NEWS	Mon Jan 11 17:12:24 2021 +0100
@@ -1,6 +1,7 @@
 Pending changes in the mainline
 ===============================
 
+* Allow images without "Per frame functional groups sequence" tag (0x5200,0x9230)
 * Support of dynamic linking against the system-wide Orthanc framework library