UsTK : Ultrasound ToolKit  version 2.0.1 under development (2023-12-07)
usImageHeaderXmlParser.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 
38 #include <visp3/ustk_core/usImageHeaderXmlParser.h>
39 
40 #if defined(VISP_HAVE_XML2) && (defined(USTK_HAVE_QT5) || defined(USTK_HAVE_VTK_QT))
41 
45 usImageHeaderXmlParser::usImageHeaderXmlParser() : m_imageHeader(), m_sequence_name()
46 {
47  nodeMap["frame_count"] = CODE_XML_FRAME_COUNT;
48  nodeMap["time_stamp"] = CODE_XML_TIME_STAMP;
49  nodeMap["data_rate"] = CODE_XML_DATA_RATE;
50  nodeMap["data_length"] = CODE_XML_DATA_LENGTH;
51  nodeMap["sample_size"] = CODE_XML_SAMPLE_SIZE;
52  nodeMap["image_type"] = CODE_XML_IMAGE_TYPE;
53  nodeMap["frame_with"] = CODE_XML_FRAME_WITH;
54  nodeMap["frame_height"] = CODE_XML_FRAME_HEIGHT;
55  nodeMap["pixel_width"] = CODE_XML_PIXEL_WIDTH;
56  nodeMap["pixel_height"] = CODE_XML_PIXEL_HEIGHT;
57  nodeMap["transmit_frequency"] = CODE_XML_TRANSMIT_FRQUENCY;
58  nodeMap["sampling_frequency"] = CODE_XML_SAMPLING_FREQUENCY;
59  nodeMap["transducer_radius"] = CODE_XML_TRANSDUCER_RADIUS;
60  nodeMap["scanline_pitch"] = CODE_XML_SCANLINE_PITCH;
61  nodeMap["scanline_number"] = CODE_XML_SCANLINE_NUMBER;
62  nodeMap["image_depth"] = CODE_XML_IMAGE_DEPTH;
63  nodeMap["angle_per_frame"] = CODE_XML_ANGLE_PER_FRAME;
64  nodeMap["frame_per_volume"] = CODE_XML_FRAME_PER_VOLUME;
65  nodeMap["motor_radius"] = CODE_XML_MOTOR_RADIUS;
66  nodeMap["motor_type"] = CODE_XML_MOTOR_TYPE;
67  nodeMap["sequence_name"] = CODE_XML_SEQUENCE_NAME;
68 }
69 
74 
80 void usImageHeaderXmlParser::readMainClass(xmlDocPtr doc, xmlNodePtr node)
81 {
82  for (xmlNodePtr dataNode = node->xmlChildrenNode; dataNode != NULL; dataNode = dataNode->next) {
83  if (dataNode->type == XML_ELEMENT_NODE) {
84  std::map<std::string, int>::iterator iter_data = this->nodeMap.find((char *)dataNode->name);
85  if (iter_data != nodeMap.end()) {
86  switch (iter_data->second) {
88  this->m_imageHeader.frameCount = xmlReadUInt32Child(doc, dataNode);
89  break;
91  this->m_imageHeader.timeStamp = xmlReadUInt64Child(doc, dataNode);
92  break;
93  case CODE_XML_DATA_RATE:
94  this->m_imageHeader.dataRate = xmlReadDoubleChild(doc, dataNode);
95  break;
97  this->m_imageHeader.dataLength = xmlReadIntChild(doc, dataNode);
98  break;
100  this->m_imageHeader.ss = xmlReadIntChild(doc, dataNode);
101  break;
102  case CODE_XML_IMAGE_TYPE:
103  this->m_imageHeader.imageType = xmlReadIntChild(doc, dataNode);
104  break;
105  case CODE_XML_FRAME_WITH:
106  this->m_imageHeader.frameWidth = xmlReadIntChild(doc, dataNode);
107  break;
109  this->m_imageHeader.frameHeight = xmlReadIntChild(doc, dataNode);
110  break;
112  this->m_imageHeader.pixelWidth = xmlReadDoubleChild(doc, dataNode);
113  break;
115  this->m_imageHeader.pixelHeight = xmlReadDoubleChild(doc, dataNode);
116  break;
118  this->m_imageHeader.transmitFrequency = xmlReadIntChild(doc, dataNode);
119  break;
121  this->m_imageHeader.samplingFrequency = xmlReadIntChild(doc, dataNode);
122  break;
124  this->m_imageHeader.transducerRadius = xmlReadDoubleChild(doc, dataNode);
125  break;
127  this->m_imageHeader.scanLinePitch = xmlReadDoubleChild(doc, dataNode);
128  break;
130  this->m_imageHeader.scanLineNumber = xmlReadIntChild(doc, dataNode);
131  break;
133  this->m_imageHeader.imageDepth = xmlReadIntChild(doc, dataNode);
134  break;
136  this->m_imageHeader.anglePerFr = xmlReadDoubleChild(doc, dataNode);
137  break;
139  this->m_imageHeader.framesPerVolume = xmlReadIntChild(doc, dataNode);
140  break;
142  this->m_imageHeader.motorRadius = xmlReadDoubleChild(doc, dataNode);
143  break;
144  case CODE_XML_MOTOR_TYPE:
145  this->m_imageHeader.motorType = xmlReadIntChild(doc, dataNode);
146  break;
148  this->m_sequence_name = xmlReadStringChild(doc, dataNode);
149  break;
150  default:
151  vpTRACE("unknown tag in readConfigNode : %d, %s", iter_data->second, (iter_data->first).c_str());
152  break;
153  }
154  }
155  }
156  }
157 }
158 
164 {
165  xmlWriteUInt32Child(node, "frame_count", this->m_imageHeader.frameCount);
166  xmlWriteUInt64Child(node, "time_stamp", this->m_imageHeader.timeStamp);
167  xmlWriteDoubleChild(node, "time_rate", this->m_imageHeader.dataRate);
168  xmlWriteIntChild(node, "data_length", this->m_imageHeader.dataLength);
169  xmlWriteIntChild(node, "sample_size", this->m_imageHeader.ss);
170  xmlWriteIntChild(node, "image_type", this->m_imageHeader.imageType);
171  xmlWriteIntChild(node, "frame_with", this->m_imageHeader.frameWidth);
172  xmlWriteIntChild(node, "frame_height", this->m_imageHeader.frameHeight);
173  xmlWriteDoubleChild(node, "pixel_width", this->m_imageHeader.pixelWidth);
174  xmlWriteDoubleChild(node, "pixel_height", this->m_imageHeader.pixelHeight);
175  xmlWriteIntChild(node, "transmit_frequency", this->m_imageHeader.transmitFrequency);
176  xmlWriteIntChild(node, "sampling_frequency", this->m_imageHeader.samplingFrequency);
177  xmlWriteDoubleChild(node, "transducer_radius", this->m_imageHeader.transducerRadius);
178  xmlWriteDoubleChild(node, "scanline_pitch", this->m_imageHeader.scanLinePitch);
179  xmlWriteUnsignedIntChild(node, "scanline_number", this->m_imageHeader.scanLineNumber);
180  xmlWriteIntChild(node, "image_depth", this->m_imageHeader.imageDepth);
181  xmlWriteDoubleChild(node, "angle_per_frame", this->m_imageHeader.anglePerFr);
182  xmlWriteIntChild(node, "frame_per_volume", this->m_imageHeader.framesPerVolume);
183  xmlWriteDoubleChild(node, "motor_radius", this->m_imageHeader.motorRadius);
184  xmlWriteIntChild(node, "motor_type", this->m_imageHeader.motorType);
185  xmlWriteStringChild(node, "sequence_name", this->m_sequence_name);
186 }
187 
188 uint32_t usImageHeaderXmlParser::xmlReadUInt32Child(xmlDocPtr doc, xmlNodePtr node)
189 {
190  if (node->xmlChildrenNode == NULL) {
191  std::string errorMsg = "Empty node " + std::string((char *)node->name) + ", cannot read int";
192  std::cerr << errorMsg << std::endl;
193  throw vpException(vpException::fatalError, errorMsg);
194  }
195  char *val_char;
196  char *control_convert;
197  uint32_t val_int;
198 
199  val_char = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
200  val_int = (uint32_t)strtol((char *)val_char, &control_convert, 10);
201 
202  if (val_char == control_convert) {
203  xmlFree((xmlChar *)val_char);
204  throw vpException(vpException::ioError, "cannot parse entry to quint32");
205  }
206  xmlFree((xmlChar *)val_char);
207 
208  return val_int;
209 }
210 
211 uint64_t usImageHeaderXmlParser::xmlReadUInt64Child(xmlDocPtr doc, xmlNodePtr node)
212 {
213  if (node->xmlChildrenNode == NULL) {
214  std::string errorMsg = "Empty node " + std::string((char *)node->name) + ", cannot read int";
215  std::cerr << errorMsg << std::endl;
216  throw vpException(vpException::fatalError, errorMsg);
217  }
218  char *val_char;
219  char *control_convert;
220  uint64_t val_int;
221 
222  val_char = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
223  val_int = (uint64_t)strtoull((char *)val_char, &control_convert, 10);
224 
225  if (val_char == control_convert) {
226  xmlFree((xmlChar *)val_char);
227  throw vpException(vpException::ioError, "cannot parse entry to quint64");
228  }
229  xmlFree((xmlChar *)val_char);
230 
231  return val_int;
232 }
233 
234 void usImageHeaderXmlParser::xmlWriteUInt32Child(xmlNodePtr node, const char *label, const uint32_t value)
235 {
236  std::ostringstream os;
237  os << value;
238  xmlNodePtr tmp = xmlNewChild(node, NULL, (xmlChar *)label, (xmlChar *)os.str().c_str());
239  xmlAddChild(node, tmp);
240 }
241 
242 void usImageHeaderXmlParser::xmlWriteUInt64Child(xmlNodePtr node, const char *label, const uint64_t value)
243 {
244  std::ostringstream os;
245  os << value;
246  xmlNodePtr tmp = xmlNewChild(node, NULL, (xmlChar *)label, (xmlChar *)os.str().c_str());
247  xmlAddChild(node, tmp);
248 }
249 #endif // VISP_HAVE_XML2 && QT
void readMainClass(xmlDocPtr doc, xmlNodePtr node)
void writeMainClass(xmlNodePtr node)
int motorType
Definition: us.h:120
double anglePerFr
Definition: us.h:117
int dataLength
Definition: us.h:89
int frameWidth
Definition: us.h:94
double dataRate
Definition: us.h:87
unsigned int scanLineNumber
Definition: us.h:109
int imageDepth
Definition: us.h:110
uint32_t frameCount
Definition: us.h:84
int samplingFrequency
Definition: us.h:101
int framesPerVolume
Definition: us.h:118
double pixelHeight
Definition: us.h:98
double motorRadius
Definition: us.h:119
int transmitFrequency
Definition: us.h:100
int frameHeight
Definition: us.h:95
int imageType
Definition: us.h:92
double pixelWidth
Definition: us.h:97
uint64_t timeStamp
Definition: us.h:85
double transducerRadius
Definition: us.h:107
double scanLinePitch
Definition: us.h:108