diff --git a/Modules/US/USFilters/mitkUSImageSource.cpp b/Modules/US/USFilters/mitkUSImageSource.cpp index 411a8bd76e..7221679399 100644 --- a/Modules/US/USFilters/mitkUSImageSource.cpp +++ b/Modules/US/USFilters/mitkUSImageSource.cpp @@ -1,121 +1,120 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkUSImageSource.h" #include "mitkProperties.h" const char* mitk::USImageSource::IMAGE_PROPERTY_IDENTIFIER = "id_nummer"; mitk::USImageSource::USImageSource() : m_OpenCVToMitkFilter(mitk::OpenCVToMitkImageFilter::New()), m_MitkToOpenCVFilter(nullptr), m_ImageFilter(mitk::BasicCombinationOpenCVImageFilter::New()), m_CurrentImageId(0) { } mitk::USImageSource::~USImageSource() { } void mitk::USImageSource::PushFilter(AbstractOpenCVImageFilter::Pointer filter) { m_ImageFilter->PushFilter(filter); } bool mitk::USImageSource::RemoveFilter(AbstractOpenCVImageFilter::Pointer filter) { return m_ImageFilter->RemoveFilter(filter); } bool mitk::USImageSource::GetIsFilterInThePipeline(AbstractOpenCVImageFilter::Pointer filter) { return m_ImageFilter->GetIsFilterOnTheList(filter); } std::vector mitk::USImageSource::GetNextImage() { std::vector result; // Apply OpenCV based filters beforehand if (m_ImageFilter.IsNotNull() && !m_ImageFilter->GetIsEmpty()) { std::vector imageVector; GetNextRawImage(imageVector); if(result.size() != imageVector.size()) result.resize(imageVector.size()); for (size_t i = 0; i < imageVector.size(); ++i) { if (!imageVector[i].empty()) { m_ImageFilterMutex.lock(); m_ImageFilter->FilterImage(imageVector[i], m_CurrentImageId); m_ImageFilterMutex.unlock(); // convert to MITK image this->m_OpenCVToMitkFilter->SetOpenCVMat(imageVector[i]); this->m_OpenCVToMitkFilter->Update(); // OpenCVToMitkImageFilter returns a standard mitk::image. result[i] = this->m_OpenCVToMitkFilter->GetOutput(); } } } else { this->GetNextRawImage(result); } for (size_t i = 0; i < result.size(); ++i) { if (result[i].IsNotNull()) { result[i]->SetProperty(IMAGE_PROPERTY_IDENTIFIER, mitk::IntProperty::New(m_CurrentImageId)); } else { - //MITK_WARN("mitkUSImageSource") << "Result image " << i << " is not set."; result[i] = mitk::Image::New(); } } m_CurrentImageId++; return result; } void mitk::USImageSource::GetNextRawImage(std::vector& imageVector) { // create filter object if it does not exist yet if (!m_MitkToOpenCVFilter) { m_MitkToOpenCVFilter = mitk::ImageToOpenCVImageFilter::New(); } // get mitk image through virtual method of the subclass std::vector mitkImg; this->GetNextRawImage(mitkImg); for (unsigned int i = 0; i < mitkImg.size(); ++i) { if (mitkImg[i].IsNull() || !mitkImg[i]->IsInitialized()) { imageVector[i] = cv::Mat(); } else { // convert mitk::Image to an OpenCV image m_MitkToOpenCVFilter->SetImage(mitkImg[i]); imageVector[i] = m_MitkToOpenCVFilter->GetOpenCVMat(); } } } diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.cpp b/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.cpp index ac4b7dc15d..fa2a0ce272 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.cpp +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.cpp @@ -1,398 +1,362 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkUSTelemedDevice.h" #include "mitkImageReadAccessor.h" #include "mitkUSTelemedSDKHeader.h" mitk::USTelemedDevice::USTelemedDevice(std::string manufacturer, std::string model) : mitk::USDevice(manufacturer, model), m_ControlsProbes(mitk::USTelemedProbesControls::New(this)), m_ControlsBMode(mitk::USTelemedBModeControls::New(this)), m_ControlsDoppler(mitk::USTelemedDopplerControls::New(this)), m_ImageSource(mitk::USTelemedImageSource::New()), m_UsgMainInterface(0), m_Probe(0), m_UsgDataView(0), m_ProbesCollection(0) { SetNumberOfIndexedOutputs(1); SetNthOutput(0, this->MakeOutput(0)); } mitk::USTelemedDevice::~USTelemedDevice() { } std::string mitk::USTelemedDevice::GetDeviceClass() { return "org.mitk.modules.us.USTelemedDevice"; } mitk::USControlInterfaceBMode::Pointer mitk::USTelemedDevice::GetControlInterfaceBMode() { return m_ControlsBMode.GetPointer(); } mitk::USControlInterfaceProbes::Pointer mitk::USTelemedDevice::GetControlInterfaceProbes() { return m_ControlsProbes.GetPointer(); }; mitk::USControlInterfaceDoppler::Pointer mitk::USTelemedDevice::GetControlInterfaceDoppler() { return m_ControlsDoppler.GetPointer(); }; bool mitk::USTelemedDevice::OnInitialization() { CoInitialize(nullptr); // initialize COM library return true; } bool mitk::USTelemedDevice::OnConnection() { // create main Telemed API COM library object HRESULT hr; hr = CoCreateInstance(Usgfw2Lib::CLSID_Usgfw2, nullptr, CLSCTX_INPROC_SERVER, Usgfw2Lib::IID_IUsgfw2,(LPVOID*) &m_UsgMainInterface); if (FAILED(hr)) { SAFE_RELEASE(m_UsgMainInterface); MITK_ERROR("USDevice")("USTelemedDevice") << "Error at connecting to ultrasound device (" << hr << ")."; return false; } this->ConnectDeviceChangeSink(); return true; } bool mitk::USTelemedDevice::OnDisconnection() { // control objects cannot be active anymore m_ControlsBMode->SetIsActive(false); m_ControlsDoppler->SetIsActive(false); m_ControlsProbes->SetIsActive(false); ReleaseUsgControls(); return true; } bool mitk::USTelemedDevice::OnActivation() { // probe controls are available now m_ControlsProbes->SetIsActive(true); if ( m_ControlsProbes->GetProbesCount() < 1 ) { MITK_WARN("USDevice")("USTelemedDevice") << "No probe found."; return false; } // select first probe as a default m_ControlsProbes->SelectProbe(0); // set scan mode b as default for activation - // control interfaces can override this later HRESULT hr = m_UsgDataView->put_ScanMode(Usgfw2Lib::SCAN_MODE_B); if (FAILED(hr)) { MITK_ERROR("USDevice")("USTelemedDevice") << "Could not set scan mode b (" << hr << ")."; return false; } // start ultrasound scanning with selected scan mode hr = m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_RUN); if (FAILED(hr)) { MITK_ERROR("USDevice")("USTelemedDevice") << "Start scanning failed (" << hr << ")."; return false; } m_ControlsBMode->ReinitializeControls(); return true; } bool mitk::USTelemedDevice::OnDeactivation() { this->StopScanning(); return true; } void mitk::USTelemedDevice::OnFreeze(bool freeze) { if ( freeze ) { m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_FREEZE); } else { m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_RUN); } } void mitk::USTelemedDevice::GenerateData() -{/* - mitk::Image::Pointer nextImage = GetUSImageSource()->GetNextImage().at(0); - mitk::Image::Pointer output = this->GetOutput(0); - - if (!output->IsInitialized() || - output->GetDimension(0) != nextImage->GetDimension(0) || - output->GetDimension(1) != nextImage->GetDimension(1) || - output->GetDimension(2) != nextImage->GetDimension(2) || - output->GetPixelType() != nextImage->GetPixelType()) - { - output->Initialize(nextImage->GetPixelType(), nextImage->GetDimension(), - nextImage->GetDimensions()); - } - - // copy contents of the given image into the member variable - mitk::ImageReadAccessor inputReadAccessor(nextImage); - output->SetImportVolume(inputReadAccessor.GetData()); - output->SetGeometry(nextImage->GetGeometry());*/ - - //this->SetNthOutput(0,nextImage); - //m_ImageVector[0] = GetUSImageSource()->GetNextImage().at(0); - //Superclass::GenerateData(); - //if( m_ImageVector.size() == 0 || this->GetNumberOfIndexedOutputs() == 0 ) - //{ - // return; - //} - - /* - m_ImageMutex.lock(); - mitk::Image::Pointer nextImage = GetUSImageSource()->GetNextImage().back(); - this->SetOutput(0,nextImage); - /* - auto& image = m_ImageVector[0]; - if( image.IsNotNull() && image->IsInitialized() && m_CurrentProbe.IsNotNull() ) - { - //MITK_INFO << "Spacing CurrentProbe: " << m_CurrentProbe->GetSpacingForGivenDepth(m_CurrentProbe->GetCurrentDepth()); - image->GetGeometry()->SetSpacing(m_CurrentProbe->GetSpacingForGivenDepth(m_CurrentProbe->GetCurrentDepth())); - this->GetOutput(0)->SetGeometry(image->GetGeometry()); - } - m_ImageMutex.unlock();*/ +{ + mitk::USTelemedImageSource::Pointer s = dynamic_cast(GetUSImageSource().GetPointer()); + s->GetNextRawImage(m_ImageVector); + Superclass::GenerateData(); } mitk::USImageSource::Pointer mitk::USTelemedDevice::GetUSImageSource() { return m_ImageSource.GetPointer(); } void mitk::USTelemedDevice::ReleaseUsgControls() { if (m_UsgDataView) { this->StopScanning(); }; SAFE_RELEASE(m_UsgMainInterface); SAFE_RELEASE(m_Probe); SAFE_RELEASE(m_UsgDataView); SAFE_RELEASE(m_ProbesCollection); } void mitk::USTelemedDevice::StopScanning() { if ( ! m_UsgDataView ) { MITK_WARN("USDevice")("USTelemedDevice") << "Cannot stop scanning as Telemed Data View is null."; return; } HRESULT hr; hr = m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_STOP); if (FAILED(hr)) { MITK_ERROR("USDevice")("USTelemedDevice") << "Stop scanning failed (" << hr << ")."; mitkThrow() << "Stop scanning failed (" << hr << ")."; } } std::vector mitk::USTelemedDevice::GetAllProbes(){ return m_ControlsProbes->GetProbeSet(); } mitk::USProbe::Pointer mitk::USTelemedDevice::GetCurrentProbe(){ return m_ControlsProbes->GetSelectedProbe(); } mitk::USProbe::Pointer mitk::USTelemedDevice::GetProbeByName(std::string name){ for (mitk::USProbe::Pointer p : m_ControlsProbes->GetProbeSet()){ if (p->GetName().compare(name)==0) {return p;} } return nullptr; } Usgfw2Lib::IUsgfw2* mitk::USTelemedDevice::GetUsgMainInterface() { return m_UsgMainInterface; } void mitk::USTelemedDevice::SetActiveDataView(Usgfw2Lib::IUsgDataView* usgDataView) { // do nothing if the usg data view hasn't changed if ( m_UsgDataView != usgDataView ) { // scan converter plugin is connected to IUsgDataView -> a new plugin // must be created when changing IUsgDataView m_UsgDataView = usgDataView; if ( ! m_ImageSource->CreateAndConnectConverterPlugin(m_UsgDataView, Usgfw2Lib::SCAN_MODE_B)) { return; } // b mode control object must know about active data view m_ControlsBMode->SetUsgDataView(m_UsgDataView); } } void mitk::USTelemedDevice::ConnectDeviceChangeSink( ) { IConnectionPointContainer* cpc = nullptr; HRESULT hr = m_UsgMainInterface->QueryInterface(IID_IConnectionPointContainer, (void**)&cpc); if (hr != S_OK) cpc = nullptr; if (cpc != nullptr) hr = cpc->FindConnectionPoint(Usgfw2Lib::IID_IUsgDeviceChangeSink, &m_UsgDeviceChangeCpnt); if (hr != S_OK) { m_UsgDeviceChangeCpnt = nullptr; m_UsgDeviceChangeCpntCookie = 0; } SAFE_RELEASE(cpc); if (m_UsgDeviceChangeCpnt != nullptr) hr = m_UsgDeviceChangeCpnt->Advise((IUnknown*)((Usgfw2Lib::IUsgDeviceChangeSink*)this), &m_UsgDeviceChangeCpntCookie); } // --- Methods for Telemed API Interfaces HRESULT __stdcall mitk::USTelemedDevice::raw_OnBeamformerArrive(IUnknown *pUsgBeamformer, ULONG *reserved) { this->Connect(); return S_OK; } HRESULT __stdcall mitk::USTelemedDevice::raw_OnBeamformerRemove(IUnknown *pUsgBeamformer, ULONG *reserved) { if ( this->GetIsActive() ) { this->Deactivate(); } this->Disconnect(); return S_OK; } HRESULT __stdcall mitk::USTelemedDevice::raw_OnProbeArrive(IUnknown*, ULONG* probeIndex) { m_ControlsProbes->ProbeAdded(static_cast(*probeIndex)); this->Activate(); return S_OK; }; HRESULT __stdcall mitk::USTelemedDevice::raw_OnProbeRemove(IUnknown*, ULONG* probeIndex) { m_ControlsProbes->ProbeRemoved(static_cast(*probeIndex)); if ( this->GetIsActive() ) { this->Deactivate(); } return S_OK; }; STDMETHODIMP_(ULONG) mitk::USTelemedDevice::AddRef() { ++m_RefCount; return m_RefCount; } STDMETHODIMP_(ULONG) mitk::USTelemedDevice::Release() { --m_RefCount; return m_RefCount; } STDMETHODIMP mitk::USTelemedDevice::QueryInterface(REFIID riid, void** ppv) { if (riid == IID_IUnknown || riid == Usgfw2Lib::IID_IUsgDeviceChangeSink) { *ppv = (IUsgDeviceChangeSink*)this; return S_OK; } if (riid == IID_IDispatch) { *ppv = (IDispatch*)this; return S_OK; } return E_NOINTERFACE; } HRESULT mitk::USTelemedDevice::GetTypeInfoCount(UINT *pctinfo) { if (pctinfo == nullptr) return E_INVALIDARG; *pctinfo = 0; return S_OK; } HRESULT mitk::USTelemedDevice::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) { if (pptinfo == nullptr) return E_INVALIDARG; *pptinfo = nullptr; if(itinfo != 0) return DISP_E_BADINDEX; return S_OK; } HRESULT mitk::USTelemedDevice::GetIDsOfNames(const IID &riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) { // this is not used - must use the same fixed dispid's from Usgfw2 idl file return S_OK; } HRESULT mitk::USTelemedDevice::Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { if ( (dispIdMember >= 1) && (dispIdMember <= 6) ) { if (pDispParams->cArgs != 2) // we need 2 arguments return S_OK; IUnknown *unkn = nullptr; ULONG *res = nullptr; VARIANTARG* p1; VARIANTARG* p; p1 = pDispParams->rgvarg; p = p1; if (p->vt == (VT_BYREF|VT_UI4)) res = p->pulVal; p1++; p = p1; if (p->vt == VT_UNKNOWN) unkn = (IUnknown*)(p->punkVal); if (dispIdMember == 1) OnProbeArrive(unkn, res); else if (dispIdMember == 2) OnBeamformerArrive(unkn, res); else if (dispIdMember == 3) OnProbeRemove(unkn, res); else if (dispIdMember == 4) OnBeamformerRemove(unkn, res); else if (dispIdMember == 5) OnProbeStateChanged(unkn, res); else if (dispIdMember == 6) OnBeamformerStateChanged(unkn, res); } return S_OK; } diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp b/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp index 5bb0a08b94..c13bb8a2dd 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp @@ -1,144 +1,139 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkUSTelemedImageSource.h" #include "mitkUSTelemedSDKHeader.h" #include "MITKUSTelemedScanConverterPlugin.h" #include "mitkImageReadAccessor.h" mitk::USTelemedImageSource::USTelemedImageSource() : m_Image(mitk::Image::New()), m_ImageMutex(new std::mutex()), m_Plugin(0), m_PluginCallback(0), m_UsgDataView(0), m_ImageProperties(0), m_DepthProperties(0), m_OldnXPelsPerUnit(0), m_OldnYPelsPerUnit(0) { } mitk::USTelemedImageSource::~USTelemedImageSource( ) { SAFE_RELEASE(m_PluginCallback); SAFE_RELEASE(m_Plugin); SAFE_RELEASE(m_ImageProperties); SAFE_RELEASE(m_DepthProperties); delete m_ImageMutex; } void mitk::USTelemedImageSource::GetNextRawImage(std::vector& imageVector) { - MITK_INFO << "Updating Telemed Image"; if (imageVector.empty() ) { imageVector.push_back( mitk::Image::New()); } //get the actual resolution to check if it changed. We have to do this every time because the geometry takes a few frames to adapt Usgfw2Lib::tagImageResolution resolutionInMetersActual; m_ImageProperties->GetResolution(&resolutionInMetersActual, 0); if (m_OldnXPelsPerUnit != resolutionInMetersActual.nXPelsPerUnit || m_OldnYPelsPerUnit != resolutionInMetersActual.nYPelsPerUnit) { //we can only update if the image exists and has a geometry if (m_Image.IsNotNull() && m_Image->GetGeometry() != nullptr) { m_OldnXPelsPerUnit = resolutionInMetersActual.nXPelsPerUnit; m_OldnYPelsPerUnit = resolutionInMetersActual.nYPelsPerUnit; UpdateImageGeometry(); } } //now update image if ( m_Image->IsInitialized() ) { m_ImageMutex->lock(); // copy contents of the given image into the member variable imageVector.at(0)->Initialize(m_Image->GetPixelType(), m_Image->GetDimension(), m_Image->GetDimensions()); mitk::ImageReadAccessor inputReadAccessor(m_Image, m_Image->GetSliceData(0,0,0)); imageVector.at(0)->SetSlice(inputReadAccessor.GetData()); imageVector.at(0)->SetGeometry(m_Image->GetGeometry()); - MITK_INFO << "Telemed Image update in progress"; m_ImageMutex->unlock(); } - MITK_INFO << "Telemed Image updated"; - } void mitk::USTelemedImageSource::UpdateImageGeometry() { Usgfw2Lib::tagPixelsOrigin origin = Usgfw2Lib::tagPixelsOrigin(); Usgfw2Lib::tagImageResolution resolutionInMeters; m_ImageProperties->GetResolution(&resolutionInMeters,0); mitk::Vector3D spacing; spacing[0] = ((double)1 / resolutionInMeters.nXPelsPerUnit) * 1000; //conversion: meters to millimeters spacing[1] = ((double)1 / resolutionInMeters.nXPelsPerUnit) * 1000; //conversion: meters to millimeters spacing[2] = 1; m_ImageMutex->lock(); if(m_Image.IsNotNull() && (m_Image->GetGeometry()!=nullptr)) { m_Image->GetGeometry()->SetSpacing(spacing); m_Image->GetGeometry()->Modified(); } else {MITK_WARN << "image or geometry was nullptr, can't adapt geometry";} m_ImageMutex->unlock(); MITK_DEBUG << "UpdateImageGeometry called!"; MITK_DEBUG << "depth: " << m_DepthProperties->GetCurrent(); MITK_DEBUG << "new spacing: " << spacing; } bool mitk::USTelemedImageSource::CreateAndConnectConverterPlugin(Usgfw2Lib::IUsgDataView* usgDataView, Usgfw2Lib::tagScanMode scanMode) { IUnknown* tmp_obj = nullptr; - // create control object from Telemed API mitk::telemed::CreateUsgControl( usgDataView, Usgfw2Lib::IID_IUsgScanConverterPlugin, scanMode, 0, (void**)&tmp_obj ); if ( ! tmp_obj ) { MITK_ERROR("USImageSource")("USTelemedImageSource") << "Could not create scan converter plugin."; return false; } // create the callback object for the scan conversion if ( ! m_PluginCallback ) { m_PluginCallback = new USTelemedScanConverterPlugin(); // current image buffer should be copied to m_Image at every callback m_PluginCallback->SetOutputImage(m_Image.GetPointer(), m_ImageMutex); } else { // make sure that the scan converter plugin is not set // to the plugin callback any longer m_PluginCallback->SetScanConverterPlugin(0); } // now the ScanConverterPlugin can be created and set as plugin SAFE_RELEASE(m_Plugin); m_Plugin = (Usgfw2Lib::IUsgScanConverterPlugin*)tmp_obj; m_PluginCallback->SetScanConverterPlugin(m_Plugin); //last: create some connections which are needed inside this class for communication with the telemed device m_UsgDataView = usgDataView; // create telemed controls if (!m_DepthProperties) {CREATE_TelemedControl(m_DepthProperties, m_UsgDataView, Usgfw2Lib::IID_IUsgDepth, Usgfw2Lib::IUsgDepth, Usgfw2Lib::SCAN_MODE_B);} if (!m_ImageProperties) {CREATE_TelemedControl(m_ImageProperties, m_UsgDataView, Usgfw2Lib::IID_IUsgImageProperties, Usgfw2Lib::IUsgImageProperties, Usgfw2Lib::SCAN_MODE_B);} return true; } diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.cpp b/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.cpp index 8722a3e304..597364bf53 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.cpp +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.cpp @@ -1,149 +1,147 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkUSTelemedScanConverterPlugin.h" #include "mitkImageWriteAccessor.h" USTelemedScanConverterPlugin::USTelemedScanConverterPlugin( ) : m_Plugin(nullptr), m_OutputImage(nullptr) { } USTelemedScanConverterPlugin::~USTelemedScanConverterPlugin( ) { ReleasePlugin(); } // -- internal Telemed API function HRESULT __stdcall USTelemedScanConverterPlugin::QueryInterface(const IID& iid, void** ppv) { reinterpret_cast(*ppv)->AddRef() ; return S_OK ; } // -- internal Telemed API function ULONG __stdcall USTelemedScanConverterPlugin::AddRef() { return InterlockedIncrement(&m_cRef) ; } // -- internal Telemed API function ULONG __stdcall USTelemedScanConverterPlugin::Release() { if (InterlockedDecrement(&m_cRef) == 0) { delete this ; return 0 ; } return m_cRef ; } STDMETHODIMP USTelemedScanConverterPlugin::InterimOutBufferCB ( PBYTE pBufferInterim, int nInterimBufferLen, PBYTE pBufferOut, int nOutBufferLen, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ) { if ( m_OutputImage.IsNull() ) { return S_FALSE; }; - m_OutputImageMutex->lock(); - // initialize mitk::Image with given image size on the first time if ( ! m_OutputImage->IsInitialized() ) { unsigned int dim[]={static_cast(abs(nOutX2 - nOutX1)), static_cast(abs(nOutY2 - nOutY1))}; // image dimensions m_OutputImage->Initialize(mitk::MakeScalarPixelType(), 2, dim); } // lock the image for writing an copy the given buffer into the image then m_OutputImage->SetSlice(pBufferOut); m_OutputImageMutex->unlock(); return S_OK; } void USTelemedScanConverterPlugin::ReleasePlugin() { if (m_Plugin != nullptr) { // remove this callback from Telemed API plugin m_Plugin->SetCallback(nullptr,USPC_BUFFER_INTERIM_OUTPUT); } } void USTelemedScanConverterPlugin::SetOutputImage(mitk::Image::Pointer outputImage, std::mutex* outputImageMutex) { m_OutputImage = outputImage; m_OutputImageMutex = outputImageMutex; } STDMETHODIMP USTelemedScanConverterPlugin::SetScanConverterPlugin(IDispatch* plugin) { // make sure that there is no scan converter plugin registered already this->ReleasePlugin(); HRESULT hr; // it is ok to call this method with a nullptr plugin to remove // a previous callback if (plugin == nullptr) { MITK_INFO("IUsgfwScanConverterPluginCB")("ScanConverterPlugin") << "nullptr plugin set to the scan converter. The callback for the previous plugin is removed now."; return S_OK; } // get Telemed API plugin from the COM library Usgfw2Lib::IUsgScanConverterPlugin* tmp_plugin; hr = plugin->QueryInterface(__uuidof(Usgfw2Lib::IUsgScanConverterPlugin), (void**)&tmp_plugin); if (FAILED(hr)) { MITK_WARN("IUsgfwScanConverterPluginCB")("ScanConverterPlugin") << "Could not query com interface for IUsgScanConverterPlugin (" << hr << ")."; return hr; } // get the converter for scan lines from the COM library and // save it as a member attribute hr = tmp_plugin->get_ScanConverter((IUnknown**)&m_Plugin); if (FAILED(hr)) { MITK_WARN("IUsgfwScanConverterPluginCB")("ScanConverterPlugin") << "Could not get ScanConverter from plugin (" << hr << ")."; return hr; } SAFE_RELEASE(tmp_plugin); // now the callback can be set -> interface functions of this // object will be called from now on when new image data is // available hr = m_Plugin->SetCallback(this,USPC_BUFFER_INTERIM_OUTPUT); if (FAILED(hr)) { MITK_WARN("IUsgfwScanConverterPluginCB")("ScanConverterPlugin") << "Could not set callback for plugin (" << hr << ")."; return hr; } return S_OK; }