From 1014e90b4744f2d997ee607a0e707742cb38cbc9 Mon Sep 17 00:00:00 2001
From: Fredrik Orderud <fredrik.orderud@ge.com>
Date: Wed, 19 Feb 2020 15:49:52 +0100
Subject: [PATCH] Update client code after API upgrade

Only an API update so far. Actual color-flow support will be added in a later PR.
---
 RegFreeTest/Main.cpp          |  27 +++++++--
 SandboxTest/Main.cpp          |  28 +++++++--
 TestPython/TestPython.py      |  15 +++--
 TestViewer/MainWindow.xaml.cs | 106 +++++++++++++++++++---------------
 4 files changed, 114 insertions(+), 62 deletions(-)

diff --git a/RegFreeTest/Main.cpp b/RegFreeTest/Main.cpp
index 74f9cb2..f3d4233 100644
--- a/RegFreeTest/Main.cpp
+++ b/RegFreeTest/Main.cpp
@@ -7,8 +7,13 @@
 void ParseSource (IImage3dSource & source) {
     CComSafeArray<unsigned int> color_map;
     {
+        ImageFormat img_format = IMAGE_FORMAT_INVALID;
         SAFEARRAY * tmp = nullptr;
-        CHECK(source.GetColorMap(&tmp));
+        CHECK(source.GetColorMap(TYPE_TISSUE_COLOR, &img_format, &tmp));
+        if (img_format != IMAGE_FORMAT_R8G8B8A8) {
+            std::wcerr << "ERROR: Unexpected color-map format.\n";
+            std::exit(-1);
+        }
         color_map.Attach(tmp);
         tmp = nullptr;
     }
@@ -16,16 +21,28 @@ void ParseSource (IImage3dSource & source) {
     Cart3dGeom bbox = {};
     CHECK(source.GetBoundingBox(&bbox));
 
+    unsigned int stream_count = 0;
+    CHECK(source.GetStreamCount(&stream_count));
+    if (stream_count == 0) {
+        std::wcerr << "ERROR: No image streams found.\n";
+        std::exit(-1);
+    }
+
+    unsigned short max_res[] = {64, 64, 64};
+    CComPtr<IImage3dStream> stream;
+    CHECK(source.GetStream(0, bbox, max_res, &stream));
+
+    ImageType stream_type = IMAGE_TYPE_INVALID;
+    CHECK(stream->GetType(&stream_type));
+
     unsigned int frame_count = 0;
-    CHECK(source.GetFrameCount(&frame_count));
+    CHECK(stream->GetFrameCount(&frame_count));
     std::wcout << L"Frame count: " << frame_count << L"\n";
 
     for (unsigned int frame = 0; frame < frame_count; ++frame) {
-        unsigned short max_res[] = {64, 64, 64};
-
         // retrieve frame data
         Image3d data;
-        CHECK(source.GetFrame(frame, bbox, max_res, &data));
+        CHECK(stream->GetFrame(frame, &data));
     }
 }
 
diff --git a/SandboxTest/Main.cpp b/SandboxTest/Main.cpp
index b5e5a40..4c1a5d8 100644
--- a/SandboxTest/Main.cpp
+++ b/SandboxTest/Main.cpp
@@ -34,8 +34,13 @@ class PerfTimer {
 void ParseSource (IImage3dSource & source, bool verbose, bool profile) {
     CComSafeArray<unsigned int> color_map;
     {
+        ImageFormat img_format = IMAGE_FORMAT_INVALID;
         SAFEARRAY * tmp = nullptr;
-        CHECK(source.GetColorMap(&tmp));
+        CHECK(source.GetColorMap(TYPE_TISSUE_COLOR, &img_format, &tmp));
+        if (img_format != IMAGE_FORMAT_R8G8B8A8) {
+            std::wcerr << "ERROR: Unexpected color-map format.\n";
+            std::exit(-1);
+        }
         color_map.Attach(tmp);
         tmp = nullptr;
     }
@@ -60,14 +65,28 @@ void ParseSource (IImage3dSource & source, bool verbose, bool profile) {
         std::cout << "  Dir3:   " << bbox.dir3_x   << ", " << bbox.dir3_y   << ", " << bbox.dir3_z   << "\n";
     }
 
+    unsigned int stream_count = 0;
+    CHECK(source.GetStreamCount(&stream_count));
+    if (stream_count == 0) {
+        std::wcerr << "ERROR: No image streams found.\n";
+        std::exit(-1);
+    }
+
+    unsigned short max_res[] = {64, 64, 64};
+    CComPtr<IImage3dStream> stream;
+    CHECK(source.GetStream(0, bbox, max_res, &stream));
+
+    ImageType stream_type = IMAGE_TYPE_INVALID;
+    CHECK(stream->GetType(&stream_type));
+
     unsigned int frame_count = 0;
-    CHECK(source.GetFrameCount(&frame_count));
+    CHECK(stream->GetFrameCount(&frame_count));
     std::wcout << L"Frame count: " << frame_count << L"\n";
 
     CComSafeArray<double> frame_times;
     {
         SAFEARRAY * data = nullptr;
-        CHECK(source.GetFrameTimes(&data));
+        CHECK(stream->GetFrameTimes(&data));
         frame_times.Attach(data);
         data = nullptr;
     }
@@ -82,7 +101,6 @@ void ParseSource (IImage3dSource & source, bool verbose, bool profile) {
     }
 
     for (unsigned int frame = 0; frame < frame_count; ++frame) {
-        unsigned short max_res[] = { 64, 64, 64 };
         if (profile) {
             max_res[0] = 128;
             max_res[1] = 128;
@@ -92,7 +110,7 @@ void ParseSource (IImage3dSource & source, bool verbose, bool profile) {
         // retrieve frame data
         Image3d data;
         PerfTimer timer("GetFrame", profile);
-        CHECK(source.GetFrame(frame, bbox, max_res, &data));
+        CHECK(stream->GetFrame(frame, &data));
 
         if (frame == 0)
             std::cout << "First frame time: " << data.time << "\n";
diff --git a/TestPython/TestPython.py b/TestPython/TestPython.py
index 514f03a..aa79279 100644
--- a/TestPython/TestPython.py
+++ b/TestPython/TestPython.py
@@ -68,13 +68,18 @@ def FrameTo3dArray (frame):
     dir2   = [bbox.dir2_x,   bbox.dir2_y,   bbox.dir2_z]
     dir3   = [bbox.dir3_x,   bbox.dir3_y,   bbox.dir3_z]
 
-    color_map = source.GetColorMap()
-    print("Color-map length: "+str(len(color_map)))
+    color_format, color_map = source.GetColorMap(Image3dAPI.TYPE_TISSUE_COLOR)
+    print("Color-map lenght: "+str(len(color_map)))
 
-    frame_count = source.GetFrameCount()
+    max_res = np.ctypeslib.as_ctypes(np.array([64, 64, 64], dtype=np.ushort))
+    stream = source.GetStream(0, bbox, max_res)
+
+    stream_type = stream.GetType()
+    print("Stream type "+str(stream_type))
+
+    frame_count = stream.GetFrameCount()
     for i in range(frame_count):
-        max_res = np.ctypeslib.as_ctypes(np.array([64, 64, 64], dtype=np.ushort))
-        frame = source.GetFrame(i, bbox, max_res)
+        frame = stream.GetFrame(i)
         
         print("Frame metadata:")
         print("  time:   "+str(frame.time))
diff --git a/TestViewer/MainWindow.xaml.cs b/TestViewer/MainWindow.xaml.cs
index 48bd6a9..5a68f5b 100644
--- a/TestViewer/MainWindow.xaml.cs
+++ b/TestViewer/MainWindow.xaml.cs
@@ -43,9 +43,9 @@ public partial class MainWindow : Window
         IImage3dFileLoader m_loader;
         IImage3dSource     m_source;
 
-        Cart3dGeom         m_bboxXY;
-        Cart3dGeom         m_bboxXZ;
-        Cart3dGeom         m_bboxZY;
+        IImage3dStream     m_streamXY;
+        IImage3dStream     m_streamXZ;
+        IImage3dStream     m_streamZY;
 
         public MainWindow()
         {
@@ -68,9 +68,9 @@ void ClearUI()
             ImageXZ.Source = null;
             ImageZY.Source = null;
 
-            m_bboxXY = new Cart3dGeom();
-            m_bboxXZ = new Cart3dGeom();
-            m_bboxZY = new Cart3dGeom();
+            m_streamXY = null;
+            m_streamXZ = null;
+            m_streamZY = null;
 
             ECG.Data = null;
 
@@ -183,18 +183,19 @@ private void FileOpenBtn_Click(object sender, RoutedEventArgs e)
                 return;
             }
 
+            InitializeSlices();
+
             FrameSelector.Minimum = 0;
-            FrameSelector.Maximum = m_source.GetFrameCount()-1;
+            FrameSelector.Maximum = m_streamXY.GetFrameCount()-1;
             FrameSelector.IsEnabled = true;
             FrameSelector.Value = 0;
 
-            FrameCount.Text = "Frame count: " + m_source.GetFrameCount();
+            FrameCount.Text = "Frame count: " + m_streamXY.GetFrameCount();
             ProbeInfo.Text = "Probe name: "+ m_source.GetProbeInfo().name;
             InstanceUID.Text = "UID: " + m_source.GetSopInstanceUID();
 
-            InitializeSlices();
             DrawSlices(0);
-            DrawEcg(m_source.GetFrameTimes()[0]);
+            DrawEcg(m_streamXY.GetFrameTimes()[0]);
         }
 
         private void DrawEcg (double cur_time)
@@ -267,13 +268,17 @@ private void FrameSelector_ValueChanged(object sender, RoutedPropertyChangedEven
         {
             var idx = (uint)FrameSelector.Value;
             DrawSlices(idx);
-            DrawEcg(m_source.GetFrameTimes()[idx]);
+            DrawEcg(m_streamXY.GetFrameTimes()[idx]);
         }
 
         private void InitializeSlices()
         {
             Debug.Assert(m_source != null);
 
+            uint stream_count = m_source.GetStreamCount();
+            if (stream_count < 1)
+                throw new Exception("No image streams found");
+
             Cart3dGeom bbox = m_source.GetBoundingBox();
             if (Math.Abs(bbox.dir3_y) > Math.Abs(bbox.dir2_y)) {
                 // swap 2nd & 3rd axis, so that the 2nd becomes predominately "Y"
@@ -285,41 +290,47 @@ private void InitializeSlices()
             // extend bounding-box axes, so that dir1, dir2 & dir3 have equal length
             ExtendBoundingBox(ref bbox);
 
+            const ushort HORIZONTAL_RES = 256;
+            const ushort VERTICAL_RES = 256;
+
             // get XY plane (assumes 1st axis is "X" and 2nd is "Y")
-            m_bboxXY = bbox;
-            m_bboxXY.origin_x = m_bboxXY.origin_x + m_bboxXY.dir3_x / 2;
-            m_bboxXY.origin_y = m_bboxXY.origin_y + m_bboxXY.dir3_y / 2;
-            m_bboxXY.origin_z = m_bboxXY.origin_z + m_bboxXY.dir3_z / 2;
-            m_bboxXY.dir3_x = 0;
-            m_bboxXY.dir3_y = 0;
-            m_bboxXY.dir3_z = 0;
+            Cart3dGeom bboxXY = bbox;
+            bboxXY.origin_x = bboxXY.origin_x + bboxXY.dir3_x / 2;
+            bboxXY.origin_y = bboxXY.origin_y + bboxXY.dir3_y / 2;
+            bboxXY.origin_z = bboxXY.origin_z + bboxXY.dir3_z / 2;
+            bboxXY.dir3_x = 0;
+            bboxXY.dir3_y = 0;
+            bboxXY.dir3_z = 0;
+            m_streamXY = m_source.GetStream(0, bboxXY, new ushort[] { HORIZONTAL_RES, VERTICAL_RES, 1 });
 
             // get XZ plane (assumes 1st axis is "X" and 3rd is "Z")
-            m_bboxXZ = bbox;
-            m_bboxXZ.origin_x = m_bboxXZ.origin_x + m_bboxXZ.dir2_x / 2;
-            m_bboxXZ.origin_y = m_bboxXZ.origin_y + m_bboxXZ.dir2_y / 2;
-            m_bboxXZ.origin_z = m_bboxXZ.origin_z + m_bboxXZ.dir2_z / 2;
-            m_bboxXZ.dir2_x = m_bboxXZ.dir3_x;
-            m_bboxXZ.dir2_y = m_bboxXZ.dir3_y;
-            m_bboxXZ.dir2_z = m_bboxXZ.dir3_z;
-            m_bboxXZ.dir3_x = 0;
-            m_bboxXZ.dir3_y = 0;
-            m_bboxXZ.dir3_z = 0;
+            Cart3dGeom bboxXZ = bbox;
+            bboxXZ.origin_x = bboxXZ.origin_x + bboxXZ.dir2_x / 2;
+            bboxXZ.origin_y = bboxXZ.origin_y + bboxXZ.dir2_y / 2;
+            bboxXZ.origin_z = bboxXZ.origin_z + bboxXZ.dir2_z / 2;
+            bboxXZ.dir2_x = bboxXZ.dir3_x;
+            bboxXZ.dir2_y = bboxXZ.dir3_y;
+            bboxXZ.dir2_z = bboxXZ.dir3_z;
+            bboxXZ.dir3_x = 0;
+            bboxXZ.dir3_y = 0;
+            bboxXZ.dir3_z = 0;
+            m_streamXZ = m_source.GetStream(0, bboxXZ, new ushort[] { HORIZONTAL_RES, VERTICAL_RES, 1 });
 
             // get ZY plane (assumes 2nd axis is "Y" and 3rd is "Z")
-            m_bboxZY = bbox;
-            m_bboxZY.origin_x = bbox.origin_x + bbox.dir1_x / 2;
-            m_bboxZY.origin_y = bbox.origin_y + bbox.dir1_y / 2;
-            m_bboxZY.origin_z = bbox.origin_z + bbox.dir1_z / 2;
-            m_bboxZY.dir1_x = bbox.dir3_x;
-            m_bboxZY.dir1_y = bbox.dir3_y;
-            m_bboxZY.dir1_z = bbox.dir3_z;
-            m_bboxZY.dir2_x = bbox.dir2_x;
-            m_bboxZY.dir2_y = bbox.dir2_y;
-            m_bboxZY.dir2_z = bbox.dir2_z;
-            m_bboxZY.dir3_x = 0;
-            m_bboxZY.dir3_y = 0;
-            m_bboxZY.dir3_z = 0;
+            Cart3dGeom bboxZY = bbox;
+            bboxZY.origin_x = bbox.origin_x + bbox.dir1_x / 2;
+            bboxZY.origin_y = bbox.origin_y + bbox.dir1_y / 2;
+            bboxZY.origin_z = bbox.origin_z + bbox.dir1_z / 2;
+            bboxZY.dir1_x = bbox.dir3_x;
+            bboxZY.dir1_y = bbox.dir3_y;
+            bboxZY.dir1_z = bbox.dir3_z;
+            bboxZY.dir2_x = bbox.dir2_x;
+            bboxZY.dir2_y = bbox.dir2_y;
+            bboxZY.dir2_z = bbox.dir2_z;
+            bboxZY.dir3_x = 0;
+            bboxZY.dir3_y = 0;
+            bboxZY.dir3_z = 0;
+            m_streamZY = m_source.GetStream(0, bboxZY, new ushort[] { HORIZONTAL_RES, VERTICAL_RES, 1 });
         }
 
         private void DrawSlices (uint frame)
@@ -327,21 +338,22 @@ private void DrawSlices (uint frame)
             Debug.Assert(m_source != null);
 
             // retrieve image slices
-            const ushort HORIZONTAL_RES = 256;
-            const ushort VERTICAL_RES = 256;
 
             // get XY plane (assumes 1st axis is "X" and 2nd is "Y")
-            Image3d imageXY = m_source.GetFrame(frame, m_bboxXY, new ushort[] { HORIZONTAL_RES, VERTICAL_RES, 1 });
+            Image3d imageXY = m_streamXY.GetFrame(frame);
 
             // get XZ plane (assumes 1st axis is "X" and 3rd is "Z")
-            Image3d imageXZ = m_source.GetFrame(frame, m_bboxXZ, new ushort[] { HORIZONTAL_RES, VERTICAL_RES, 1 });
+            Image3d imageXZ = m_streamXZ.GetFrame(frame);
 
             // get ZY plane (assumes 2nd axis is "Y" and 3rd is "Z")
-            Image3d imageZY = m_source.GetFrame(frame, m_bboxZY, new ushort[] { HORIZONTAL_RES, VERTICAL_RES, 1 });
+            Image3d imageZY = m_streamZY.GetFrame(frame);
 
             FrameTime.Text = "Frame time: " + imageXY.time;
 
-            uint[] color_map = m_source.GetColorMap();
+            ImageFormat image_format;
+            uint[] color_map = m_source.GetColorMap(ColorMapType.TYPE_TISSUE_COLOR, out image_format);
+            if (image_format != ImageFormat.IMAGE_FORMAT_R8G8B8A8)
+                throw new Exception("Unexpected color-map format");
 
             ImageXY.Source = GenerateBitmap(imageXY, color_map);
             ImageXZ.Source = GenerateBitmap(imageXZ, color_map);