Skip to content

Commit

Permalink
Update DummyLoader after API upgrade
Browse files Browse the repository at this point in the history
Only an API update so far. Actual color-flow support will be added in a later PR.
  • Loading branch information
Fredrik Orderud committed Mar 23, 2020
1 parent 4f26d0b commit f0fc938
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 74 deletions.
10 changes: 10 additions & 0 deletions DummyLoader/DummyLoader.idl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ library DummyLoader
{
importlib("stdole2.tlb");

[
version(1.2),
uuid(78317A0E-56BF-4735-AB5B-FE0751219FE8),
helpstring("3D image stream")
]
coclass Image3dStream
{
[default] interface IImage3dStream;
};

[
version(1.2),
uuid(6FA82ED5-6332-4344-8417-DEA55E72098C),
Expand Down
Binary file modified DummyLoader/DummyLoader.rc
Binary file not shown.
89 changes: 24 additions & 65 deletions DummyLoader/Image3dSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
#include "LinAlg.hpp"


static const uint8_t OUTSIDE_VAL = 0; // black outside image volume
static const uint8_t PROBE_PLANE = 127; // gray value for plane closest to probe


Image3dSource::Image3dSource() {
Expand Down Expand Up @@ -45,104 +43,65 @@ Image3dSource::Image3dSource() {
0.20f,0, 0, // dir1 (width)
0, 0.10f, 0, // dir2 (depth)
0, 0, 0.15f};// dir3 (elevation)
m_img_geom = geom;
}
{
// checker board image data
unsigned short dims[] = { 20, 15, 10 }; // matches length of dir1, dir2 & dir3, so that the image squares become quadratic
std::vector<byte> img_buf(dims[0] * dims[1] * dims[2]);
for (size_t frameNumber = 0; frameNumber < numFrames; ++frameNumber) {
for (unsigned int z = 0; z < dims[2]; ++z) {
for (unsigned int y = 0; y < dims[1]; ++y) {
for (unsigned int x = 0; x < dims[0]; ++x) {
bool even_f = (frameNumber / 2 % 2) == 0;
bool even_x = (x / 2 % 2) == 0;
bool even_y = (y / 2 % 2) == 0;
bool even_z = (z / 2 % 2) == 0;
byte & out_sample = img_buf[x + y*dims[0] + z*dims[0] * dims[1]];
if (even_f ^ even_x ^ even_y ^ even_z)
out_sample = 255;
else
out_sample = 0;
}
}
}

// special grayscale value for plane closest to probe
for (unsigned int z = 0; z < dims[2]; ++z) {
for (unsigned int x = 0; x < dims[0]; ++x) {
unsigned int y = 0;
byte & out_sample = img_buf[x + y*dims[0] + z*dims[0] * dims[1]];
out_sample = PROBE_PLANE;
}
}

m_frames.push_back(CreateImage3d(frameNumber*(duration/numFrames) + startTime, IMAGE_FORMAT_U8, dims, img_buf));
}
m_bbox = geom;
}

// a single tissue stream
m_stream_types.push_back(IMAGE_TYPE_TISSUE);
}

Image3dSource::~Image3dSource() {
}


HRESULT Image3dSource::GetFrameCount(/*out*/unsigned int *size) {
HRESULT Image3dSource::GetStreamCount(/*out*/unsigned int *size) {
if (!size)
return E_INVALIDARG;

*size = static_cast<unsigned int>(m_frames.size());
*size = static_cast<unsigned int>(m_stream_types.size());
return S_OK;
}

HRESULT Image3dSource::GetFrameTimes(/*out*/SAFEARRAY * *frame_times) {
if (!frame_times)
return E_INVALIDARG;

const unsigned int N = static_cast<unsigned int>(m_frames.size());
CComSafeArray<double> result(N);
if (N > 0) {
double * time_arr = &result.GetAt(0);
for (unsigned int i = 0; i < N; ++i)
time_arr[i] = m_frames[i].time;
}

*frame_times = result.Detach();
return S_OK;
}


HRESULT Image3dSource::GetFrame(unsigned int index, Cart3dGeom out_geom, unsigned short max_res[3], /*out*/Image3d *data) {
if (!data)
HRESULT Image3dSource::GetStream(int index, Cart3dGeom out_geom, unsigned short max_resolution[3], /*out*/IImage3dStream ** stream) {
if (!stream)
return E_INVALIDARG;
if (index >= m_frames.size())
if (index >= m_stream_types.size())
return E_BOUNDS;

ImageFormat format = m_frames[index].format;
if (format == FORMAT_U8) {
Image3d result = SampleFrame<uint8_t>(m_frames[index], m_img_geom, out_geom, max_res);
*data = std::move(result);
return S_OK;
CComPtr<IImage3dStream> stream_obj;
{
// on-demand stream creation
auto stream_cls = CreateLocalInstance<Image3dStream>();
stream_cls->Initialize(m_stream_types[index], m_bbox, out_geom, max_resolution);
stream_obj = stream_cls; // cast class pointer to interface
}

return E_NOTIMPL;
*stream = stream_obj.Detach();
return S_OK;
}

HRESULT Image3dSource::GetBoundingBox(/*out*/Cart3dGeom *geom) {
if (!geom)
return E_INVALIDARG;

*geom = m_img_geom;
*geom = m_bbox;
return S_OK;
}

HRESULT Image3dSource::GetColorMap(/*out*/SAFEARRAY ** map) {
HRESULT Image3dSource::GetColorMap(ColorMapType type, /*out*/ImageFormat * format, /*out*/SAFEARRAY ** map) {
if (!map)
return E_INVALIDARG;
if (*map)
return E_INVALIDARG;

if (type != TYPE_TISSUE_COLOR)
return E_NOT_SET;

*format = IMAGE_FORMAT_R8G8B8A8;
// copy to new buffer
CComSafeArray<uint32_t> color_map(static_cast<unsigned int>(m_color_map.size()));
CComSafeArray<uint8_t> color_map(4*static_cast<unsigned int>(m_color_map.size()));
memcpy(&color_map.GetAt(0), m_color_map.data(), sizeof(m_color_map));
*map = color_map.Detach(); // transfer ownership
return S_OK;
Expand Down
12 changes: 6 additions & 6 deletions DummyLoader/Image3dSource.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@ class ATL_NO_VTABLE Image3dSource :

/*NOT virtual*/ ~Image3dSource();

HRESULT STDMETHODCALLTYPE GetFrameCount(/*out*/unsigned int *size) override;

HRESULT STDMETHODCALLTYPE GetFrameTimes(/*out*/SAFEARRAY * *frame_times) override;
HRESULT STDMETHODCALLTYPE GetStreamCount (/*out*/unsigned int * size) override;

HRESULT STDMETHODCALLTYPE GetFrame(unsigned int index, Cart3dGeom out_geom, unsigned short max_res[3], /*out*/Image3d *data) override;
HRESULT STDMETHODCALLTYPE GetStream (int index, Cart3dGeom out_geom, unsigned short max_resolution[3], /*out*/IImage3dStream ** stream) override;

HRESULT STDMETHODCALLTYPE GetBoundingBox(/*out*/Cart3dGeom *geom) override;

HRESULT STDMETHODCALLTYPE GetColorMap(/*out*/SAFEARRAY ** map) override;
HRESULT STDMETHODCALLTYPE GetColorMap(ColorMapType type, /*out*/ImageFormat * format, /*out*/SAFEARRAY ** map) override;

HRESULT STDMETHODCALLTYPE GetECG(/*out*/EcgSeries *ecg) override;

Expand All @@ -42,8 +41,9 @@ class ATL_NO_VTABLE Image3dSource :
ProbeInfo m_probe;
EcgSeries m_ecg;
std::array<R8G8B8A8,256> m_color_map;
Cart3dGeom m_img_geom = {};
std::vector<Image3d> m_frames;

Cart3dGeom m_bbox = {};
std::vector<ImageType> m_stream_types;
};

OBJECT_ENTRY_AUTO(__uuidof(Image3dSource), Image3dSource)
107 changes: 107 additions & 0 deletions DummyLoader/Image3dStream.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,108 @@
#include "Image3dStream.hpp"

#include "LinAlg.hpp"


static const uint8_t OUTSIDE_VAL = 0; // black outside image volume
static const uint8_t PROBE_PLANE = 127; // gray value for plane closest to probe


Image3dStream::Image3dStream() {
}

void Image3dStream::Initialize (ImageType type, Cart3dGeom img_geom, Cart3dGeom out_geom, unsigned short max_resolution[3]) {
m_type = type;
m_img_geom = img_geom;
m_out_geom = out_geom;

for (size_t i = 0; i < 3; ++i)
m_max_res[i] = max_resolution[i];

// One second loop starting at t = 10
const size_t numFrames = 25;
const double duration = 1.0; // Seconds
const double startTime = 10.0;

{
// checker board image data
unsigned short dims[] = { 20, 15, 10 }; // matches length of dir1, dir2 & dir3, so that the image squares become quadratic
std::vector<byte> img_buf(dims[0] * dims[1] * dims[2]);
for (size_t frameNumber = 0; frameNumber < numFrames; ++frameNumber) {
for (unsigned int z = 0; z < dims[2]; ++z) {
for (unsigned int y = 0; y < dims[1]; ++y) {
for (unsigned int x = 0; x < dims[0]; ++x) {
bool even_f = (frameNumber / 2 % 2) == 0;
bool even_x = (x / 2 % 2) == 0;
bool even_y = (y / 2 % 2) == 0;
bool even_z = (z / 2 % 2) == 0;
byte & out_sample = img_buf[x + y*dims[0] + z*dims[0] * dims[1]];
if (even_f ^ even_x ^ even_y ^ even_z)
out_sample = 255;
else
out_sample = 0;
}
}
}

// special grayscale value for plane closest to probe
for (unsigned int z = 0; z < dims[2]; ++z) {
for (unsigned int x = 0; x < dims[0]; ++x) {
unsigned int y = 0;
byte & out_sample = img_buf[x + y*dims[0] + z*dims[0] * dims[1]];
out_sample = PROBE_PLANE;
}
}

m_frames.push_back(CreateImage3d(frameNumber*(duration/numFrames) + startTime, IMAGE_FORMAT_U8, dims, img_buf));
}
}
}

Image3dStream::~Image3dStream() {
}


HRESULT Image3dStream::GetFrameCount(/*out*/unsigned int *size) {
if (!size)
return E_INVALIDARG;

*size = static_cast<unsigned int>(m_frames.size());
return S_OK;
}

HRESULT Image3dStream::GetFrameTimes(/*out*/SAFEARRAY * *frame_times) {
if (!frame_times)
return E_INVALIDARG;

const unsigned int N = static_cast<unsigned int>(m_frames.size());
CComSafeArray<double> result(N);
if (N > 0) {
double * time_arr = &result.GetAt(0);
for (unsigned int i = 0; i < N; ++i)
time_arr[i] = m_frames[i].time;
}

*frame_times = result.Detach();
return S_OK;
}


HRESULT Image3dStream::GetFrame(unsigned int index, /*out*/Image3d *data) {
if (!data)
return E_INVALIDARG;
if (index >= m_frames.size())
return E_BOUNDS;

ImageFormat format = m_frames[index].format;
if (format == IMAGE_FORMAT_U8) {
Image3d result = SampleFrame<uint8_t>(m_frames[index], m_img_geom, m_out_geom, m_max_res);
*data = std::move(result);
return S_OK;
} else if (format == IMAGE_FORMAT_FREQ8POW8) {
Image3d result = SampleFrame<uint16_t>(m_frames[index], m_img_geom, m_out_geom, m_max_res);
*data = std::move(result);
return S_OK;
}

return E_NOTIMPL;
}
47 changes: 46 additions & 1 deletion DummyLoader/Image3dStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ struct R8G8B8A8 {
/** Determine the sample size [bytes] for a given image format. */
static unsigned int ImageFormatSize(ImageFormat format) {
switch (format) {
case IMAGE_FORMAT_U8: return 1;
case IMAGE_FORMAT_U8: return 1;
case IMAGE_FORMAT_FREQ8POW8: return 2;
case IMAGE_FORMAT_R8G8B8A8: return 4;
}

abort(); // should never be reached
Expand All @@ -64,3 +66,46 @@ static Image3d CreateImage3d (double time, ImageFormat format, const unsigned sh

return img;
}


class ATL_NO_VTABLE Image3dStream :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<Image3dStream, &__uuidof(Image3dStream)>,
public IImage3dStream {
public:
Image3dStream();

/*NOT virtual*/ ~Image3dStream();

void Initialize (ImageType type, Cart3dGeom img_geom, Cart3dGeom out_geom, unsigned short max_resolution[3]);

HRESULT STDMETHODCALLTYPE GetType (/*out*/ImageType * type) override {
if (!type)
return E_INVALIDARG;

*type = m_type;
return S_OK;
}

HRESULT STDMETHODCALLTYPE GetFrameCount(/*out*/unsigned int *size) override;

HRESULT STDMETHODCALLTYPE GetFrameTimes(/*out*/SAFEARRAY * *frame_times) override;

HRESULT STDMETHODCALLTYPE GetFrame(unsigned int index, /*out*/Image3d *data) override;

DECLARE_REGISTRY_RESOURCEID(IDR_Image3dStream)

BEGIN_COM_MAP(Image3dStream)
COM_INTERFACE_ENTRY(IImage3dStream)
END_COM_MAP()

private:
ImageType m_type = IMAGE_TYPE_INVALID;
Cart3dGeom m_img_geom = {};
std::vector<Image3d> m_frames;

Cart3dGeom m_out_geom = {};
unsigned short m_max_res[3];
};

OBJECT_ENTRY_AUTO(__uuidof(Image3dStream), Image3dStream)
5 changes: 3 additions & 2 deletions DummyLoader/Resource.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define IDS_PROJNAME 100

#define IDR_AppID 105
#define IDR_Image3dSource 106
#define IDR_Image3dFileLoader 107
#define IDR_Image3dStream 106
#define IDR_Image3dSource 107
#define IDR_Image3dFileLoader 108
5 changes: 5 additions & 0 deletions DummyLoader/UNREGISTER_DummyLoader.bat
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ for %%R in (HKEY_LOCAL_MACHINE HKEY_CURRENT_USER) do (
reg delete "%%R\SOFTWARE\Classes\TypeLib\{67E59584-3F6A-4852-8051-103A4583CA5E}" /f 2> NUL

for %%P in (32 64) do (
:: Image3dStream class
reg delete "%%R\SOFTWARE\Classes\DummyLoader.Image3dStream" /f 2> NUL
reg delete "%%R\SOFTWARE\Classes\DummyLoader.Image3dStream.1" /f 2> NUL
reg delete "%%R\SOFTWARE\Classes\CLSID\{78317A0E-56BF-4735-AB5B-FE0751219FE8}" /f /reg:%%P 2> NUL

:: Image3dSource class
reg delete "%%R\SOFTWARE\Classes\DummyLoader.Image3dSource" /f 2> NUL
reg delete "%%R\SOFTWARE\Classes\DummyLoader.Image3dSource.1" /f 2> NUL
Expand Down

0 comments on commit f0fc938

Please sign in to comment.