UsTK : Ultrasound ToolKit  version 2.0.1 under development (2024-05-21)
usVirtualServer.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ustk software.
4  * Copyright (C) 2016 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ustk with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * This software was developed at:
17  * Inria Rennes - Bretagne Atlantique
18  * Campus Universitaire de Beaulieu
19  * 35042 Rennes Cedex
20  * France
21  *
22  * If you have questions regarding the use of this file, please contact
23  * Inria at ustk@inria.fr
24  *
25  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27  *
28  * Authors:
29  * Marc Pouliquen
30  *
31  *****************************************************************************/
32 
33 #include "usVirtualServer.h"
34 
41 usVirtualServer::usVirtualServer(std::string sequencePath, QObject *parent)
42  : QObject(parent), m_tcpServer(), m_serverIsSendingImages(false), m_consoleListener()
43 {
44  m_usePause = false;
45  m_pauseOn = false;
46  m_volumePauseTmp = false;
47  m_pauseDurationOffset = 0;
48  m_pauseIndexOffset = 0;
49 
50  m_useRewind = false;
51 
52  if (qApp->arguments().contains(QString("--pause"))) {
53  m_usePause = true;
54  m_pauseImageNumber = qApp->arguments().at(qApp->arguments().indexOf(QString("--pause")) + 1).toInt();
55  std::cout << "Pause activated on image N. : " << m_pauseImageNumber << "\n";
56  }
57 
58  if (qApp->arguments().contains(QString("--rewind"))) {
59  m_useRewind = true;
60  std::cout << "Rewind option activated\n";
61  }
62 
63  imageHeader.frameCount = 0;
64  // read sequence parameters
65  setSequencePath(sequencePath); // opens first image of the sequence
66 
67  // init TCP server
68  // set : acceptTheConnection() will be called whenever there is a new connection
69  connect(&m_tcpServer, SIGNAL(newConnection()), this, SLOT(acceptTheConnection()));
70 
71  // loop sending image activation / desactivation
72  connect(this, SIGNAL(runAcquisitionSignal(bool)), this, SLOT(runAcquisition(bool)));
73  connect(this, SIGNAL(startSendingLoopSignal()), this, SLOT(startSendingLoop()));
74 
75  // console input (user)
76  connect(&m_consoleListener, SIGNAL(quitPause()), this, SLOT(quitPause()));
77 
78  // Start listening on port 8080
79  QString portNum = QString::number(8080);
80  bool status = m_tcpServer.listen(QHostAddress::Any, portNum.toUShort());
81 
82  // Check, if the server did start correctly or not
83  if (status == true) {
84  std::cout << "TCP server Started\nServer now listening on port# " << portNum.toStdString() << std::endl;
85  } else {
86  std::cout << "TCP server start failure" << m_tcpServer.errorString().toStdString() << std::endl;
87  }
88 }
89 
94 
98 void usVirtualServer::acceptTheConnection()
99 {
100 
101  connectionSoc = m_tcpServer.nextPendingConnection();
102 
103  connect(connectionSoc, SIGNAL(readyRead()), this, SLOT(readIncomingData()));
104 
105  connect(connectionSoc, SIGNAL(disconnected()), this, SLOT(connectionAboutToClose()));
106 }
107 
111 void usVirtualServer::readIncomingData()
112 {
113  // headers possible to be received
115 
116  // reading part
117 
118  // prepare reading in QDataStream
119  QDataStream in;
120  in.setDevice(connectionSoc);
121 #if defined(USTK_HAVE_VTK_QT4)
122  in.setVersion(QDataStream::Qt_4_8);
123 #else
124  in.setVersion(QDataStream::Qt_5_0);
125 #endif
126 
127  // read header id
128  int id;
129  in >> id;
130 
131  if (id == 1) { // init header
132  in >> headerInit.probeId;
133  in >> headerInit.slotId;
134  in >> headerInit.imagingMode;
135 
136  // values by default for virtual server
137  confirmHeader.initOk = 1;
138  confirmHeader.probeId = 0;
139 
140  // send back default params
141  QByteArray block;
142  QDataStream out(&block, QIODevice::WriteOnly);
143 #if defined(USTK_HAVE_VTK_QT4)
144  out.setVersion(QDataStream::Qt_4_8);
145 #else
146  out.setVersion(QDataStream::Qt_5_0);
147 #endif
148  out << confirmHeader.headerId;
149  out << confirmHeader.initOk;
150  out << confirmHeader.probeId;
151 
152  writeInitAcquisitionParameters(out, headerInit.imagingMode);
153 
154  connectionSoc->write(block);
155  } else if (id == 2) { // update header
156  throw(vpException(vpException::fatalError, "no update available for virtual server !"));
157  } else if (id == 3) { // run - stop command
158  bool run;
159  in >> run;
160 
161  emit(runAcquisitionSignal(run));
162  } else {
163  std::cout << "ERROR : unknown data received !" << std::endl;
164  }
165 }
166 
170 void usVirtualServer::connectionAboutToClose()
171 {
172  // Set this text into the label
173  std::cout << "Connection to client closed" << std::endl;
174 
175  // Close the connection (Say bye)
176  connectionSoc->close();
177 
178 // delete sequcence reader and reset frame count (to prepare them for a potential new connection)
179 #ifdef VISP_HAVE_XML2
180  m_sequenceReaderPostScan = usSequenceReader<usImagePostScan2D<unsigned char> >();
181  m_sequenceReaderPreScan = usSequenceReader<usImagePreScan2D<unsigned char> >();
182 #endif
183  imageHeader.frameCount = 0;
184 
185  // Re-open the sequence to prepare next connection incomming (the server is still running)
186  setSequencePath(m_sequencePath);
187 }
188 
192 void usVirtualServer::writeInitAcquisitionParameters(QDataStream &stream, int imagingMode)
193 {
194 
195  int transmitFrequency = 0;
196  int samplingFrequency = 0;
197  bool postScanMode = false;
198  int postScanHeight = 0;
199  int postScanWidth = 0;
200  int imageDepth = 0;
201  int sector = 100;
202  bool activateMotor = false;
203  int motorPosition = 0;
204  int framesPerVolume = 1;
205  int stepsPerFrame = 0;
206  int transmitFrequencyMin = 0;
207  int samplingFrequencyMin = 0;
208  int imagingModeMin = 0;
209  int imageDepthMin = 0;
210  int sectorMin = 100;
211  int motorPositionMin = 0;
212  int framesPerVolumeMin = 1;
213  int stepsPerFrameMin = 0;
214  int transmitFrequencyMax = 0;
215  int samplingFrequencyMax = 0;
216  int imagingModeMax = 27;
217  int imageDepthMax = 0;
218  int sectorMax = 100;
219  int motorPositionMax = 0;
220  int framesPerVolumeMax = 0;
221  int stepsPerFrameMax = 0;
222 
223  if (m_imageType == us::PRESCAN_2D) {
224  transmitFrequency = m_preScanImage2d.getTransmitFrequency();
225  transmitFrequencyMin = m_preScanImage2d.getTransmitFrequency();
226  transmitFrequencyMax = m_preScanImage2d.getTransmitFrequency();
227 
228  samplingFrequency = m_preScanImage2d.getSamplingFrequency();
229  samplingFrequencyMin = m_preScanImage2d.getSamplingFrequency();
230  samplingFrequencyMax = m_preScanImage2d.getSamplingFrequency();
231 
232  imageDepth = m_preScanImage2d.getDepth();
233  imageDepthMin = m_preScanImage2d.getDepth();
234  imageDepthMax = m_preScanImage2d.getDepth();
235  } else if (m_imageType == us::POSTSCAN_2D) {
236  transmitFrequency = m_postScanImage2d.getTransmitFrequency();
237  transmitFrequencyMin = m_postScanImage2d.getTransmitFrequency();
238  transmitFrequencyMax = m_postScanImage2d.getTransmitFrequency();
239 
240  samplingFrequency = m_postScanImage2d.getSamplingFrequency();
241  samplingFrequencyMin = m_postScanImage2d.getSamplingFrequency();
242  samplingFrequencyMax = m_postScanImage2d.getSamplingFrequency();
243 
244  imageDepth = m_postScanImage2d.getDepth();
245  imageDepthMin = m_postScanImage2d.getDepth();
246  imageDepthMax = m_postScanImage2d.getDepth();
247 
248  postScanMode = true;
249  }
250 
251  stream << transmitFrequency;
252  stream << samplingFrequency;
253  stream << imagingMode;
254  stream << postScanMode;
255  stream << postScanHeight;
256  stream << postScanWidth;
257  stream << imageDepth;
258  stream << sector;
259  stream << activateMotor;
260  stream << motorPosition;
261  stream << framesPerVolume;
262  stream << stepsPerFrame;
263  stream << transmitFrequencyMin;
264  stream << samplingFrequencyMin;
265  stream << imagingModeMin;
266  stream << imageDepthMin;
267  stream << sectorMin;
268  stream << motorPositionMin;
269  stream << framesPerVolumeMin;
270  stream << stepsPerFrameMin;
271  stream << transmitFrequencyMax;
272  stream << samplingFrequencyMax;
273  stream << imagingModeMax;
274  stream << imageDepthMax;
275  stream << sectorMax;
276  stream << motorPositionMax;
277  stream << framesPerVolumeMax;
278  stream << stepsPerFrameMax;
279 }
280 
286 void usVirtualServer::setSequencePath(const std::string sequencePath)
287 {
288 
289  if (vpIoTools::checkFilename(sequencePath)) { // xml file pointing on a sequence of 2d images (pre-scan or post-scan)
290 
291  m_sequencePath = sequencePath;
292 #ifdef VISP_HAVE_XML2
293  m_sequenceReaderPostScan.setSequenceFileName(sequencePath);
294  m_sequenceReaderPreScan.setSequenceFileName(sequencePath);
295  // try to open post-scan sequence
296  try {
297  uint64_t timestampTmp;
298  m_sequenceReaderPostScan.open(m_postScanImage2d, timestampTmp);
299  imageHeader.timeStamp = timestampTmp;
300  m_nextImageTimestamp = m_sequenceReaderPostScan.getSequenceTimestamps().at(imageHeader.frameCount + 1);
301  if (imageHeader.timeStamp ==
302  m_nextImageTimestamp) { // timestamps are supposed to be different for different frames
303  throw(vpException(vpException::fatalError), "usVirtualServer error : successives timestamps are equal !");
304  }
305  m_imageType = us::POSTSCAN_2D;
306  m_isMHDSequence = false;
307  } catch (...) {
308  // if we have an exception, it's not a post-scan image. So we try a pre-scan
309  try {
310  uint64_t timestampTmp;
311  m_sequenceReaderPreScan.open(m_preScanImage2d, timestampTmp);
312  imageHeader.timeStamp = timestampTmp;
313  m_nextImageTimestamp = m_sequenceReaderPreScan.getSequenceTimestamps().at(imageHeader.frameCount + 1);
314  if (imageHeader.timeStamp ==
315  m_nextImageTimestamp) { // timestamps are supposed to be different for different frames
316  throw(vpException(vpException::fatalError), "usVirtualServer error : successives timestamps are equal !");
317  }
318  invertRowsColsOnPreScan(); // to fit with ultrasonix grabbers (pre-scan image is inverted in porta SDK)
319  m_imageType = us::PRESCAN_2D;
320  m_isMHDSequence = false;
321  } catch (...) {
322  throw(vpException(vpException::badValue), "usVirtualServer error : trying to open a xml image sequence not "
323  "managed (neither pre-scan 2D nor post-scan 2D)or with no timestamp "
324  "associated");
325  }
326  }
327 #endif
328  }
329 
330  // case of a directory containing a sequence of mhd/raw images
331  else if (vpIoTools::checkDirectory(sequencePath) &&
332  usImageIo::getHeaderFormat(vpIoTools::getDirFiles(sequencePath).front()) == usImageIo::FORMAT_MHD) {
333  m_MHDSequenceReader.setSequenceDirectory(sequencePath);
334 
335  // at this point, we don't know the type of image contained in the sequence, we have to try them all
336  try {
337  uint64_t timestampTmp;
338  m_MHDSequenceReader.acquire(m_rfImage2d, timestampTmp);
339  imageHeader.timeStamp = timestampTmp;
340  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp();
341  if (imageHeader.timeStamp == m_nextImageTimestamp) // timestamps are supposed to be different for different frames
342  throw(vpException(vpException::fatalError), "usVirtualServer error : successives timestamps are equal !");
343  } catch (...) { // if we have an exception, it's not a RF 2D image. So we try a pre-scan 2D
344  try {
345  uint64_t timestampTmp;
346  m_MHDSequenceReader.acquire(m_preScanImage2d, timestampTmp);
347  imageHeader.timeStamp = timestampTmp;
348  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp();
349  if (imageHeader.timeStamp ==
350  m_nextImageTimestamp) // timestamps are supposed to be different for different frames
351  throw(vpException(vpException::fatalError), "usVirtualServer error : successives timestamps are equal !");
352 
353  invertRowsColsOnPreScan(); // to fit with ultrasonix grabbers (pre-scan image is inverted in porta SDK)
354  } catch (...) { // it's not a pre-scan 2D image...
355  try {
356  uint64_t timestampTmp;
357  m_MHDSequenceReader.acquire(m_postScanImage2d, timestampTmp);
358  imageHeader.timeStamp = timestampTmp;
359  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp();
360  if (imageHeader.timeStamp ==
361  m_nextImageTimestamp) // timestamps are supposed to be different for different frames
362  throw(vpException(vpException::fatalError), "usVirtualServer error : successives timestamps are equal !");
363  } catch (...) { // it's not a post-scan 2D image...
364  try {
365  m_timestamps.clear();
366  m_MHDSequenceReader.acquire(m_rfImage3d, m_timestamps);
367  imageHeader.timeStamp = m_timestamps.at(0);
368  m_nextImageTimestamp = m_timestamps.at(1);
369  if (imageHeader.timeStamp == m_nextImageTimestamp)
370  throw(vpException(vpException::fatalError), "usVirtualServer error : successives timestamps are equal !");
371  } catch (...) { // it's not a rf 3D image...
372  try {
373  m_timestamps.clear();
374  m_MHDSequenceReader.acquire(m_preScanImage3d, m_timestamps);
375  imageHeader.timeStamp = m_timestamps.at(0);
376  m_nextImageTimestamp = m_timestamps.at(1);
377  if (imageHeader.timeStamp == m_nextImageTimestamp)
378  throw(vpException(vpException::fatalError),
379  "usVirtualServer error : successives timestamps are equal !");
380 
381  m_preScanImage3d.getFrame(m_preScanImage2d, 0);
382  m_preScanImage2d.setImagePreScanSettings(m_preScanImage3d);
383  invertRowsColsOnPreScan(); // to fit with ultrasonix grabbers (pre-scan image is inverted in porta SDK)
384  } catch (...) { // it's not a valid type
385  throw(vpException(vpException::badValue), "usVirtualServer error : trying to open a mhd image sequence "
386  "not managed, or with no timestamps associated to sequence "
387  "frames !");
388  }
389  }
390  }
391  }
392  }
393  m_imageType = m_MHDSequenceReader.getImageType();
394  m_isMHDSequence = true;
395  } else {
396  throw(vpException(vpException::badValue, "usVirtualServer error : sequence path incorrect !"));
397  }
398 }
399 
403 void usVirtualServer::startSendingLoop()
404 {
405  if (m_isMHDSequence)
406  sendingLoopSequenceMHD();
407  else
408  sendingLoopSequenceXml();
409 }
410 
414 void usVirtualServer::sendingLoopSequenceXml()
415 {
416 #ifdef VISP_HAVE_XML2
417  bool endOfSequence = false;
418  while (m_serverIsSendingImages && !endOfSequence) {
419  // manage first frame sent (already aquired with open() method)
420  if (imageHeader.frameCount != 0) {
421  if (m_imageType == us::PRESCAN_2D) {
422  if (m_usePause) {
423  if (!m_pauseOn) {
424  uint64_t localTimestamp;
425  m_sequenceReaderPreScan.acquire(m_preScanImage2d, localTimestamp);
426  invertRowsColsOnPreScan(); // to fit with ultrasonix grabbers (pre-scan image is inverted in porta SDK)
427  imageHeader.timeStamp = localTimestamp + m_pauseDurationOffset;
428  if (m_sequenceReaderPreScan.getSequenceTimestamps().size() >
429  imageHeader.frameCount + 1 - m_pauseIndexOffset)
430  m_nextImageTimestamp =
431  m_sequenceReaderPreScan.getSequenceTimestamps().at(imageHeader.frameCount + 1 - m_pauseIndexOffset) +
432  m_pauseDurationOffset;
433  imageHeader.imageType = 0;
434  } else { // pause activated, we continue sending the same image, and increasing timestamps
435  uint64_t deltaT = m_nextImageTimestamp - imageHeader.timeStamp;
436  m_nextImageTimestamp += deltaT;
437  imageHeader.timeStamp += deltaT;
438  m_pauseDurationOffset += deltaT;
439  m_pauseIndexOffset++;
440  }
441 
442  if (imageHeader.frameCount == m_pauseImageNumber)
443  m_pauseOn = true;
444  } else {
445  uint64_t localTimestamp;
446  m_sequenceReaderPreScan.acquire(m_preScanImage2d, localTimestamp);
447  invertRowsColsOnPreScan(); // to fit with ultrasonix grabbers (pre-scan image is inverted in porta SDK)
448  imageHeader.timeStamp = localTimestamp;
449  if (m_sequenceReaderPreScan.getSequenceTimestamps().size() > imageHeader.frameCount + 1)
450  m_nextImageTimestamp = m_sequenceReaderPreScan.getSequenceTimestamps().at(imageHeader.frameCount + 1);
451  imageHeader.imageType = 0;
452  }
453  } else if (m_imageType == us::POSTSCAN_2D) {
454  if (m_usePause) {
455  if (!m_pauseOn) {
456  uint64_t localTimestamp;
457  m_sequenceReaderPreScan.acquire(m_preScanImage2d, localTimestamp);
458  invertRowsColsOnPreScan(); // to fit with ultrasonix grabbers (pre-scan image is inverted in porta SDK)
459  imageHeader.timeStamp = localTimestamp;
460  if (m_sequenceReaderPreScan.getSequenceTimestamps().size() >
461  imageHeader.frameCount + 1 - m_pauseIndexOffset)
462  m_nextImageTimestamp =
463  m_sequenceReaderPreScan.getSequenceTimestamps().at(imageHeader.frameCount + 1 - m_pauseIndexOffset);
464  imageHeader.imageType = 1;
465  } else { // pause activated, we continue sending the same image, and increasing timestamps
466  uint64_t deltaT = m_nextImageTimestamp - imageHeader.timeStamp;
467  m_nextImageTimestamp += deltaT;
468  imageHeader.timeStamp += deltaT;
469  m_pauseDurationOffset += deltaT;
470  m_pauseIndexOffset++;
471  }
472 
473  if (imageHeader.frameCount == m_pauseImageNumber)
474  m_pauseOn = true;
475  } else {
476  uint64_t localTimestamp;
477  m_sequenceReaderPostScan.acquire(m_postScanImage2d, localTimestamp);
478  imageHeader.timeStamp = localTimestamp;
479  if (m_sequenceReaderPostScan.getSequenceTimestamps().size() > imageHeader.frameCount + 1)
480  m_nextImageTimestamp = m_sequenceReaderPostScan.getSequenceTimestamps().at(imageHeader.frameCount + 1);
481  imageHeader.imageType = 1;
482  }
483  }
484  } else { // first image
485  if (m_usePause && imageHeader.frameCount == m_pauseImageNumber)
486  m_pauseOn = true;
487 
488  if (m_usePause && m_pauseOn) {
489  uint64_t deltaT = 40; // if we pause on first image, we set the pause time to 40ms
490  m_nextImageTimestamp += deltaT;
491  imageHeader.timeStamp += deltaT;
492  m_pauseDurationOffset += deltaT;
493  if (imageHeader.frameCount != 0) // manage first case
494  m_pauseIndexOffset++;
495  }
496  }
497 
498  imageHeader.dataRate = 1000.0 / (m_nextImageTimestamp - imageHeader.timeStamp);
499 
500  QByteArray block;
501  QDataStream out(&block, QIODevice::WriteOnly);
502 #if defined(USTK_HAVE_VTK_QT4)
503  out.setVersion(QDataStream::Qt_4_8);
504 #else
505  out.setVersion(QDataStream::Qt_5_0);
506 #endif
507  out << imageHeader.headerId;
508  out << imageHeader.frameCount;
509  out << imageHeader.timeStamp;
510  out << imageHeader.dataRate;
511 
512  if (m_imageType == us::PRESCAN_2D) { // send pre-scan image
513  out << (int)m_preScanImage2d.getHeight() * m_preScanImage2d.getWidth(); // datalength in bytes
514  out << (int)8; // sample size in bits
515  out << (int)0;
516  out << m_preScanImage2d.getHeight();
517  out << m_preScanImage2d.getWidth();
518  out << (double).0; // pixelWidth
519  out << (double).0; // pixelHeight
520  out << m_preScanImage2d.getTransmitFrequency();
521  out << m_preScanImage2d.getSamplingFrequency();
522  out << m_preScanImage2d.getTransducerRadius();
523  out << m_preScanImage2d.getScanLinePitch();
524  out << (int)m_preScanImage2d.getScanLineNumber();
525  out << (int)(m_postScanImage2d.getDepth() / 1000.0); // int in mm
526  out << (double).0; // degPerFrame
527  out << (int)0; // framesPerVolume
528  out << (double).0; // motorRadius
529  out << (int)0; // motorType
530  out.writeRawData((char *)m_preScanImage2d.bitmap,
531  (int)m_preScanImage2d.getHeight() * m_preScanImage2d.getWidth());
532 
533  endOfSequence = (m_sequenceReaderPreScan.getFrameCount() == imageHeader.frameCount + 1 - m_pauseIndexOffset);
534  } else if (m_imageType == us::POSTSCAN_2D) { // send post-scan image
535  out << (int)m_postScanImage2d.getHeight() * m_postScanImage2d.getWidth(); // datalength in bytes
536  out << (int)8; // sample size in bits
537  out << (int)1;
538  out << m_postScanImage2d.getWidth();
539  out << m_postScanImage2d.getHeight();
540  out << m_postScanImage2d.getWidthResolution(); // pixelWidth
541  out << m_postScanImage2d.getHeightResolution(); // pixelHeight
542  out << m_postScanImage2d.getTransmitFrequency();
543  out << m_postScanImage2d.getSamplingFrequency();
544  out << m_postScanImage2d.getTransducerRadius();
545  out << m_postScanImage2d.getScanLinePitch();
546  out << (int)m_postScanImage2d.getScanLineNumber();
547  out << (int)(m_postScanImage2d.getDepth() / 1000.0); // int in mm
548  out << (double).0; // degPerFrame
549  out << (int)0; // framesPerVolume
550  out << (double).0; // motorRadius
551  out << (int)0; // motorType
552  out.writeRawData((char *)m_postScanImage2d.bitmap,
553  (int)m_postScanImage2d.getHeight() * m_postScanImage2d.getWidth());
554 
555  endOfSequence = (m_sequenceReaderPostScan.getFrameCount() == imageHeader.frameCount + 1 - m_pauseIndexOffset);
556  }
557 
558  connectionSoc->write(block);
559  qApp->processEvents();
560 
561  std::cout << "new frame sent, No " << imageHeader.frameCount << std::endl;
562 
563  imageHeader.frameCount++;
564  // WAITING PROCESS (to respect sequence timestamps)
565  vpTime::wait((double)(m_nextImageTimestamp - imageHeader.timeStamp));
566  }
567 #else
568  throw(vpException(vpException::badValue),
569  "usVirtualServer error : cannot use xml sequence, xml2 dependency is missing !");
570 #endif
571 }
572 
576 void usVirtualServer::sendingLoopSequenceMHD()
577 {
578  bool endOfSequence = false;
579  while (m_serverIsSendingImages && !endOfSequence) {
580  // manage first frame sent (already aquired with open() method)
581  if (imageHeader.frameCount != 0) {
582  if (m_imageType == us::RF_2D) {
583  if (m_usePause) {
584  if (!m_pauseOn) {
585  if (m_useRewind) {
586  // counting the number of total sequence sent
587  unsigned int currentNumberOfWholeSequenceSent = 0;
588  if (imageHeader.frameCount - m_pauseIndexOffset >=
589  (unsigned int)m_MHDSequenceReader.getTotalImageNumber()) {
590  currentNumberOfWholeSequenceSent =
591  ((imageHeader.frameCount - m_pauseIndexOffset - m_MHDSequenceReader.getTotalImageNumber()) /
592  (m_MHDSequenceReader.getTotalImageNumber() - 1)) +
593  1;
594  }
595  if (currentNumberOfWholeSequenceSent == 0) { // sending first sequence
596  int imageIndex =
597  (imageHeader.frameCount - m_pauseIndexOffset) % (m_MHDSequenceReader.getTotalImageNumber());
598 
599  uint64_t localTimestamp;
600  m_MHDSequenceReader.acquire(m_rfImage2d, localTimestamp);
601  imageHeader.timeStamp = localTimestamp;
602  if (imageIndex != m_MHDSequenceReader.getTotalImageNumber() - 1) {
603  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp();
604  } else { // next timestamp is the previous image, so we compute the abs diff between 2 timpestamps
605  // first we get the timestamp of the previous image
606  usImageRF2D<short int> tmpImg;
607  uint64_t tmpTimpstamp;
608  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, tmpTimpstamp);
609  // then we compute the delta
610  m_nextImageTimestamp = (imageHeader.timeStamp - tmpTimpstamp) + imageHeader.timeStamp;
611  }
612  imageHeader.imageType = 2;
613 
614  } else if (currentNumberOfWholeSequenceSent % 2 == 0) {
615  int imageIndex =
616  (imageHeader.frameCount - m_pauseIndexOffset - m_MHDSequenceReader.getTotalImageNumber()) %
617  (m_MHDSequenceReader.getTotalImageNumber() - 1) +
618  1;
619 
620  // current real timestamp
621  uint64_t localTimestamp;
622  m_MHDSequenceReader.getImage(imageIndex, m_rfImage2d, localTimestamp);
623  // offset (increment because of rewind)
624  uint64_t previousTimestamp;
625  usImageRF2D<short int> tmpImg;
626  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, previousTimestamp);
627  uint64_t deltaTimestamp = localTimestamp - previousTimestamp;
628  imageHeader.timeStamp += deltaTimestamp;
629 
630  // next timestamp (for waiting process)
631  uint64_t nextTimestamp;
632  uint64_t deltaTimestampNext;
633  if (imageIndex != m_MHDSequenceReader.getTotalImageNumber() - 1) {
634  usImageRF2D<short int> tmpImg;
635  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, nextTimestamp);
636  deltaTimestampNext = nextTimestamp - localTimestamp;
637  } else {
638  usImageRF2D<short int> tmpImg;
639  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, nextTimestamp);
640  deltaTimestampNext = localTimestamp - nextTimestamp;
641  }
642  m_nextImageTimestamp += deltaTimestampNext;
643 
644  imageHeader.imageType = 2;
645  } else {
646  int imageIndex =
647  m_MHDSequenceReader.getTotalImageNumber() - 2 -
648  ((imageHeader.frameCount - m_pauseIndexOffset - m_MHDSequenceReader.getTotalImageNumber()) %
649  (m_MHDSequenceReader.getTotalImageNumber() - 1));
650 
651  // current real timestamp
652  uint64_t localTimestamp;
653  m_MHDSequenceReader.getImage(imageIndex, m_rfImage2d, localTimestamp);
654  // offset (increment because of rewind)
655  uint64_t previousTimestamp;
656  usImageRF2D<short int> tmpImg;
657  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, previousTimestamp);
658  uint64_t deltaTimestamp = previousTimestamp - localTimestamp;
659  imageHeader.timeStamp += deltaTimestamp;
660 
661  // next timestamp (for waiting process)
662  uint64_t nextTimestamp;
663  uint64_t deltaTimestampNext;
664  if (imageIndex != 0) {
665  usImageRF2D<short int> tmpImg;
666  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, nextTimestamp);
667  deltaTimestampNext = localTimestamp - nextTimestamp;
668  } else {
669  usImageRF2D<short int> tmpImg;
670  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, nextTimestamp);
671  deltaTimestampNext = nextTimestamp - localTimestamp;
672  }
673  m_nextImageTimestamp += deltaTimestampNext;
674  imageHeader.imageType = 2;
675  }
676  } else {
677  uint64_t localTimestamp;
678  m_MHDSequenceReader.acquire(m_rfImage2d, localTimestamp);
679  imageHeader.timeStamp = localTimestamp + m_pauseDurationOffset;
680  if (!m_MHDSequenceReader.end())
681  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp() + m_pauseDurationOffset;
682  imageHeader.imageType = 2;
683  }
684  } else { // pause activated, we continue sending the same image, and increasing timestamps
685  uint64_t deltaT = m_nextImageTimestamp - imageHeader.timeStamp;
686  m_nextImageTimestamp += deltaT;
687  imageHeader.timeStamp += deltaT;
688  m_pauseDurationOffset += deltaT;
689  m_pauseIndexOffset++;
690  }
691 
692  if (imageHeader.frameCount == m_pauseImageNumber)
693  m_pauseOn = true;
694  } else if (m_useRewind) {
695  // counting the number of total sequence sent
696  unsigned int currentNumberOfWholeSequenceSent = 0;
697  if (imageHeader.frameCount >= (unsigned int)m_MHDSequenceReader.getTotalImageNumber()) {
698  currentNumberOfWholeSequenceSent = ((imageHeader.frameCount - m_MHDSequenceReader.getTotalImageNumber()) /
699  (m_MHDSequenceReader.getTotalImageNumber() - 1)) +
700  1;
701  }
702  if (currentNumberOfWholeSequenceSent == 0) { // sending first sequence
703  int imageIndex = (imageHeader.frameCount % (m_MHDSequenceReader.getTotalImageNumber()));
704 
705  uint64_t localTimestamp;
706  m_MHDSequenceReader.acquire(m_rfImage2d, localTimestamp);
707  imageHeader.timeStamp = localTimestamp;
708  if (imageIndex != m_MHDSequenceReader.getTotalImageNumber() - 1) {
709  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp();
710  } else { // next timestamp is the previous image, so we compute the abs diff between 2 timpestamps
711  // first we get the timestamp of the previous image
712  usImageRF2D<short int> tmpImg;
713  uint64_t tmpTimpstamp;
714  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, tmpTimpstamp);
715  // then we compute the delta
716  m_nextImageTimestamp = (imageHeader.timeStamp - tmpTimpstamp) + imageHeader.timeStamp;
717  }
718  imageHeader.imageType = 2;
719 
720  } else if (currentNumberOfWholeSequenceSent % 2 == 0) {
721  int imageIndex = (imageHeader.frameCount - m_MHDSequenceReader.getTotalImageNumber()) %
722  (m_MHDSequenceReader.getTotalImageNumber() - 1) +
723  1;
724 
725  // current real timestamp
726  uint64_t localTimestamp;
727  m_MHDSequenceReader.getImage(imageIndex, m_rfImage2d, localTimestamp);
728  // offset (increment because of rewind)
729  uint64_t previousTimestamp;
730  usImageRF2D<short int> tmpImg;
731  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, previousTimestamp);
732  uint64_t deltaTimestamp = localTimestamp - previousTimestamp;
733  imageHeader.timeStamp += deltaTimestamp;
734 
735  // next timestamp (for waiting process)
736  uint64_t nextTimestamp;
737  uint64_t deltaTimestampNext;
738  if (imageIndex != m_MHDSequenceReader.getTotalImageNumber() - 1) {
739  usImageRF2D<short int> tmpImg;
740  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, nextTimestamp);
741  deltaTimestampNext = nextTimestamp - localTimestamp;
742  } else {
743  usImageRF2D<short int> tmpImg;
744  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, nextTimestamp);
745  deltaTimestampNext = localTimestamp - nextTimestamp;
746  }
747  m_nextImageTimestamp += deltaTimestampNext;
748 
749  imageHeader.imageType = 2;
750  } else {
751  int imageIndex = m_MHDSequenceReader.getTotalImageNumber() - 2 -
752  ((imageHeader.frameCount - m_MHDSequenceReader.getTotalImageNumber()) %
753  (m_MHDSequenceReader.getTotalImageNumber() - 1));
754 
755  // current real timestamp
756  uint64_t localTimestamp;
757  m_MHDSequenceReader.getImage(imageIndex, m_rfImage2d, localTimestamp);
758  // offset (increment because of rewind)
759  uint64_t previousTimestamp;
760  usImageRF2D<short int> tmpImg;
761  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, previousTimestamp);
762  uint64_t deltaTimestamp = previousTimestamp - localTimestamp;
763  imageHeader.timeStamp += deltaTimestamp;
764 
765  // next timestamp (for waiting process)
766  uint64_t nextTimestamp;
767  uint64_t deltaTimestampNext;
768  if (imageIndex != 0) {
769  usImageRF2D<short int> tmpImg;
770  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, nextTimestamp);
771  deltaTimestampNext = localTimestamp - nextTimestamp;
772  } else {
773  usImageRF2D<short int> tmpImg;
774  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, nextTimestamp);
775  deltaTimestampNext = nextTimestamp - localTimestamp;
776  }
777  m_nextImageTimestamp += deltaTimestampNext;
778  imageHeader.imageType = 2;
779  }
780  } else {
781  uint64_t localTimestamp;
782  m_MHDSequenceReader.acquire(m_rfImage2d, localTimestamp);
783  imageHeader.timeStamp = localTimestamp;
784  if (!m_MHDSequenceReader.end())
785  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp();
786  imageHeader.imageType = 2;
787  }
788  } else if (m_imageType == us::PRESCAN_2D) {
789  if (m_usePause) {
790  if (!m_pauseOn) {
791  if (m_useRewind) {
792  // counting the number of total sequence sent
793  unsigned int currentNumberOfWholeSequenceSent = 0;
794  if (imageHeader.frameCount - m_pauseIndexOffset >=
795  (unsigned int)m_MHDSequenceReader.getTotalImageNumber()) {
796  currentNumberOfWholeSequenceSent =
797  ((imageHeader.frameCount - m_pauseIndexOffset - m_MHDSequenceReader.getTotalImageNumber()) /
798  (m_MHDSequenceReader.getTotalImageNumber() - 1)) +
799  1;
800  }
801  if (currentNumberOfWholeSequenceSent == 0) { // sending first sequence
802  int imageIndex =
803  (imageHeader.frameCount - m_pauseIndexOffset) % (m_MHDSequenceReader.getTotalImageNumber());
804 
805  uint64_t localTimestamp;
806  m_MHDSequenceReader.acquire(m_preScanImage2d, localTimestamp);
807  invertRowsColsOnPreScan(); // to fit with ultrasonix grabbers (pre-scan image is inverted in porta SDK)
808  imageHeader.timeStamp = localTimestamp;
809  if (imageIndex != m_MHDSequenceReader.getTotalImageNumber() - 1) {
810  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp();
811  } else { // next timestamp is the previous image, so we compute the abs diff between 2 timpestamps
812  // first we get the timestamp of the previous image
814  uint64_t tmpTimpstamp;
815  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, tmpTimpstamp);
816  // then we compute the delta
817  m_nextImageTimestamp = (imageHeader.timeStamp - tmpTimpstamp) + imageHeader.timeStamp;
818  }
819  imageHeader.imageType = 0;
820 
821  } else if (currentNumberOfWholeSequenceSent % 2 == 0) { // sequence currently sent : from image 1 to N-1
822  int imageIndex =
823  (imageHeader.frameCount - m_pauseIndexOffset - m_MHDSequenceReader.getTotalImageNumber()) %
824  (m_MHDSequenceReader.getTotalImageNumber() - 1) +
825  1;
826 
827  // current real timestamp
828  uint64_t localTimestamp;
829  m_MHDSequenceReader.getImage(imageIndex, m_preScanImage2d, localTimestamp);
830  invertRowsColsOnPreScan(); // to fit with ultrasonix grabbers (pre-scan image is inverted in porta SDK)
831  // offset (increment because of rewind)
832  uint64_t previousTimestamp;
834  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, previousTimestamp);
835  uint64_t deltaTimestamp = localTimestamp - previousTimestamp;
836  imageHeader.timeStamp += deltaTimestamp;
837 
838  // next timestamp (for waiting process)
839  uint64_t nextTimestamp;
840  uint64_t deltaTimestampNext;
841  if (imageIndex != m_MHDSequenceReader.getTotalImageNumber() - 1) {
843  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, nextTimestamp);
844  deltaTimestampNext = nextTimestamp - localTimestamp;
845  } else {
847  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, nextTimestamp);
848  deltaTimestampNext = localTimestamp - nextTimestamp;
849  }
850  m_nextImageTimestamp += deltaTimestampNext;
851 
852  imageHeader.imageType = 0;
853  } else { // sequence currently sent : from image N-2 to 0
854  int imageIndex =
855  m_MHDSequenceReader.getTotalImageNumber() - 2 -
856  ((imageHeader.frameCount - m_pauseIndexOffset - m_MHDSequenceReader.getTotalImageNumber()) %
857  (m_MHDSequenceReader.getTotalImageNumber() - 1));
858 
859  // current real timestamp
860  uint64_t localTimestamp;
861  m_MHDSequenceReader.getImage(imageIndex, m_preScanImage2d, localTimestamp);
862  invertRowsColsOnPreScan(); // to fit with ultrasonix grabbers (pre-scan image is inverted in porta SDK)
863  // offset (increment because of rewind)
864  uint64_t previousTimestamp;
866  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, previousTimestamp);
867  uint64_t deltaTimestamp = previousTimestamp - localTimestamp;
868  imageHeader.timeStamp += deltaTimestamp;
869 
870  // next timestamp (for waiting process)
871  uint64_t nextTimestamp;
872  uint64_t deltaTimestampNext;
873  if (imageIndex != 0) {
875  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, nextTimestamp);
876  deltaTimestampNext = localTimestamp - nextTimestamp;
877  } else {
879  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, nextTimestamp);
880  deltaTimestampNext = nextTimestamp - localTimestamp;
881  }
882  m_nextImageTimestamp += deltaTimestampNext;
883  imageHeader.imageType = 0;
884  }
885  } else {
886  uint64_t localTimestamp;
887  m_MHDSequenceReader.acquire(m_preScanImage2d, localTimestamp);
888  invertRowsColsOnPreScan(); // to fit with ultrasonix grabbers (pre-scan image is inverted in porta SDK)
889  imageHeader.timeStamp = localTimestamp + m_pauseDurationOffset;
890  if (!m_MHDSequenceReader.end())
891  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp() + m_pauseDurationOffset;
892  imageHeader.imageType = 0;
893  }
894  } else { // pause activated, we continue sending the same image, and increasing timestamps
895  uint64_t deltaT = m_nextImageTimestamp - imageHeader.timeStamp;
896  m_nextImageTimestamp += deltaT;
897  imageHeader.timeStamp += deltaT;
898  m_pauseDurationOffset += deltaT;
899  m_pauseIndexOffset++;
900  }
901 
902  if (imageHeader.frameCount == m_pauseImageNumber)
903  m_pauseOn = true;
904  } else if (m_useRewind) {
905  // counting the number of total sequence sent
906  unsigned int currentNumberOfWholeSequenceSent = 0;
907  if (imageHeader.frameCount >= (unsigned int)m_MHDSequenceReader.getTotalImageNumber()) {
908  currentNumberOfWholeSequenceSent = ((imageHeader.frameCount - m_MHDSequenceReader.getTotalImageNumber()) /
909  (m_MHDSequenceReader.getTotalImageNumber() - 1)) +
910  1;
911  }
912  if (currentNumberOfWholeSequenceSent == 0) { // sending first sequence
913  int imageIndex = (imageHeader.frameCount % (m_MHDSequenceReader.getTotalImageNumber()));
914 
915  uint64_t localTimestamp;
916  m_MHDSequenceReader.acquire(m_preScanImage2d, localTimestamp);
917  invertRowsColsOnPreScan(); // to fit with ultrasonix grabbers (pre-scan image is inverted in porta SDK)
918  imageHeader.timeStamp = localTimestamp;
919  if (imageIndex != m_MHDSequenceReader.getTotalImageNumber() - 1) {
920  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp();
921  } else { // next timestamp is the previous image, so we compute the abs diff between 2 timpestamps
922  // first we get the timestamp of the previous image
924  uint64_t tmpTimpstamp;
925  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, tmpTimpstamp);
926  // then we compute the delta
927  m_nextImageTimestamp = (imageHeader.timeStamp - tmpTimpstamp) + imageHeader.timeStamp;
928  }
929  imageHeader.imageType = 0;
930 
931  } else if (currentNumberOfWholeSequenceSent % 2 == 0) {
932  int imageIndex = (imageHeader.frameCount - m_MHDSequenceReader.getTotalImageNumber()) %
933  (m_MHDSequenceReader.getTotalImageNumber() - 1) +
934  1;
935 
936  // current real timestamp
937  uint64_t localTimestamp;
938  m_MHDSequenceReader.getImage(imageIndex, m_preScanImage2d, localTimestamp);
939  invertRowsColsOnPreScan(); // to fit with ultrasonix grabbers (pre-scan image is inverted in porta SDK)
940  // offset (increment because of rewind)
941  uint64_t previousTimestamp;
943  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, previousTimestamp);
944  uint64_t deltaTimestamp = localTimestamp - previousTimestamp;
945  imageHeader.timeStamp += deltaTimestamp;
946 
947  // next timestamp (for waiting process)
948  uint64_t nextTimestamp;
949  uint64_t deltaTimestampNext;
950  if (imageIndex != m_MHDSequenceReader.getTotalImageNumber() - 1) {
952  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, nextTimestamp);
953  deltaTimestampNext = nextTimestamp - localTimestamp;
954  } else {
956  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, nextTimestamp);
957  deltaTimestampNext = localTimestamp - nextTimestamp;
958  }
959  m_nextImageTimestamp += deltaTimestampNext;
960 
961  imageHeader.imageType = 0;
962  } else {
963  int imageIndex = m_MHDSequenceReader.getTotalImageNumber() - 2 -
964  ((imageHeader.frameCount - m_MHDSequenceReader.getTotalImageNumber()) %
965  (m_MHDSequenceReader.getTotalImageNumber() - 1));
966 
967  // current real timestamp
968  uint64_t localTimestamp;
969  m_MHDSequenceReader.getImage(imageIndex, m_preScanImage2d, localTimestamp);
970  invertRowsColsOnPreScan(); // to fit with ultrasonix grabbers (pre-scan image is inverted in porta SDK)
971  // offset (increment because of rewind)
972  uint64_t previousTimestamp;
974  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, previousTimestamp);
975  uint64_t deltaTimestamp = previousTimestamp - localTimestamp;
976  imageHeader.timeStamp += deltaTimestamp;
977 
978  // next timestamp (for waiting process)
979  uint64_t nextTimestamp;
980  uint64_t deltaTimestampNext;
981  if (imageIndex != 0) {
983  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, nextTimestamp);
984  deltaTimestampNext = localTimestamp - nextTimestamp;
985  } else {
987  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, nextTimestamp);
988  deltaTimestampNext = nextTimestamp - localTimestamp;
989  }
990  m_nextImageTimestamp += deltaTimestampNext;
991  imageHeader.imageType = 0;
992  }
993  } else {
994  uint64_t localTimestamp;
995  m_MHDSequenceReader.acquire(m_preScanImage2d, localTimestamp);
996  invertRowsColsOnPreScan(); // to fit with ultrasonix grabbers (pre-scan image is inverted in porta SDK)
997  imageHeader.timeStamp = localTimestamp;
998  if (!m_MHDSequenceReader.end())
999  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp();
1000  imageHeader.imageType = 0;
1001  }
1002  } else if (m_imageType == us::POSTSCAN_2D) {
1003  if (m_usePause) {
1004  if (!m_pauseOn) {
1005  if (m_useRewind) {
1006  // counting the number of total sequence sent
1007  unsigned int currentNumberOfWholeSequenceSent = 0;
1008  if (imageHeader.frameCount - m_pauseIndexOffset >=
1009  (unsigned int)m_MHDSequenceReader.getTotalImageNumber()) {
1010  currentNumberOfWholeSequenceSent =
1011  ((imageHeader.frameCount - m_pauseIndexOffset - m_MHDSequenceReader.getTotalImageNumber()) /
1012  (m_MHDSequenceReader.getTotalImageNumber() - 1)) +
1013  1;
1014  }
1015  if (currentNumberOfWholeSequenceSent == 0) { // sending first sequence
1016  int imageIndex =
1017  (imageHeader.frameCount - m_pauseIndexOffset) % (m_MHDSequenceReader.getTotalImageNumber());
1018 
1019  uint64_t localTimestamp;
1020  m_MHDSequenceReader.acquire(m_postScanImage2d, localTimestamp);
1021  imageHeader.timeStamp = localTimestamp;
1022  if (imageIndex != m_MHDSequenceReader.getTotalImageNumber() - 1) {
1023  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp();
1024  } else { // next timestamp is the previous image, so we compute the abs diff between 2 timpestamps
1025  // first we get the timestamp of the previous image
1027  uint64_t tmpTimpstamp;
1028  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, tmpTimpstamp);
1029  // then we compute the delta
1030  m_nextImageTimestamp = (imageHeader.timeStamp - tmpTimpstamp) + imageHeader.timeStamp;
1031  }
1032  imageHeader.imageType = 1;
1033 
1034  } else if (currentNumberOfWholeSequenceSent % 2 == 0) {
1035  int imageIndex =
1036  (imageHeader.frameCount - m_pauseIndexOffset - m_MHDSequenceReader.getTotalImageNumber()) %
1037  (m_MHDSequenceReader.getTotalImageNumber() - 1) +
1038  1;
1039 
1040  // current real timestamp
1041  uint64_t localTimestamp;
1042  m_MHDSequenceReader.getImage(imageIndex, m_postScanImage2d, localTimestamp);
1043  // offset (increment because of rewind)
1044  uint64_t previousTimestamp;
1046  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, previousTimestamp);
1047  uint64_t deltaTimestamp = localTimestamp - previousTimestamp;
1048  imageHeader.timeStamp += deltaTimestamp;
1049 
1050  // next timestamp (for waiting process)
1051  uint64_t nextTimestamp;
1052  uint64_t deltaTimestampNext;
1053  if (imageIndex != m_MHDSequenceReader.getTotalImageNumber() - 1) {
1055  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, nextTimestamp);
1056  deltaTimestampNext = nextTimestamp - localTimestamp;
1057  } else {
1059  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, nextTimestamp);
1060  deltaTimestampNext = localTimestamp - nextTimestamp;
1061  }
1062  m_nextImageTimestamp += deltaTimestampNext;
1063 
1064  imageHeader.imageType = 1;
1065  } else {
1066  int imageIndex =
1067  m_MHDSequenceReader.getTotalImageNumber() - 2 -
1068  ((imageHeader.frameCount - m_pauseIndexOffset - m_MHDSequenceReader.getTotalImageNumber()) %
1069  (m_MHDSequenceReader.getTotalImageNumber() - 1));
1070 
1071  // current real timestamp
1072  uint64_t localTimestamp;
1073  m_MHDSequenceReader.getImage(imageIndex, m_postScanImage2d, localTimestamp);
1074  // offset (increment because of rewind)
1075  uint64_t previousTimestamp;
1077  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, previousTimestamp);
1078  uint64_t deltaTimestamp = previousTimestamp - localTimestamp;
1079  imageHeader.timeStamp += deltaTimestamp;
1080 
1081  // next timestamp (for waiting process)
1082  uint64_t nextTimestamp;
1083  uint64_t deltaTimestampNext;
1084  if (imageIndex != 0) {
1086  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, nextTimestamp);
1087  deltaTimestampNext = localTimestamp - nextTimestamp;
1088  } else {
1090  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, nextTimestamp);
1091  deltaTimestampNext = nextTimestamp - localTimestamp;
1092  }
1093  m_nextImageTimestamp += deltaTimestampNext;
1094  imageHeader.imageType = 1;
1095  }
1096  } else {
1097  uint64_t localTimestamp;
1098  m_MHDSequenceReader.acquire(m_postScanImage2d, localTimestamp);
1099  imageHeader.timeStamp = localTimestamp + m_pauseDurationOffset;
1100  if (!m_MHDSequenceReader.end())
1101  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp() + m_pauseDurationOffset;
1102  imageHeader.imageType = 1;
1103  }
1104  } else { // pause activated, we continue sending the same image, and increasing timestamps
1105  uint64_t deltaT = m_nextImageTimestamp - imageHeader.timeStamp;
1106  m_nextImageTimestamp += deltaT;
1107  imageHeader.timeStamp += deltaT;
1108  m_pauseDurationOffset += deltaT;
1109  m_pauseIndexOffset++;
1110  }
1111 
1112  if (imageHeader.frameCount == m_pauseImageNumber)
1113  m_pauseOn = true;
1114  } else if (m_useRewind) {
1115  // counting the number of total sequence sent
1116  unsigned int currentNumberOfWholeSequenceSent = 0;
1117  if (imageHeader.frameCount >= (unsigned int)m_MHDSequenceReader.getTotalImageNumber()) {
1118  currentNumberOfWholeSequenceSent = ((imageHeader.frameCount - m_MHDSequenceReader.getTotalImageNumber()) /
1119  (m_MHDSequenceReader.getTotalImageNumber() - 1)) +
1120  1;
1121  }
1122  if (currentNumberOfWholeSequenceSent == 0) { // sending first sequence
1123  int imageIndex = (imageHeader.frameCount % (m_MHDSequenceReader.getTotalImageNumber()));
1124 
1125  uint64_t localTimestamp;
1126  m_MHDSequenceReader.acquire(m_postScanImage2d, localTimestamp);
1127  imageHeader.timeStamp = localTimestamp;
1128  if (imageIndex != m_MHDSequenceReader.getTotalImageNumber() - 1) {
1129  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp();
1130  } else { // next timestamp is the previous image, so we compute the abs diff between 2 timpestamps
1131  // first we get the timestamp of the previous image
1133  uint64_t tmpTimpstamp;
1134  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, tmpTimpstamp);
1135  // then we compute the delta
1136  m_nextImageTimestamp = (imageHeader.timeStamp - tmpTimpstamp) + imageHeader.timeStamp;
1137  }
1138  imageHeader.imageType = 1;
1139 
1140  } else if (currentNumberOfWholeSequenceSent % 2 == 0) {
1141  int imageIndex = (imageHeader.frameCount - m_MHDSequenceReader.getTotalImageNumber()) %
1142  (m_MHDSequenceReader.getTotalImageNumber() - 1) +
1143  1;
1144 
1145  // current real timestamp
1146  uint64_t localTimestamp;
1147  m_MHDSequenceReader.getImage(imageIndex, m_postScanImage2d, localTimestamp);
1148  // offset (increment because of rewind)
1149  uint64_t previousTimestamp;
1151  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, previousTimestamp);
1152  uint64_t deltaTimestamp = localTimestamp - previousTimestamp;
1153  imageHeader.timeStamp += deltaTimestamp;
1154 
1155  // next timestamp (for waiting process)
1156  uint64_t nextTimestamp;
1157  uint64_t deltaTimestampNext;
1158  if (imageIndex != m_MHDSequenceReader.getTotalImageNumber() - 1) {
1160  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, nextTimestamp);
1161  deltaTimestampNext = nextTimestamp - localTimestamp;
1162  } else {
1164  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, nextTimestamp);
1165  deltaTimestampNext = localTimestamp - nextTimestamp;
1166  }
1167  m_nextImageTimestamp += deltaTimestampNext;
1168 
1169  imageHeader.imageType = 1;
1170  } else {
1171  int imageIndex = m_MHDSequenceReader.getTotalImageNumber() - 2 -
1172  ((imageHeader.frameCount - m_MHDSequenceReader.getTotalImageNumber()) %
1173  (m_MHDSequenceReader.getTotalImageNumber() - 1));
1174 
1175  // current real timestamp
1176  uint64_t localTimestamp;
1177  m_MHDSequenceReader.getImage(imageIndex, m_postScanImage2d, localTimestamp);
1178  // offset (increment because of rewind)
1179  uint64_t previousTimestamp;
1181  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, previousTimestamp);
1182  uint64_t deltaTimestamp = previousTimestamp - localTimestamp;
1183  imageHeader.timeStamp += deltaTimestamp;
1184 
1185  // next timestamp (for waiting process)
1186  uint64_t nextTimestamp;
1187  uint64_t deltaTimestampNext;
1188  if (imageIndex != 0) {
1190  m_MHDSequenceReader.getImage(imageIndex - 1, tmpImg, nextTimestamp);
1191  deltaTimestampNext = localTimestamp - nextTimestamp;
1192  } else {
1194  m_MHDSequenceReader.getImage(imageIndex + 1, tmpImg, nextTimestamp);
1195  deltaTimestampNext = nextTimestamp - localTimestamp;
1196  }
1197  m_nextImageTimestamp += deltaTimestampNext;
1198  imageHeader.imageType = 1;
1199  }
1200  } else {
1201  uint64_t localTimestamp;
1202  m_MHDSequenceReader.acquire(m_postScanImage2d, localTimestamp);
1203  imageHeader.timeStamp = localTimestamp;
1204  if (!m_MHDSequenceReader.end())
1205  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamp();
1206  imageHeader.imageType = 1;
1207  }
1208  } else if (m_imageType == us::RF_3D) {
1209  if (m_usePause) {
1210  if (!m_pauseOn) {
1211  if (m_useRewind) {
1212  // counting the number of total sequence sent
1213  unsigned int currentNumberOfWholeSequenceSent = 0;
1214 
1215  if (imageHeader.frameCount - m_pauseIndexOffset >=
1216  (unsigned int)m_MHDSequenceReader.getTotalImageNumber() * m_rfImage3d.getFrameNumber()) {
1217  currentNumberOfWholeSequenceSent =
1218  ((imageHeader.frameCount - m_pauseIndexOffset -
1219  (m_MHDSequenceReader.getTotalImageNumber() * m_rfImage3d.getFrameNumber())) /
1220  ((m_MHDSequenceReader.getTotalImageNumber() - 1) * m_rfImage3d.getFrameNumber())) +
1221  1;
1222  }
1223 
1224  if (currentNumberOfWholeSequenceSent == 0) { // sending first sequence
1225  int volumeIndex = ((imageHeader.frameCount - m_pauseIndexOffset) / m_rfImage3d.getFrameNumber());
1226 
1227  m_MHDSequenceReader.getImage(volumeIndex, m_rfImage3d, m_timestamps);
1228  imageHeader.timeStamp = m_timestamps.at(0);
1229  m_nextImageTimestamp = m_timestamps.at(1);
1230  imageHeader.imageType = 2;
1231 
1232  } else if (currentNumberOfWholeSequenceSent % 2 == 0) {
1233  int volumeIndex = (((imageHeader.frameCount - m_pauseIndexOffset -
1234  (m_MHDSequenceReader.getTotalImageNumber() * m_rfImage3d.getFrameNumber())) /
1235  m_rfImage3d.getFrameNumber()) %
1236  (m_MHDSequenceReader.getTotalImageNumber() - 1)) +
1237  1;
1238 
1239  m_MHDSequenceReader.getImage(volumeIndex, m_rfImage3d, m_timestamps);
1240  imageHeader.imageType = 2;
1241  } else {
1242  int volumeIndex = m_MHDSequenceReader.getTotalImageNumber() - 2 -
1243  ((imageHeader.frameCount - m_pauseIndexOffset -
1244  (m_MHDSequenceReader.getTotalImageNumber() * m_rfImage3d.getFrameNumber())) /
1245  m_rfImage3d.getFrameNumber()) %
1246  (m_MHDSequenceReader.getTotalImageNumber() - 1);
1247 
1248  m_MHDSequenceReader.getImage(volumeIndex, m_rfImage3d, m_timestamps);
1249  imageHeader.imageType = 2;
1250  }
1251  } else {
1252  m_MHDSequenceReader.acquire(m_rfImage3d, m_timestamps);
1253  imageHeader.timeStamp = m_timestamps.at(0) + m_pauseDurationOffset;
1254  m_nextImageTimestamp = m_timestamps.at(1) + m_pauseDurationOffset;
1255  imageHeader.imageType = 2;
1256  }
1257  }
1258 
1259  if (imageHeader.frameCount / m_rfImage3d.getFrameNumber() == m_pauseImageNumber &&
1260  !m_pauseOn) { // we arrive on the volume to pause on
1261  m_MHDSequenceReader.acquire(m_rfImage3dTemp,
1262  m_timestampsTemp); // temp attributes contains next volume and timestamps
1263  m_pauseOn = true;
1264  }
1265  } else if (m_useRewind) {
1266  // counting the number of total sequence sent
1267  unsigned int currentNumberOfWholeSequenceSent = 0;
1268 
1269  if (imageHeader.frameCount >=
1270  (unsigned int)m_MHDSequenceReader.getTotalImageNumber() * m_rfImage3d.getFrameNumber()) {
1271  currentNumberOfWholeSequenceSent =
1272  ((imageHeader.frameCount - (m_MHDSequenceReader.getTotalImageNumber() * m_rfImage3d.getFrameNumber())) /
1273  ((m_MHDSequenceReader.getTotalImageNumber() - 1) * m_rfImage3d.getFrameNumber())) +
1274  1;
1275  }
1276 
1277  if (currentNumberOfWholeSequenceSent == 0) { // sending first sequence
1278 
1279  m_MHDSequenceReader.acquire(m_rfImage3d, m_timestamps);
1280  imageHeader.timeStamp = m_timestamps.at(0);
1281  m_nextImageTimestamp = m_timestamps.at(1);
1282  imageHeader.imageType = 2;
1283 
1284  } else if (currentNumberOfWholeSequenceSent % 2 == 0) {
1285  int volumeIndex = (((imageHeader.frameCount -
1286  (m_MHDSequenceReader.getTotalImageNumber() * m_rfImage3d.getFrameNumber())) /
1287  m_rfImage3d.getFrameNumber()) %
1288  (m_MHDSequenceReader.getTotalImageNumber() - 1)) +
1289  1;
1290 
1291  m_MHDSequenceReader.getImage(volumeIndex, m_rfImage3d, m_timestamps);
1292  imageHeader.imageType = 2;
1293  } else {
1294  int volumeIndex =
1295  m_MHDSequenceReader.getTotalImageNumber() - 2 -
1296  ((imageHeader.frameCount - (m_MHDSequenceReader.getTotalImageNumber() * m_rfImage3d.getFrameNumber())) /
1297  m_rfImage3d.getFrameNumber()) %
1298  (m_MHDSequenceReader.getTotalImageNumber() - 1);
1299 
1300  m_MHDSequenceReader.getImage(volumeIndex, m_rfImage3d, m_timestamps);
1301  imageHeader.imageType = 2;
1302  }
1303  } else {
1304  m_MHDSequenceReader.acquire(m_rfImage3d, m_timestamps);
1305  imageHeader.timeStamp = m_timestamps.at(0);
1306  m_nextImageTimestamp = m_timestamps.at(1);
1307  imageHeader.imageType = 2;
1308  }
1309  } else if (m_imageType == us::PRESCAN_3D) {
1310  if (m_usePause) {
1311  if (!m_pauseOn) {
1312  if (m_useRewind) {
1313  // counting the number of total sequence sent
1314  unsigned int currentNumberOfWholeSequenceSent = 0;
1315 
1316  if (imageHeader.frameCount - m_pauseIndexOffset >=
1317  (unsigned int)m_MHDSequenceReader.getTotalImageNumber() * m_preScanImage3d.getFrameNumber()) {
1318  currentNumberOfWholeSequenceSent =
1319  ((imageHeader.frameCount - m_pauseIndexOffset -
1320  (m_MHDSequenceReader.getTotalImageNumber() * m_preScanImage3d.getFrameNumber())) /
1321  ((m_MHDSequenceReader.getTotalImageNumber() - 1) * m_preScanImage3d.getFrameNumber())) +
1322  1;
1323  }
1324 
1325  if (currentNumberOfWholeSequenceSent == 0) { // sending first sequence
1326  int volumeIndex = ((imageHeader.frameCount - m_pauseIndexOffset) / m_preScanImage3d.getFrameNumber());
1327 
1328  m_MHDSequenceReader.getImage(volumeIndex, m_preScanImage3d, m_timestamps);
1329  imageHeader.timeStamp = m_timestamps.at(0);
1330  m_nextImageTimestamp = m_timestamps.at(1);
1331  imageHeader.imageType = 0;
1332 
1333  } else if (currentNumberOfWholeSequenceSent % 2 == 0) {
1334  int volumeIndex = (((imageHeader.frameCount - m_pauseIndexOffset -
1335  (m_MHDSequenceReader.getTotalImageNumber() * m_preScanImage3d.getFrameNumber())) /
1336  m_preScanImage3d.getFrameNumber()) %
1337  (m_MHDSequenceReader.getTotalImageNumber() - 1)) +
1338  1;
1339 
1340  m_MHDSequenceReader.getImage(volumeIndex, m_preScanImage3d, m_timestamps);
1341  imageHeader.imageType = 0;
1342  } else {
1343  int volumeIndex = m_MHDSequenceReader.getTotalImageNumber() - 2 -
1344  ((imageHeader.frameCount - m_pauseIndexOffset -
1345  (m_MHDSequenceReader.getTotalImageNumber() * m_preScanImage3d.getFrameNumber())) /
1346  m_preScanImage3d.getFrameNumber()) %
1347  (m_MHDSequenceReader.getTotalImageNumber() - 1);
1348 
1349  m_MHDSequenceReader.getImage(volumeIndex, m_preScanImage3d, m_timestamps);
1350  imageHeader.imageType = 0;
1351  }
1352  } else {
1353  m_MHDSequenceReader.acquire(m_preScanImage3d, m_timestamps);
1354  imageHeader.timeStamp = m_timestamps.at(0) + m_pauseDurationOffset;
1355  m_nextImageTimestamp = m_timestamps.at(1) + m_pauseDurationOffset;
1356  imageHeader.imageType = 0;
1357  }
1358  }
1359 
1360  if (imageHeader.frameCount / m_preScanImage3d.getFrameNumber() == m_pauseImageNumber &&
1361  !m_pauseOn) { // we arrive on the volume to pause on
1362  m_MHDSequenceReader.acquire(m_preScanImage3dTemp,
1363  m_timestampsTemp); // temp attributes contains next volume and timestamps
1364  m_pauseOn = true;
1365  }
1366  } else if (m_useRewind) {
1367  // counting the number of total sequence sent
1368  unsigned int currentNumberOfWholeSequenceSent = 0;
1369 
1370  if (imageHeader.frameCount >=
1371  (unsigned int)m_MHDSequenceReader.getTotalImageNumber() * m_preScanImage3d.getFrameNumber()) {
1372  currentNumberOfWholeSequenceSent =
1373  ((imageHeader.frameCount -
1374  (m_MHDSequenceReader.getTotalImageNumber() * m_preScanImage3d.getFrameNumber())) /
1375  ((m_MHDSequenceReader.getTotalImageNumber() - 1) * m_preScanImage3d.getFrameNumber())) +
1376  1;
1377  }
1378 
1379  if (currentNumberOfWholeSequenceSent == 0) { // sending first sequence
1380 
1381  m_MHDSequenceReader.acquire(m_preScanImage3d, m_timestamps);
1382  imageHeader.timeStamp = m_timestamps.at(0);
1383  m_nextImageTimestamp = m_timestamps.at(1);
1384  imageHeader.imageType = 0;
1385 
1386  } else if (currentNumberOfWholeSequenceSent % 2 == 0) {
1387  int volumeIndex = (((imageHeader.frameCount -
1388  (m_MHDSequenceReader.getTotalImageNumber() * m_preScanImage3d.getFrameNumber())) /
1389  m_preScanImage3d.getFrameNumber()) %
1390  (m_MHDSequenceReader.getTotalImageNumber() - 1)) +
1391  1;
1392 
1393  m_MHDSequenceReader.getImage(volumeIndex, m_preScanImage3d, m_timestamps);
1394  imageHeader.imageType = 0;
1395  } else {
1396  int volumeIndex = m_MHDSequenceReader.getTotalImageNumber() - 2 -
1397  ((imageHeader.frameCount -
1398  (m_MHDSequenceReader.getTotalImageNumber() * m_preScanImage3d.getFrameNumber())) /
1399  m_preScanImage3d.getFrameNumber()) %
1400  (m_MHDSequenceReader.getTotalImageNumber() - 1);
1401 
1402  m_MHDSequenceReader.getImage(volumeIndex, m_preScanImage3d, m_timestamps);
1403  imageHeader.imageType = 0;
1404  }
1405  } else {
1406  m_MHDSequenceReader.acquire(m_preScanImage3d, m_timestamps);
1407  imageHeader.timeStamp = m_timestamps.at(0);
1408  m_nextImageTimestamp = m_timestamps.at(1);
1409  imageHeader.imageType = 0;
1410  }
1411  }
1412  } else if (m_imageType == us::RF_2D || m_imageType == us::PRESCAN_2D ||
1413  m_imageType == us::POSTSCAN_2D) { // pause on first image (2D case)
1414  if (m_usePause && imageHeader.frameCount == m_pauseImageNumber)
1415  m_pauseOn = true;
1416 
1417  if (m_usePause && m_pauseOn) {
1418  uint64_t deltaT = 40; // if we pause on first image, we set the time delta between 2 same frames to 40ms
1419  m_nextImageTimestamp += deltaT;
1420  imageHeader.timeStamp += deltaT;
1421  m_pauseDurationOffset += deltaT;
1422  if (imageHeader.frameCount != 0) // manage first image case
1423  m_pauseIndexOffset++;
1424  }
1425  }
1426 
1427  if (m_imageType == us::RF_2D) { // send RF image
1428  imageHeader.dataRate = 1000.0 / (m_nextImageTimestamp - imageHeader.timeStamp);
1429 
1430  QByteArray block;
1431  QDataStream out(&block, QIODevice::WriteOnly);
1432 #if defined(USTK_HAVE_VTK_QT4)
1433  out.setVersion(QDataStream::Qt_4_8);
1434 #else
1435  out.setVersion(QDataStream::Qt_5_0);
1436 #endif
1437 
1438  out << imageHeader.headerId;
1439  out << imageHeader.frameCount;
1440  out << imageHeader.timeStamp;
1441  out << imageHeader.dataRate;
1442  out << (int)m_rfImage2d.getHeight() * m_rfImage2d.getWidth() * 2; // datalength in bytes
1443  out << (int)16; // sample size in bits
1444  out << (int)2; // image type
1445  out << m_rfImage2d.getWidth();
1446  out << m_rfImage2d.getHeight();
1447  out << (double).0; // pixelWidth
1448  out << (double).0; // pixelHeight
1449  out << m_rfImage2d.getTransmitFrequency();
1450  out << m_rfImage2d.getSamplingFrequency();
1451  out << m_rfImage2d.getTransducerRadius();
1452  out << m_rfImage2d.getScanLinePitch();
1453  out << (int)m_rfImage2d.getScanLineNumber();
1454  out << (int)(m_rfImage2d.getDepth() * 1000.0); // int in mm
1455  out << (double).0; // degPerFrame
1456  out << (int)0; // framesPerVolume
1457  out << (double).0; // motorRadius
1458  out << (int)0; // motorType
1459  out.writeRawData((char *)m_rfImage2d.bitmap, (int)m_rfImage2d.getHeight() * m_rfImage2d.getWidth() * 2);
1460 
1461  endOfSequence = m_MHDSequenceReader.end() && !m_useRewind;
1462 
1463  connectionSoc->write(block);
1464  qApp->processEvents();
1465 
1466  std::cout << "new frame sent, No " << imageHeader.frameCount << std::endl;
1467 
1468  imageHeader.frameCount++;
1469 
1470  // WAITING PROCESS (to respect sequence timestamps)
1471  vpTime::wait((double)(m_nextImageTimestamp - imageHeader.timeStamp));
1472  } else if (m_imageType == us::PRESCAN_2D) { // send pre-scan image
1473  imageHeader.dataRate = 1000.0 / (m_nextImageTimestamp - imageHeader.timeStamp);
1474 
1475  QByteArray block;
1476  QDataStream out(&block, QIODevice::WriteOnly);
1477 #if defined(USTK_HAVE_VTK_QT4)
1478  out.setVersion(QDataStream::Qt_4_8);
1479 #else
1480  out.setVersion(QDataStream::Qt_5_0);
1481 #endif
1482 
1483  out << imageHeader.headerId;
1484  out << imageHeader.frameCount;
1485  out << imageHeader.timeStamp;
1486  out << imageHeader.dataRate;
1487  out << (int)m_preScanImage2d.getHeight() * m_preScanImage2d.getWidth(); // datalength in bytes
1488  out << (int)8; // sample size in bits
1489  out << (int)0;
1490  out << m_preScanImage2d.getHeight();
1491  out << m_preScanImage2d.getWidth();
1492  out << (double).0; // pixelWidth
1493  out << (double).0; // pixelHeight
1494  out << m_preScanImage2d.getTransmitFrequency();
1495  out << m_preScanImage2d.getSamplingFrequency();
1496  out << m_preScanImage2d.getTransducerRadius();
1497  out << m_preScanImage2d.getScanLinePitch();
1498  out << (int)m_preScanImage2d.getScanLineNumber();
1499  out << (int)(m_preScanImage2d.getDepth() * 1000.0); // int in mm
1500  out << (double).0; // degPerFrame
1501  out << (int)0; // framesPerVolume
1502  out << (double).0; // motorRadius
1503  out << (int)0; // motorType
1504  out.writeRawData((char *)m_preScanImage2d.bitmap,
1505  (int)m_preScanImage2d.getHeight() * m_preScanImage2d.getWidth());
1506 
1507  endOfSequence = m_MHDSequenceReader.end() && !m_useRewind;
1508 
1509  connectionSoc->write(block);
1510  qApp->processEvents();
1511 
1512  std::cout << "new frame sent, No " << imageHeader.frameCount << std::endl;
1513 
1514  imageHeader.frameCount++;
1515 
1516  // WAITING PROCESS (to respect sequence timestamps)
1517  vpTime::wait((double)(m_nextImageTimestamp - imageHeader.timeStamp));
1518  } else if (m_imageType == us::POSTSCAN_2D) { // send post-scan image
1519  imageHeader.dataRate = 1000.0 / (m_nextImageTimestamp - imageHeader.timeStamp);
1520 
1521  QByteArray block;
1522  QDataStream out(&block, QIODevice::WriteOnly);
1523 #if defined(USTK_HAVE_VTK_QT4)
1524  out.setVersion(QDataStream::Qt_4_8);
1525 #else
1526  out.setVersion(QDataStream::Qt_5_0);
1527 #endif
1528 
1529  out << imageHeader.headerId;
1530  out << imageHeader.frameCount;
1531  out << imageHeader.timeStamp;
1532  out << imageHeader.dataRate;
1533  out << (int)m_postScanImage2d.getHeight() * m_postScanImage2d.getWidth(); // datalength in bytes
1534  out << (int)8; // sample size in bits
1535  out << (int)1;
1536  out << m_postScanImage2d.getWidth();
1537  out << m_postScanImage2d.getHeight();
1538  out << m_postScanImage2d.getWidthResolution(); // pixelWidth
1539  out << m_postScanImage2d.getHeightResolution(); // pixelHeight
1540  out << m_postScanImage2d.getTransmitFrequency();
1541  out << m_postScanImage2d.getSamplingFrequency();
1542  out << m_postScanImage2d.getTransducerRadius();
1543  out << m_postScanImage2d.getScanLinePitch();
1544  out << (int)m_postScanImage2d.getScanLineNumber();
1545  out << (int)(m_postScanImage2d.getDepth() * 1000.0); // int in mm
1546  out << (double).0; // degPerFrame
1547  out << (int)0; // framesPerVolume
1548  out << (double).0; // motorRadius
1549  out << (int)0; // motorType
1550  out.writeRawData((char *)m_postScanImage2d.bitmap,
1551  (int)m_postScanImage2d.getHeight() * m_postScanImage2d.getWidth());
1552 
1553  endOfSequence = m_MHDSequenceReader.end() && !m_useRewind;
1554 
1555  connectionSoc->write(block);
1556  qApp->processEvents();
1557 
1558  std::cout << "new frame sent, No " << imageHeader.frameCount << std::endl;
1559 
1560  imageHeader.frameCount++;
1561 
1562  // WAITING PROCESS (to respect sequence timestamps)
1563  vpTime::wait((double)(m_nextImageTimestamp - imageHeader.timeStamp));
1564  }
1565  // 3D case
1566  else if (m_imageType == us::RF_3D) { // send RF volume frame by frame
1567  bool endOfVolume = false;
1568  unsigned int currentFrameInVolume = 0;
1569  while (!endOfVolume) {
1570  QByteArray block;
1571  QDataStream out(&block, QIODevice::WriteOnly);
1572 #if defined(USTK_HAVE_VTK_QT4)
1573  out.setVersion(QDataStream::Qt_4_8);
1574 #else
1575  out.setVersion(QDataStream::Qt_5_0);
1576 #endif
1577  // new frame to send
1578  if (m_pauseOn) { // pause case (we send volumes V, V+1, V, V+1, ...)
1579  // check if current volume is odd or even
1580  unsigned int framePositionInVolume;
1581  if ((imageHeader.frameCount / m_rfImage3d.getFrameNumber()) % 2 == 1)
1582  framePositionInVolume = m_rfImage3d.getFrameNumber() - currentFrameInVolume - 1;
1583  else
1584  framePositionInVolume = currentFrameInVolume;
1585 
1586  // we choose between V and V+1
1587  if (imageHeader.frameCount % (2 * m_rfImage3d.getFrameNumber()) >= m_rfImage3d.getFrameNumber() - 1) { // V+1
1588  m_rfImage3dTemp.getFrame(m_rfImage2d, framePositionInVolume);
1589  imageHeader.timeStamp = m_timestampsTemp.at(currentFrameInVolume) + m_pauseDurationOffset;
1590  if (m_rfImage3dTemp.getFrameNumber() ==
1591  currentFrameInVolume + 1) { // we're sending last frame of the volume
1592  m_nextImageTimestamp =
1593  imageHeader.timeStamp + 40; // next delta is 40ms (we don't know timestamp of first image of V+2
1594  if (m_volumePauseTmp)
1595  m_pauseOn = false;
1596  } else
1597  m_nextImageTimestamp = m_timestampsTemp.at(currentFrameInVolume + 1) + m_pauseDurationOffset;
1598  } else {
1599  m_rfImage3d.getFrame(m_rfImage2d, framePositionInVolume);
1600  imageHeader.timeStamp = m_timestamps.at(currentFrameInVolume) + m_pauseDurationOffset;
1601  if (m_rfImage3dTemp.getFrameNumber() == currentFrameInVolume + 1) // we're sending last frame of the volume
1602  m_nextImageTimestamp = m_timestampsTemp.at(currentFrameInVolume + 1) +
1603  m_pauseDurationOffset; // next timestamp is first of V+1
1604  else
1605  m_nextImageTimestamp = m_timestamps.at(currentFrameInVolume + 1) + m_pauseDurationOffset;
1606  }
1607  // time offset due to pause
1608  uint64_t deltaT = m_nextImageTimestamp - imageHeader.timeStamp;
1609  m_pauseDurationOffset += deltaT;
1610  m_pauseIndexOffset++;
1611  } else if (m_useRewind) {
1612  // counting the number of total sequence sent
1613  unsigned int currentNumberOfWholeSequenceSent = 0;
1614  if (imageHeader.frameCount >=
1615  (unsigned int)m_MHDSequenceReader.getTotalImageNumber() * m_rfImage3d.getFrameNumber()) {
1616  currentNumberOfWholeSequenceSent =
1617  ((imageHeader.frameCount - (m_MHDSequenceReader.getTotalImageNumber() * m_rfImage3d.getFrameNumber())) /
1618  ((m_MHDSequenceReader.getTotalImageNumber() - 1) * m_rfImage3d.getFrameNumber())) +
1619  1;
1620  }
1621 
1622  if (currentNumberOfWholeSequenceSent == 0) {
1623  // get frame
1624  if ((imageHeader.frameCount / m_rfImage3d.getFrameNumber()) % 2 == 1) {
1625  m_rfImage3d.getFrame(m_rfImage2d, m_rfImage3d.getFrameNumber() - currentFrameInVolume - 1);
1626  } else {
1627  m_rfImage3d.getFrame(m_rfImage2d, currentFrameInVolume);
1628  }
1629 
1630  // timestamp
1631  imageHeader.timeStamp = m_timestamps.at(currentFrameInVolume) + m_pauseDurationOffset;
1632  if (m_rfImage3d.getFrameNumber() == currentFrameInVolume + 1) { // we're sending last frame of the volume
1633  if (m_MHDSequenceReader.end()) { // last frame of last volume
1634  m_nextImageTimestamp = imageHeader.timeStamp + (m_timestamps.at(currentFrameInVolume) -
1635  m_timestamps.at(currentFrameInVolume - 1));
1636  } else if ((imageHeader.frameCount / m_rfImage3d.getFrameNumber()) % 2 == 0) { // nex volume is odd
1637  m_nextImageTimestamp =
1638  m_MHDSequenceReader.getNextTimeStamps().back(); // next timestamp is last of next volume
1639  } else { // next volume is even
1640  m_nextImageTimestamp =
1641  m_MHDSequenceReader.getNextTimeStamps().back(); // next timestamp is first of next volume
1642  }
1643  } else if (m_timestamps.size() != currentFrameInVolume + 1)
1644  m_nextImageTimestamp = m_timestamps.at(currentFrameInVolume + 1);
1645 
1646  } else if (currentNumberOfWholeSequenceSent % 2 == 0) { // we go from volume 1 to N-1
1647  // get frame
1648  if ((imageHeader.frameCount / m_rfImage3d.getFrameNumber()) % 2 == 1) {
1649  m_rfImage3d.getFrame(m_rfImage2d, m_rfImage3d.getFrameNumber() - currentFrameInVolume - 1);
1650  } else {
1651  m_rfImage3d.getFrame(m_rfImage2d, currentFrameInVolume);
1652  }
1653 
1654  // timestamp
1655  uint64_t delta;
1656  uint64_t deltaNext;
1657  if (m_rfImage3d.getFrameNumber() == currentFrameInVolume + 1) { // we're sending last frame of the volume
1658  delta = m_timestamps.at(currentFrameInVolume) - m_timestamps.at(currentFrameInVolume - 1);
1659  deltaNext = delta; // we consider same delta for convinience
1660  } else if (currentFrameInVolume == 0) { // first frame of the volume
1661  deltaNext = m_timestamps.at(currentFrameInVolume + 1) - m_timestamps.at(currentFrameInVolume);
1662  delta = deltaNext; // we consider same delta for convinience
1663  } else {
1664  delta = m_timestamps.at(currentFrameInVolume) - m_timestamps.at(currentFrameInVolume - 1);
1665  deltaNext = m_timestamps.at(currentFrameInVolume + 1) - m_timestamps.at(currentFrameInVolume);
1666  }
1667  imageHeader.timeStamp += delta;
1668  m_nextImageTimestamp = imageHeader.timeStamp + deltaNext;
1669  } else { // we go from volume N-2 to 0
1670  // get frame
1671  if ((imageHeader.frameCount / m_rfImage3d.getFrameNumber()) % 2 == 1) {
1672  m_rfImage3d.getFrame(m_rfImage2d, m_rfImage3d.getFrameNumber() - currentFrameInVolume - 1);
1673  } else {
1674  m_rfImage3d.getFrame(m_rfImage2d, currentFrameInVolume);
1675  }
1676 
1677  // timestamp
1678  uint64_t delta;
1679  uint64_t deltaNext;
1680  if (m_rfImage3d.getFrameNumber() == currentFrameInVolume + 1) { // we're sending last frame of the volume
1681  delta = m_timestamps.at(currentFrameInVolume) - m_timestamps.at(currentFrameInVolume - 1);
1682  deltaNext = delta; // we consider same delta for convinience
1683  } else if (currentFrameInVolume == 0) { // first frame of the volume
1684  deltaNext = m_timestamps.at(currentFrameInVolume + 1) - m_timestamps.at(currentFrameInVolume);
1685  delta = deltaNext; // we consider same delta for convinience
1686  } else {
1687  delta = m_timestamps.at(currentFrameInVolume) - m_timestamps.at(currentFrameInVolume - 1);
1688  deltaNext = m_timestamps.at(currentFrameInVolume + 1) - m_timestamps.at(currentFrameInVolume);
1689  }
1690  imageHeader.timeStamp += delta;
1691  m_nextImageTimestamp = imageHeader.timeStamp + deltaNext;
1692  }
1693  } else {
1694  if ((imageHeader.frameCount / m_rfImage3d.getFrameNumber()) % 2 == 1)
1695  m_rfImage3d.getFrame(m_rfImage2d, m_rfImage3d.getFrameNumber() - currentFrameInVolume - 1);
1696  else
1697  m_rfImage3d.getFrame(m_rfImage2d, currentFrameInVolume);
1698 
1699  // timestamps
1700  imageHeader.timeStamp = m_timestamps.at(currentFrameInVolume) + m_pauseDurationOffset;
1701  if (m_rfImage3d.getFrameNumber() == currentFrameInVolume + 1) { // we're sending last frame of the volume
1702  if (m_MHDSequenceReader.end()) // last frame of last volume
1703  m_nextImageTimestamp = imageHeader.timeStamp;
1704  else if ((imageHeader.frameCount / m_rfImage3d.getFrameNumber()) % 2 == 0) { // nex volume is odd
1705  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamps().back() +
1706  m_pauseDurationOffset; // next timestamp is last of next volume
1707  } else { // next volume is even
1708  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamps().back() +
1709  m_pauseDurationOffset; // next timestamp is first of next volume
1710  }
1711  } else if (m_timestamps.size() != currentFrameInVolume + 1)
1712  m_nextImageTimestamp = m_timestamps.at(currentFrameInVolume + 1) + m_pauseDurationOffset;
1713  }
1714  imageHeader.dataRate = 1000.0 / (m_nextImageTimestamp - imageHeader.timeStamp);
1715 
1716  out << imageHeader.headerId;
1717  out << imageHeader.frameCount;
1718  out << imageHeader.timeStamp;
1719  out << imageHeader.dataRate;
1720  out << (int)m_rfImage3d.getWidth() * m_rfImage3d.getHeight() * 2; // datalength in bytes
1721  out << (int)16; // sample size in bits
1722  out << (int)2; // image type
1723  out << m_rfImage3d.getWidth();
1724  out << m_rfImage3d.getHeight();
1725  out << (double).0; // pixelWidth
1726  out << (double).0; // pixelHeight
1727  out << m_rfImage3d.getTransmitFrequency();
1728  out << m_rfImage3d.getSamplingFrequency();
1729  out << m_rfImage3d.getTransducerRadius();
1730  out << m_rfImage3d.getScanLinePitch();
1731  out << (int)m_rfImage3d.getScanLineNumber();
1732  out << (int)(m_rfImage3d.getDepth() * 1000.0); // int in mm
1733  out << (double)vpMath::deg(m_rfImage3d.getFramePitch()); // degPerFrame
1734  out << (int)m_rfImage3d.getFrameNumber(); // framesPerVolume
1735  out << (double)m_rfImage3d.getMotorRadius(); // motorRadius
1736  out << (int)m_rfImage3d.getMotorType(); // motorType
1737  out.writeRawData((char *)m_rfImage2d.bitmap, (int)m_rfImage2d.getHeight() * m_rfImage2d.getWidth() * 2);
1738 
1739  connectionSoc->write(block);
1740  qApp->processEvents();
1741 
1742  std::cout << "new frame sent, No " << imageHeader.frameCount << std::endl;
1743 
1744  imageHeader.frameCount++;
1745  currentFrameInVolume++;
1746  endOfVolume = m_rfImage3d.getFrameNumber() == currentFrameInVolume;
1747  endOfSequence = (m_MHDSequenceReader.end() && endOfVolume && !m_useRewind);
1748 
1749  // WAITING PROCESS (to respect sequence timestamps)
1750  vpTime::wait((double)(m_nextImageTimestamp - imageHeader.timeStamp));
1751  }
1752  } else if (m_imageType == us::PRESCAN_3D) { // send pre-scan volume frame by frame
1753  bool endOfVolume = false;
1754  unsigned int currentFrameInVolume = 0;
1755  while (!endOfVolume) {
1756  QByteArray block;
1757  QDataStream out(&block, QIODevice::WriteOnly);
1758 #if defined(USTK_HAVE_VTK_QT4)
1759  out.setVersion(QDataStream::Qt_4_8);
1760 #else
1761  out.setVersion(QDataStream::Qt_5_0);
1762 #endif
1763  // new frame to send
1764  if (m_pauseOn) { // pause case (we send volumes V, V+1, V, V+1, ...)
1765  // check if current volume is odd or even
1766  unsigned int framePositionInVolume;
1767  if ((imageHeader.frameCount / m_preScanImage3d.getFrameNumber()) % 2 == 1)
1768  framePositionInVolume = m_preScanImage3d.getFrameNumber() - currentFrameInVolume - 1;
1769  else
1770  framePositionInVolume = currentFrameInVolume;
1771 
1772  // we choose between V and V+1
1773  if (imageHeader.frameCount % (2 * m_preScanImage3d.getFrameNumber()) >=
1774  m_preScanImage3d.getFrameNumber() - 1) { // V+1
1775  m_preScanImage3dTemp.getFrame(m_preScanImage2d, framePositionInVolume);
1776  imageHeader.timeStamp = m_timestampsTemp.at(currentFrameInVolume) + m_pauseDurationOffset;
1777  if (m_preScanImage3dTemp.getFrameNumber() ==
1778  currentFrameInVolume + 1) { // we're sending last frame of the volume
1779  m_nextImageTimestamp =
1780  imageHeader.timeStamp + 40; // next delta is 40ms (we don't know timestamp of first image of V+2
1781  if (m_volumePauseTmp)
1782  m_pauseOn = false;
1783  } else
1784  m_nextImageTimestamp = m_timestampsTemp.at(currentFrameInVolume + 1) + m_pauseDurationOffset;
1785  } else {
1786  m_preScanImage3d.getFrame(m_preScanImage2d, framePositionInVolume);
1787  imageHeader.timeStamp = m_timestamps.at(currentFrameInVolume) + m_pauseDurationOffset;
1788  if (m_preScanImage3dTemp.getFrameNumber() ==
1789  currentFrameInVolume + 1) // we're sending last frame of the volume
1790  m_nextImageTimestamp = m_timestampsTemp.at(currentFrameInVolume + 1) +
1791  m_pauseDurationOffset; // next timestamp is first of V+1
1792  else
1793  m_nextImageTimestamp = m_timestamps.at(currentFrameInVolume + 1) + m_pauseDurationOffset;
1794  }
1795  invertRowsColsOnPreScan();
1796  // time offset due to pause
1797  uint64_t deltaT = m_nextImageTimestamp - imageHeader.timeStamp;
1798  m_pauseDurationOffset += deltaT;
1799  m_pauseIndexOffset++;
1800  } else if (m_useRewind) {
1801  // counting the number of total sequence sent
1802  unsigned int currentNumberOfWholeSequenceSent = 0;
1803  if (imageHeader.frameCount >=
1804  (unsigned int)m_MHDSequenceReader.getTotalImageNumber() * m_preScanImage3d.getFrameNumber()) {
1805  currentNumberOfWholeSequenceSent =
1806  ((imageHeader.frameCount -
1807  (m_MHDSequenceReader.getTotalImageNumber() * m_preScanImage3d.getFrameNumber())) /
1808  ((m_MHDSequenceReader.getTotalImageNumber() - 1) * m_preScanImage3d.getFrameNumber())) +
1809  1;
1810  }
1811 
1812  if (currentNumberOfWholeSequenceSent == 0) {
1813  // get frame
1814  if ((imageHeader.frameCount / m_preScanImage3d.getFrameNumber()) % 2 == 1) {
1815  m_preScanImage3d.getFrame(m_preScanImage2d, m_preScanImage3d.getFrameNumber() - currentFrameInVolume - 1);
1816  } else {
1817  m_preScanImage3d.getFrame(m_preScanImage2d, currentFrameInVolume);
1818  }
1819 
1820  invertRowsColsOnPreScan();
1821 
1822  // timestamp
1823  imageHeader.timeStamp = m_timestamps.at(currentFrameInVolume) + m_pauseDurationOffset;
1824  if (m_preScanImage3d.getFrameNumber() ==
1825  currentFrameInVolume + 1) { // we're sending last frame of the volume
1826  if (m_MHDSequenceReader.end()) { // last frame of last volume
1827  m_nextImageTimestamp = imageHeader.timeStamp + (m_timestamps.at(currentFrameInVolume) -
1828  m_timestamps.at(currentFrameInVolume - 1));
1829  } else if ((imageHeader.frameCount / m_preScanImage3d.getFrameNumber()) % 2 == 0) { // nex volume is odd
1830  m_nextImageTimestamp =
1831  m_MHDSequenceReader.getNextTimeStamps().back(); // next timestamp is last of next volume
1832  } else { // next volume is even
1833  m_nextImageTimestamp =
1834  m_MHDSequenceReader.getNextTimeStamps().back(); // next timestamp is first of next volume
1835  }
1836  } else if (m_timestamps.size() != currentFrameInVolume + 1)
1837  m_nextImageTimestamp = m_timestamps.at(currentFrameInVolume + 1);
1838 
1839  } else if (currentNumberOfWholeSequenceSent % 2 == 0) { // we go from volume 1 to N-1
1840  // get frame
1841  if ((imageHeader.frameCount / m_preScanImage3d.getFrameNumber()) % 2 == 1) {
1842  m_preScanImage3d.getFrame(m_preScanImage2d, m_preScanImage3d.getFrameNumber() - currentFrameInVolume - 1);
1843  } else {
1844  m_preScanImage3d.getFrame(m_preScanImage2d, currentFrameInVolume);
1845  }
1846 
1847  invertRowsColsOnPreScan();
1848 
1849  // timestamp
1850  uint64_t delta;
1851  uint64_t deltaNext;
1852  if (m_preScanImage3d.getFrameNumber() ==
1853  currentFrameInVolume + 1) { // we're sending last frame of the volume
1854  delta = m_timestamps.at(currentFrameInVolume) - m_timestamps.at(currentFrameInVolume - 1);
1855  deltaNext = delta; // we consider same delta for convinience
1856  } else if (currentFrameInVolume == 0) { // first frame of the volume
1857  deltaNext = m_timestamps.at(currentFrameInVolume + 1) - m_timestamps.at(currentFrameInVolume);
1858  delta = deltaNext; // we consider same delta for convinience
1859  } else {
1860  delta = m_timestamps.at(currentFrameInVolume) - m_timestamps.at(currentFrameInVolume - 1);
1861  deltaNext = m_timestamps.at(currentFrameInVolume + 1) - m_timestamps.at(currentFrameInVolume);
1862  }
1863  imageHeader.timeStamp += delta;
1864  m_nextImageTimestamp = imageHeader.timeStamp + deltaNext;
1865  } else { // we go from volume N-2 to 0
1866  // get frame
1867  if ((imageHeader.frameCount / m_preScanImage3d.getFrameNumber()) % 2 == 1) {
1868  m_preScanImage3d.getFrame(m_preScanImage2d, m_preScanImage3d.getFrameNumber() - currentFrameInVolume - 1);
1869  } else {
1870  m_preScanImage3d.getFrame(m_preScanImage2d, currentFrameInVolume);
1871  }
1872 
1873  invertRowsColsOnPreScan();
1874 
1875  // timestamp
1876  uint64_t delta;
1877  uint64_t deltaNext;
1878  if (m_preScanImage3d.getFrameNumber() ==
1879  currentFrameInVolume + 1) { // we're sending last frame of the volume
1880  delta = m_timestamps.at(currentFrameInVolume) - m_timestamps.at(currentFrameInVolume - 1);
1881  deltaNext = delta; // we consider same delta for convinience
1882  } else if (currentFrameInVolume == 0) { // first frame of the volume
1883  deltaNext = m_timestamps.at(currentFrameInVolume + 1) - m_timestamps.at(currentFrameInVolume);
1884  delta = deltaNext; // we consider same delta for convinience
1885  } else {
1886  delta = m_timestamps.at(currentFrameInVolume) - m_timestamps.at(currentFrameInVolume - 1);
1887  deltaNext = m_timestamps.at(currentFrameInVolume + 1) - m_timestamps.at(currentFrameInVolume);
1888  }
1889  imageHeader.timeStamp += delta;
1890  m_nextImageTimestamp = imageHeader.timeStamp + deltaNext;
1891  }
1892  } else {
1893  if ((imageHeader.frameCount / m_preScanImage3d.getFrameNumber()) % 2 == 1)
1894  m_preScanImage3d.getFrame(m_preScanImage2d, m_preScanImage3d.getFrameNumber() - currentFrameInVolume - 1);
1895  else
1896  m_preScanImage3d.getFrame(m_preScanImage2d, currentFrameInVolume);
1897  invertRowsColsOnPreScan();
1898  // timestamps
1899  imageHeader.timeStamp = m_timestamps.at(currentFrameInVolume) + m_pauseDurationOffset;
1900  if (m_preScanImage3d.getFrameNumber() == currentFrameInVolume + 1) { // we're sending last frame of the volume
1901  if (m_MHDSequenceReader.end()) // last frame of last volume
1902  m_nextImageTimestamp = imageHeader.timeStamp;
1903  else if ((imageHeader.frameCount / m_preScanImage3d.getFrameNumber()) % 2 == 0) { // nex volume is odd
1904  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamps().back() +
1905  m_pauseDurationOffset; // next timestamp is last of next volume
1906  } else { // next volume is even
1907  m_nextImageTimestamp = m_MHDSequenceReader.getNextTimeStamps().back() +
1908  m_pauseDurationOffset; // next timestamp is first of next volume
1909  }
1910  } else if (m_timestamps.size() != currentFrameInVolume + 1)
1911  m_nextImageTimestamp = m_timestamps.at(currentFrameInVolume + 1) + m_pauseDurationOffset;
1912  }
1913 
1914  imageHeader.dataRate = 1000.0 / (m_nextImageTimestamp - imageHeader.timeStamp);
1915 
1916  out << imageHeader.headerId;
1917  out << imageHeader.frameCount;
1918  out << imageHeader.timeStamp;
1919  out << imageHeader.dataRate;
1920  out << (int)m_preScanImage3d.getWidth() * m_preScanImage3d.getHeight(); // datalength in bytes
1921  out << (int)8; // sample size in bits
1922  out << (int)0;
1923  out << m_preScanImage3d.getWidth();
1924  out << m_preScanImage3d.getHeight();
1925  out << (double).0; // pixelWidth
1926  out << (double).0; // pixelHeight
1927  out << m_preScanImage3d.getTransmitFrequency();
1928  out << m_preScanImage3d.getSamplingFrequency();
1929  out << m_preScanImage3d.getTransducerRadius();
1930  out << m_preScanImage3d.getScanLinePitch();
1931  out << (int)m_preScanImage3d.getScanLineNumber();
1932  out << (int)(m_preScanImage3d.getDepth() * 1000.0); // int in mm
1933  out << (double)vpMath::deg(m_preScanImage3d.getFramePitch()); // degPerFrame
1934  out << (int)m_preScanImage3d.getFrameNumber(); // framesPerVolume
1935  out << (double)m_preScanImage3d.getMotorRadius(); // motorRadius
1936  out << (int)m_preScanImage3d.getMotorType(); // motorType
1937  // invert row / cols to fit porta SDK (using member image pre-scan 2D
1938  out.writeRawData((char *)m_preScanImage2d.bitmap,
1939  (int)m_preScanImage2d.getHeight() * m_preScanImage2d.getWidth());
1940 
1941  connectionSoc->write(block);
1942  qApp->processEvents();
1943 
1944  std::cout << "new frame sent, No " << imageHeader.frameCount << std::endl;
1945 
1946  imageHeader.frameCount++;
1947  currentFrameInVolume++;
1948  endOfVolume = m_preScanImage3d.getFrameNumber() == currentFrameInVolume;
1949  endOfSequence = (m_MHDSequenceReader.end() && endOfVolume && !m_useRewind);
1950 
1951  // WAITING PROCESS (to respect sequence timestamps)
1952  if (!endOfSequence)
1953  vpTime::wait((double)(m_nextImageTimestamp - imageHeader.timeStamp));
1954  }
1955  }
1956  }
1957 }
1958 
1962 void usVirtualServer::invertRowsColsOnPreScan()
1963 {
1964  usImagePreScan2D<unsigned char> temp = m_preScanImage2d;
1965  m_preScanImage2d.resize(temp.getWidth(), temp.getHeight());
1966 
1967  for (unsigned int i = 0; i < m_preScanImage2d.getHeight(); i++)
1968  for (unsigned int j = 0; j < m_preScanImage2d.getWidth(); j++)
1969  m_preScanImage2d(i, j, temp(j, i));
1970 }
1971 
1975 void usVirtualServer::runAcquisition(bool run)
1976 {
1977  m_serverIsSendingImages = run;
1978  if (run) {
1979  emit(startSendingLoopSignal());
1980  }
1981 }
1982 
1986 void usVirtualServer::quitPause()
1987 {
1988  if (m_imageType == us::RF_2D || m_imageType == us::PRESCAN_2D || m_imageType == us::POSTSCAN_2D) { //(2D case)
1989  m_pauseOn = false;
1990  } else { // we wait the volume (V & V+1) is totally sent
1991  m_volumePauseTmp = true;
1992  }
1993 }
unsigned int getHeight() const
Definition: usImage3D.h:131
unsigned int getWidth() const
Definition: usImage3D.h:125
static usHeaderFormatType getHeaderFormat(const std::string &headerfilename)
Definition: usImageIo.cpp:50
@ FORMAT_MHD
Definition: usImageIo.h:152
double getHeightResolution() const
double getWidthResolution() const
void resize(const unsigned int h, const unsigned int w)
void getFrame(usImagePreScan2D< Type > &image, unsigned int index)
void setImagePreScanSettings(const usImagePreScanSettings &preScanSettings)
unsigned int getHeight() const
Definition: usImageRF2D.h:412
unsigned int getWidth() const
Definition: usImageRF2D.h:424
void getFrame(usImageRF2D< Type > &image, unsigned int index) const
Definition: usImageRF3D.h:395
unsigned int getWidth() const
Definition: usImageRF3D.h:471
unsigned int getHeight() const
Definition: usImageRF3D.h:477
void acquire(usImageRF2D< short int > &image, uint64_t &timestamp)
std::vector< uint64_t > getNextTimeStamps()
void getImage(unsigned int imageNumber, usImageRF2D< short int > &image, uint64_t &timestamp)
void setSequenceDirectory(const std::string sequenceDirectory)
us::ImageType getImageType() const
unsigned int getFrameNumber() const
double getMotorRadius() const
double getFramePitch() const
usMotorType getMotorType() const
Reading of sequences of ultrasound images.
void open(ImageType &image, uint64_t &timestamp)
void acquire(ImageType &image)
void setSequenceFileName(const std::string &sequenceFileName)
std::vector< uint64_t > getSequenceTimestamps() const
double getTransducerRadius() const
unsigned int getScanLineNumber() const
void startSendingLoopSignal()
void runAcquisitionSignal(bool run)
usVirtualServer(std::string sequencePath, QObject *parent=0)
@ PRESCAN_2D
Definition: us.h:70
@ POSTSCAN_2D
Definition: us.h:72
@ RF_2D
Definition: us.h:68
@ PRESCAN_3D
Definition: us.h:71
@ RF_3D
Definition: us.h:69