43 #include "vtkImageData.h"
44 #include "vtkCriticalSection.h"
45 #include "vtkObjectFactory.h"
46 #include "vtkTimerLog.h"
47 #include "vtkInformation.h"
48 #include "vtkInformationVector.h"
49 #include "vtkStreamingDemandDrivenPipeline.h"
50 #include "vtkUnsignedCharArray.h"
51 #include "vtksys/SystemTools.hxx"
54 #include <igtlImageMessage.h>
61 #pragma warning (push, 3)
67 #include "ulterius_def.h"
68 #include "ImagingModes.h"
89 #define VARID_FREQ "b image"
90 #define VARID_DEPTH "b-depth"
91 #define VARID_GAIN "b-gain"
92 #define VARID_CGAIN "color-gain"
93 #define VARID_PGAIN "pw-gain"
94 #define VARID_TGC "gain curve"
95 #define VARID_ZOOM "zoom user"
96 #define VARID_CPRF "color-prp"
97 #define VARID_PPRF "pw-prp"
98 #define VARID_SECTOR "sector"
99 #define VARID_BCHROMA "b-chroma"
100 #define VARID_MCHROMA "m-chroma"
101 #define VARID_DYNRANGE "b-pulse index a"
102 #define VARID_CFOCUS "b-focus count"
103 #define VARID_CFOCUSCOLOR "color-focus count"
104 #define VARID_SFOCUS "focus span"
105 #define VARID_DFOCUS "focus depth"
106 #define VARID_FRATE "b frame rate"
107 #define VARID_MSWEEP 101
108 #define VARID_CLARITY 1112
109 #define VARID_CMAP 1082
110 #define VARID_BMAP 601
112 #if ( _MSC_VER >= 1300 ) // Visual studio .NET
113 #pragma warning ( disable : 4311 )
114 #pragma warning ( disable : 4312 )
115 # define vtkGetWindowLong GetWindowLongPtr
116 # define vtkSetWindowLong SetWindowLongPtr
117 # define vtkGWL_USERDATA GWLP_USERDATA
118 #else // regular Visual studio
119 # define vtkGetWindowLong GetWindowLong
120 # define vtkSetWindowLong SetWindowLong
121 # define vtkGWL_USERDATA GWL_USERDATA
137 this->
ult =
new ulterius;
139 this->Initialized = 0;
141 this->FrameSize[0] = 800;
142 this->FrameSize[1] = 600;
143 this->FrameSize[2] = 1;
154 this->OutputFormat = VTK_LUMINANCE;
155 this->NumberOfScalarComponents = 1;
156 this->FrameBufferBitsPerPixel = 8;
157 this->FlipFrames = 1;
158 this->FrameBufferRowAlignment = 1;
197 if(!vtkSonixVideoSource::Instance)
200 vtkSonixVideoSource::Instance =
dynamic_cast<vtkSonixVideoSource*
>(vtkObjectFactory::CreateInstance(
"vtkSonixVideoSource"));
201 if(!vtkSonixVideoSource::Instance)
205 if(!vtkSonixVideoSource::Instance)
211 return vtkSonixVideoSource::Instance;
216 if (vtkSonixVideoSource::Instance==instance)
221 if (vtkSonixVideoSource::Instance)
223 vtkSonixVideoSource::Instance->Delete();;
225 vtkSonixVideoSource::Instance = instance;
231 instance->Register(NULL);
236 this->Superclass::PrintSelf(os,indent);
238 os << indent <<
"Imaging mode: " << this->
ImagingMode <<
"\n";
239 os << indent <<
"Frequency: " << this->
Frequency <<
"MHz\n";
240 os << indent <<
"Frame rate: " << this->
FrameRate <<
"fps\n";
246 bool vtkSonixVideoSource::vtkSonixVideoSourceNewFrameCallback(
void * data,
int type,
int sz,
bool cine,
int frmnum)
250 printf(
"Error: no actual frame data received\n");
277 if (missedFrames < 0)
279 std::cout <<
"Missed frames: " << missedFrames <<
" " << std::endl;
302 this->FrameBufferMutex->Lock();
307 vtkErrorMacro(<<
"Received data type is different than expected");
310 if (this->AutoAdvance)
312 this->AdvanceFrameBuffer(1);
313 if (this->FrameIndex + 1 < this->FrameBufferSize)
318 int index = this->FrameBufferIndex;
329 this->FrameBufferTimeStamps[index] = vtkTimerLog::GetUniversalTime();
331 if (this->FrameCount++ == 0)
333 this->StartTimeStamp = this->FrameBufferTimeStamps[index];
343 if (type != this->AcquisitionDataType)
347 std::cout <<
"Error incorrect data type" << std::endl;
351 unsigned char *deviceDataPtr =
static_cast<unsigned char*
>(dataPtr);
354 unsigned char *frameBufferPtr = (
unsigned char *)((
reinterpret_cast<vtkUnsignedCharArray*
>(this->FrameBuffer[index]))->GetPointer(0));
361 int imagingDepth = 0;
362 int sectorPercent = 0;
363 bool linearProbe =
true;
365 if(!this->
ult->getParamValue(
"b-depth", imagingDepth))
366 std::cout <<
"Couldn't request the BMode imaging depth." << std::endl;
368 if(!this->
ult->getParamValue(
"sector", sectorPercent))
369 std::cout <<
"Couldn't request the sector percent." << std::endl;
372 if(!this->
ult->getActiveProbe(probeName, 200))
373 std::cout <<
"Couldn't request probe name." << std::endl;
376 QString probeFile =
"C:/Program Files/Ultrasonix/Exam/config/probes.xml";
380 std::cout <<
"Failed to initialize probe xml reader" << std::endl;
384 QDomNode probeNode = reader.getProbeNode(probeName);
385 linearProbe = reader.isProbeLinear(probeNode);
400 int outBytesPerRow = ((this->FrameBufferExtent[1]- this->FrameBufferExtent[0]+1)* this->FrameBufferBitsPerPixel + 7)/8;
401 outBytesPerRow += outBytesPerRow % this->FrameBufferRowAlignment;
403 int inBytesPerRow = this->FrameSize[0] * this->FrameBufferBitsPerPixel/8;
405 int rows = this->FrameBufferExtent[3]-this->FrameBufferExtent[2]+1;
408 if (sz != inBytesPerRow*rows)
414 std::cout <<
"Data discrepancy! size: " << sz <<
" inBytesPerRow: " << inBytesPerRow <<
" rows: " << rows << std::endl;
415 std::cout <<
"FrameSize[0]: " << this->FrameSize[0] <<
" * FrameBufferBitsPerPixel: " << this->FrameBufferBitsPerPixel << std::endl;
417 if (rows > sz / inBytesPerRow)
419 rows = sz / inBytesPerRow;
421 std::cout <<
"Trying to fix this by setting rows = " << rows << std::endl;
426 std::cout <<
"Keeping rows = " << rows << std::endl;
432 if( (type == udtBPre) || (type == udtRF)
433 || (type == udtMPre) || (type == udtPWRF)
434 || (type == udtColorRF)
441 deviceDataPtr += this->FrameBufferExtent[0]* this->FrameBufferBitsPerPixel/8;
442 deviceDataPtr += this->FrameBufferExtent[2]*inBytesPerRow;
445 if (outBytesPerRow == inBytesPerRow)
447 memcpy(frameBufferPtr,deviceDataPtr,inBytesPerRow*rows);
456 memcpy(frameBufferPtr,deviceDataPtr,outBytesPerRow);
457 frameBufferPtr += outBytesPerRow;
458 deviceDataPtr += inBytesPerRow;
480 if (this->OutputFormat == VTK_LUMINANCE)
485 else if (this->OutputFormat == VTK_LUMINANCE_ALPHA)
490 else if (this->OutputFormat == VTK_RGBA)
496 std::cout <<
"Unknown pixel format (not 8 or 32)" << std::endl;
499 rows = this->FrameBufferExtent[3]-this->FrameBufferExtent[2]+1;
500 frameBufferPtr = (
unsigned char *)((
reinterpret_cast<vtkUnsignedCharArray*
>(this->FrameBuffer[index]))->GetPointer(0));
502 frame.
mWidth = outBytesPerRow / this->NumberOfScalarComponents;
509 frame.
mSpacing[0] = this->DataSpacing[0];
510 frame.
mSpacing[1] = this->DataSpacing[1];
514 frame.
mOrigin[0] = this->DataOrigin[0] - this->FrameBufferExtent[0];
515 frame.
mOrigin[1] = this->DataOrigin[1] - this->FrameBufferExtent[2];
553 frame.
ulx = this->FrameBufferExtent[0] - this->FrameBufferExtent[0];
554 frame.
uly = this->FrameBufferExtent[2] - this->FrameBufferExtent[2];
555 frame.
urx = this->FrameBufferExtent[1] - this->FrameBufferExtent[0];
556 frame.
ury = this->FrameBufferExtent[2] - this->FrameBufferExtent[2];
557 frame.
brx = this->FrameBufferExtent[1] - this->FrameBufferExtent[0];
558 frame.
bry = this->FrameBufferExtent[3] - this->FrameBufferExtent[2];
559 frame.
blx = this->FrameBufferExtent[0] - this->FrameBufferExtent[0];
560 frame.
bly = this->FrameBufferExtent[3] - this->FrameBufferExtent[2];
577 this->FrameBufferMutex->Unlock();
582 return this->Initialized;
591 if (!this->Initialized)
594 return this->
ult->getFreezeState();
597 void vtkSonixVideoSource::waitForSonixWindow()
599 HWND phandle = FindWindow(NULL,
"Sonix: No connections");
604 std::cout <<
"Found Sonix window. First connect - Waiting "<<
mSonixConnectionDelay <<
" sec to connect" << std::endl;
611 std::cout <<
"Found Sonix window. Reconnect - Waiting 3 sec to connect" << std::endl;
612 vtksys::SystemTools::Delay(3000);
616 std::cout <<
"Didn't find Sonix window" << std::endl;
633 if (this->Initialized)
638 this->waitForSonixWindow();
641 if(!this->
ult->connect(this->SonixHostIP))
643 std::cout <<
"Try to connect to: " << this->
SonixHostIP << std::endl;
644 char *err =
new char[256];
646 this->
ult->getLastError(err,sz);
648 std::cout <<
"Initialize: couldn't connect to Sonix RP"<<
" (" << err <<
")" << std::endl;
654 if (!this->
ult->selectMode(this->ImagingMode))
656 char *err =
new char[256];
658 this->
ult->getLastError(err,sz);
660 std::cout <<
"Initialize: couldn't select imaging mode (" << err <<
")" << std::endl;
668 vtksys::SystemTools::Delay(2000);
673 char *err =
new char[256];
675 this->
ult->getLastError(err,sz);
677 std::cout <<
"Initialize: Requested imaging mode could not be selected(" << err <<
")" << std::endl;
686 char *err =
new char[256];
688 this->
ult->getLastError(err,sz);
690 std::cout <<
"Initialize: Requested the data aquisition type not available for selected imaging mode(" << err <<
")" << std::endl;
695 if (!this->
ult->setDataToAcquire(AcquisitionDataType))
697 char *err =
new char[256];
699 this->
ult->getLastError(err,sz);
701 std::cout <<
"Initialize: couldn't request the data aquisition type (" << err <<
")" << std::endl;
709 char *err =
new char[256];
711 this->
ult->getLastError(err,sz);
713 std::cout <<
"Initialize: couldn't retrieve data descriptor (" << err <<
")" << std::endl;
719 this->FrameBufferMutex->Lock();
721 this->FrameBufferMutex->Unlock();
757 this->
ult->setCallback(vtkSonixVideoSourceNewFrameCallback);
760 this->UpdateFrameBuffer();
763 ult->setSharedMemoryStatus(0);
765 this->Initialized = 1;
771 this->
ult->disconnect();
773 this->Initialized = 0;
786 if (!this->Initialized)
800 if (!this->Initialized)
810 if (!this->Recording)
823 this->vtkVideoSource::Play();
837 else if (this->Playing)
839 this->vtkVideoSource::Stop();
846 vtkInformation * vtkNotUsed(request),
847 vtkInformationVector **vtkNotUsed(inputVector),
848 vtkInformationVector *outputVector)
851 vtkInformation* outInfo = outputVector->GetInformationObject(0);
859 for (i = 0; i < 3; i++)
862 extent[2*i] = this->OutputWholeExtent[2*i];
863 extent[2*i+1] = this->OutputWholeExtent[2*i+1];
865 if (extent[2*i+1] < extent[2*i])
869 this->FrameBufferExtent[2*i+1] - this->FrameBufferExtent[2*i];
871 this->FrameOutputExtent[2*i] = extent[2*i];
872 this->FrameOutputExtent[2*i+1] = extent[2*i+1];
875 int numFrames = this->NumberOfOutputFrames;
880 if (numFrames > this->FrameBufferSize)
882 numFrames = this->FrameBufferSize;
886 extent[5] = extent[4] + (extent[5]-extent[4]+1) * numFrames - 1;
888 outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),extent,6);
890 outInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),extent,6);
892 outInfo->Set(vtkDataObject::SPACING(),this->DataSpacing,3);
895 outInfo->Set(vtkDataObject::ORIGIN(),this->DataOrigin,3);
897 if((this->AcquisitionDataType == udtRF) || (this->AcquisitionDataType == udtColorRF) || (this->AcquisitionDataType == udtPWRF))
899 vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_SHORT,
900 this->NumberOfScalarComponents);
905 vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_UNSIGNED_CHAR,
906 this->NumberOfScalarComponents);
914 vtkInformation *request,
915 vtkInformationVector **vtkNotUsed(inputVector),
916 vtkInformationVector *vtkNotUsed(outputVector))
918 vtkImageData *data = this->AllocateOutputData(this->GetOutput(), request);
922 int saveOutputExtent[6];
923 data->GetExtent(outputExtent);
924 for (i = 0; i < 6; i++)
926 saveOutputExtent[i] = outputExtent[i];
929 outputExtent[4] = this->FrameOutputExtent[4];
930 outputExtent[5] = this->FrameOutputExtent[5];
932 int frameExtentX = this->FrameBufferExtent[1]-this->FrameBufferExtent[0]+1;
933 int frameExtentY = this->FrameBufferExtent[3]-this->FrameBufferExtent[2]+1;
934 int frameExtentZ = this->FrameBufferExtent[5]-this->FrameBufferExtent[4]+1;
936 int extentX = outputExtent[1]-outputExtent[0]+1;
937 int extentY = outputExtent[3]-outputExtent[2]+1;
938 int extentZ = outputExtent[5]-outputExtent[4]+1;
945 int firstFrame = (saveOutputExtent[4]-outputExtent[4])/extentZ;
946 int firstOutputExtent4 = saveOutputExtent[4] - extentZ*firstFrame;
949 int finalFrame = (saveOutputExtent[5]-outputExtent[4])/extentZ;
950 int finalOutputExtent5 = saveOutputExtent[5] - extentZ*finalFrame;
952 char *outPtr = (
char *)data->GetScalarPointer();
955 int inIncY = (frameExtentX*this->FrameBufferBitsPerPixel + 7)/8;
956 inIncY = ((inIncY + this->FrameBufferRowAlignment - 1)/
957 this->FrameBufferRowAlignment)*this->FrameBufferRowAlignment;
958 int inIncZ = inIncY*frameExtentY;
960 int outIncX = this->FrameBufferBitsPerPixel/8;
961 int outIncY = outIncX*extentX;
962 int outIncZ = outIncY*extentY;
968 int outPadX = -outputExtent[0];
969 int outPadY = -outputExtent[2];
984 int outX = frameExtentX - inPadX;
985 int outY = frameExtentY - inPadY;
988 if (outX > extentX - outPadX)
990 outX = extentX - outPadX;
992 if (outY > extentY - outPadY)
994 outY = extentY - outPadY;
998 for (i = 0; i < 3; i++)
1000 if (saveOutputExtent[i] != this->LastOutputExtent[i])
1002 this->LastOutputExtent[i] = saveOutputExtent[i];
1003 this->OutputNeedsInitialization = 1;
1008 if (data->GetNumberOfScalarComponents() !=
1009 this->LastNumberOfScalarComponents)
1011 this->LastNumberOfScalarComponents = data->GetNumberOfScalarComponents();
1012 this->OutputNeedsInitialization = 1;
1016 if (this->OutputNeedsInitialization)
1019 (saveOutputExtent[1]-saveOutputExtent[0]+1)*
1020 (saveOutputExtent[3]-saveOutputExtent[2]+1)*
1021 (saveOutputExtent[5]-saveOutputExtent[4]+1)*outIncX);
1022 this->OutputNeedsInitialization = 0;
1028 int saveOutputExtent4 = outputExtent[4];
1029 outputExtent[4] = firstOutputExtent4;
1031 this->FrameBufferMutex->Lock();
1033 int index = this->FrameBufferIndex;
1034 this->FrameTimeStamp =
1035 this->FrameBufferTimeStamps[index % this->FrameBufferSize];
1038 for (frame = firstFrame; frame <= finalFrame; frame++)
1040 if (frame == finalFrame)
1042 outputExtent[5] = finalOutputExtent5;
1045 vtkDataArray *frameBuffer =
reinterpret_cast<vtkDataArray *
>(this->FrameBuffer[(index + frame) % this->FrameBufferSize]);
1047 char *inPtr =
reinterpret_cast<char*
>(frameBuffer->GetVoidPointer(0));
1050 extentZ = outputExtent[5]-outputExtent[4]+1;
1052 int outPadZ = -outputExtent[4];
1060 int outZ = frameExtentZ - inPadZ;
1062 if (outZ > extentZ - outPadZ)
1064 outZ = extentZ - outPadZ;
1067 if (this->FlipFrames)
1069 outPtr += outIncZ*outPadZ+outIncY*outPadY+outIncX*outPadX;
1070 inPtr += inIncZ*inPadZ+inIncY*(frameExtentY-inPadY-outY);
1072 for (i = 0; i < outZ; i++)
1075 outPtrTmp = outPtr + outIncY*outY;
1076 for (j = 0; j < outY; j++)
1078 outPtrTmp -= outIncY;
1091 outPtr += outIncZ*outPadZ+outIncY*outPadY+outIncX*outPadX;
1092 inPtr += inIncZ*inPadZ+inIncY*inPadY;
1094 for (i = 0; i < outZ; i++)
1098 for (j = 0; j < outY; j++)
1104 outPtrTmp += outIncY;
1112 outputExtent[4] = saveOutputExtent4;
1115 this->FrameBufferMutex->Unlock();
1127 int start,
int count)
1129 char alpha = (char)(this->Opacity*255);
1131 switch (this->AcquisitionDataType)
1137 case udtElastoOverlay:
1140 memcpy(outptr,inptr,count);
1150 memcpy(outptr,inptr,count);
1164 while (--count >= 0)
1166 *--outptr = *inptr++;
1167 *--outptr = *inptr++;
1181 case udtColorVelocityVariance:
1182 this->OutputFormat = VTK_RGB;
1183 this->NumberOfScalarComponents = 2;
1190 case udtElastoCombined:
1191 case udtColorCombined:
1195 while (--count >= 0)
1198 *--outptr = *inptr++;
1199 *--outptr = *inptr++;
1200 *--outptr = *inptr++;
1219 if (format == this->OutputFormat)
1224 this->OutputFormat = format;
1229 switch (this->OutputFormat)
1237 case VTK_LUMINANCE_ALPHA:
1245 vtkErrorMacro(<<
"SetOutputFormat: Unrecognized color format.");
1248 this->NumberOfScalarComponents = numComponents;
1250 if (this->FrameBufferBitsPerPixel != numComponents*8)
1252 this->FrameBufferMutex->Lock();
1253 this->FrameBufferBitsPerPixel = numComponents*8;
1254 if (this->Initialized)
1256 this->UpdateFrameBuffer();
1259 this->FrameBufferMutex->Unlock();
1320 switch (this->AcquisitionDataType)
1326 case udtElastoOverlay:
1327 this->OutputFormat = VTK_LUMINANCE;
1328 this->NumberOfScalarComponents = 1;
1337 this->OutputFormat = VTK_LUMINANCE;
1338 this->NumberOfScalarComponents = 1;
1348 this->OutputFormat = VTK_LUMINANCE;
1349 this->NumberOfScalarComponents = 1;
1354 case udtColorVelocityVariance:
1357 this->OutputFormat = VTK_LUMINANCE_ALPHA;
1358 this->NumberOfScalarComponents = 2;
1365 case udtElastoCombined:
1366 case udtColorCombined:
1367 this->OutputFormat = VTK_RGBA;
1368 this->NumberOfScalarComponents = 4;
1376 this->UpdateFrameBuffer();
1403 this->
ult->getParamValue(
"origin", origin))
1410 vtkErrorMacro(
"Couldn't request the origin.");
1412 double prevOriginX = this->DataOrigin[0];
1413 double prevOriginY = this->DataOrigin[1];
1414 this->DataOrigin[0] = origin.x;
1415 this->DataOrigin[1] = origin.y;
1418 if(prevOriginX != this->DataOrigin[0] || prevOriginY != this->DataOrigin[1])
1419 std::cout <<
"Origin: " << this->DataOrigin[0] <<
", " << this->DataOrigin[1] << std::endl;
1427 this->
ult->getParamValue(
"microns", microns))
1434 vtkErrorMacro(
"Couldn't request the microns (spacing?).");
1436 double prevSpacingX = this->DataSpacing[0];
1437 double prevSpacingY = this->DataSpacing[1];
1438 this->DataSpacing[0] = microns.x/1000.0;
1439 this->DataSpacing[1] = microns.y/1000.0;
1441 (prevSpacingX != this->DataSpacing[0]) || (prevSpacingY != this->DataSpacing[1]) ) )
1444 std::cout <<
"Spacing (mm): " << this->DataSpacing[0] <<
", " << this->DataSpacing[1] << std::endl;
1455 std::cout <<
"Set SonixHostIP: " << SonixIP << std::endl;
1475 this->FrameBufferExtent[0] =
max(roi.ulx, 0);
1476 this->FrameBufferExtent[1] =
min(roi.urx, this->FrameSize[0] - 1);
1477 this->FrameBufferExtent[2] =
max(roi.uly, 0);
1478 this->FrameBufferExtent[3] =
min(roi.bly, this->FrameSize[1] - 1);
1483 this->FrameBufferExtent[0] = 0;
1484 this->FrameBufferExtent[1] = this->FrameSize[0] - 1;
1485 this->FrameBufferExtent[2] = 0;
1486 this->FrameBufferExtent[3] = this->FrameSize[1] - 1;