EZC3D
Header.cpp
Go to the documentation of this file.
1 #define EZC3D_API_EXPORTS
2 
10 #include "Header.h"
11 #include "Parameters.h"
12 
14  _nbOfZerosBeforeHeader(0),
15  _parametersAddress(2),
16  _checksum(0x50),
17  _nb3dPoints(0),
18  _nbAnalogsMeasurement(0),
19  _firstFrame(0),
20  _lastFrame(0),
21  _nbMaxInterpGap(10),
22  _scaleFactor(-1),
23  _dataStart(1),
24  _nbAnalogByFrame(0),
25  _frameRate(0),
26  _emptyBlock1(0),
27  _emptyBlock2(0),
28  _emptyBlock3(0),
29  _emptyBlock4(0),
30  _keyLabelPresent(0),
31  _firstBlockKeyLabel(0),
32  _fourCharPresent(0x3039),
33  _nbEvents(0)
34 {
35  _eventsTime.resize(18);
36  _eventsDisplay.resize(9);
37  _eventsLabel.resize(18);
38 }
39 
40 ezc3d::Header::Header(ezc3d::c3d &c3d, std::fstream &file) :
41  _nbOfZerosBeforeHeader(0),
42  _parametersAddress(2),
43  _checksum(0),
44  _nb3dPoints(0),
45  _nbAnalogsMeasurement(0),
46  _firstFrame(0),
47  _lastFrame(0),
48  _nbMaxInterpGap(10),
49  _scaleFactor(-1),
50  _dataStart(1),
51  _nbAnalogByFrame(0),
52  _frameRate(0),
53  _emptyBlock1(0),
54  _emptyBlock2(0),
55  _emptyBlock3(0),
56  _emptyBlock4(0),
57  _keyLabelPresent(0),
58  _firstBlockKeyLabel(0),
59  _fourCharPresent(0x3039),
60  _nbEvents(0)
61 {
62  _eventsTime.resize(18);
63  _eventsDisplay.resize(9);
64  _eventsLabel.resize(18);
65  read(c3d, file);
66 }
67 
68 void ezc3d::Header::print() const{
69  std::cout << "HEADER" << std::endl;
70  std::cout << "nb3dPoints = " << nb3dPoints() << std::endl;
71  std::cout << "nbAnalogsMeasurement = " << nbAnalogsMeasurement() << std::endl;
72  std::cout << "nbAnalogs = " << nbAnalogs() << std::endl;
73  std::cout << "firstFrame = " << firstFrame() << std::endl;
74  std::cout << "lastFrame = " << lastFrame() << std::endl;
75  std::cout << "nbFrames = " << nbFrames() << std::endl;
76  std::cout << "nbMaxInterpGap = " << nbMaxInterpGap() << std::endl;
77  std::cout << "scaleFactor = " << scaleFactor() << std::endl;
78  std::cout << "dataStart = " << dataStart() << std::endl;
79  std::cout << "nbAnalogByFrame = " << nbAnalogByFrame() << std::endl;
80  std::cout << "frameRate = " << frameRate() << std::endl;
81  std::cout << "keyLabelPresent = " << keyLabelPresent() << std::endl;
82  std::cout << "firstBlockKeyLabel = " << firstBlockKeyLabel() << std::endl;
83  std::cout << "fourCharPresent = " << fourCharPresent() << std::endl;
84  std::cout << "nbEvents = " << nbEvents() << std::endl;
85  for (size_t i=0; i < eventsTime().size(); ++i)
86  std::cout << "eventsTime[" << i << "] = " << eventsTime(i) << std::endl;
87  for (size_t i=0; i < eventsDisplay().size(); ++i)
88  std::cout << "eventsDisplay[" << i << "] = " << eventsDisplay(i) << std::endl;
89  for (size_t i=0; i < eventsLabel().size(); ++i)
90  std::cout << "eventsLabel[" << i << "] = " << eventsLabel(i) << std::endl;
91  std::cout << std::endl;
92 }
93 
94 void ezc3d::Header::write(std::fstream &f, std::streampos &dataStartPosition) const
95 {
96  // write the checksum byte and the start point of header
97  int parameterAddessDefault(2);
98  f.write(reinterpret_cast<const char*>(&parameterAddessDefault), ezc3d::BYTE);
99  int checksum(0x50);
100  f.write(reinterpret_cast<const char*>(&checksum), ezc3d::BYTE);
101 
102  // Number of data
103  f.write(reinterpret_cast<const char*>(&_nb3dPoints), 1*ezc3d::DATA_TYPE::WORD);
104  f.write(reinterpret_cast<const char*>(&_nbAnalogsMeasurement), 1*ezc3d::DATA_TYPE::WORD);
105 
106  // Idx of first and last frame
107  size_t firstFrame(_firstFrame + 1); // 1-based!
108  size_t lastFrame(_lastFrame + 1); // 1-based!
109  if (lastFrame > 0xFFFF)
110  lastFrame = 0xFFFF; // Combine this with group("POINT").parameter("FRAMES") = -1
111  f.write(reinterpret_cast<const char*>(&firstFrame), 1*ezc3d::DATA_TYPE::WORD);
112  f.write(reinterpret_cast<const char*>(&lastFrame), 1*ezc3d::DATA_TYPE::WORD);
113 
114  // Some info
115  f.write(reinterpret_cast<const char*>(&_nbMaxInterpGap), 1*ezc3d::DATA_TYPE::WORD);
116  f.write(reinterpret_cast<const char*>(&_scaleFactor), 2*ezc3d::DATA_TYPE::WORD);
117 
118  // Parameters of analog data
119  dataStartPosition = f.tellg();
120  f.write(reinterpret_cast<const char*>(&_dataStart), 1*ezc3d::DATA_TYPE::WORD); // To be changed when we know where the data are
121  f.write(reinterpret_cast<const char*>(&_nbAnalogByFrame), 1*ezc3d::DATA_TYPE::WORD);
122  float frameRate(_frameRate);
123  f.write(reinterpret_cast<const char*>(&frameRate), 2*ezc3d::DATA_TYPE::WORD);
124  for (int i=0; i<135; ++i)
125  f.write(reinterpret_cast<const char*>(&_emptyBlock1), 1*ezc3d::DATA_TYPE::WORD);
126 
127  // Parameters of keys
128  f.write(reinterpret_cast<const char*>(&_keyLabelPresent), 1*ezc3d::DATA_TYPE::WORD);
129  f.write(reinterpret_cast<const char*>(&_firstBlockKeyLabel), 1*ezc3d::DATA_TYPE::WORD);
130  f.write(reinterpret_cast<const char*>(&_fourCharPresent), 1*ezc3d::DATA_TYPE::WORD);
131 
132  // Parameters of events
133  f.write(reinterpret_cast<const char*>(&_nbEvents), 1*ezc3d::DATA_TYPE::WORD);
134  f.write(reinterpret_cast<const char*>(&_emptyBlock2), 1*ezc3d::DATA_TYPE::WORD);
135  for (unsigned int i = 0; i < _eventsTime.size(); ++i)
136  f.write(reinterpret_cast<const char*>(&_eventsTime[i]), 2*ezc3d::DATA_TYPE::WORD);
137  for (unsigned int i = 0; i < _eventsDisplay.size(); ++i)
138  f.write(reinterpret_cast<const char*>(&_eventsDisplay[i]), 1*ezc3d::DATA_TYPE::WORD);
139  f.write(reinterpret_cast<const char*>(&_emptyBlock3), 1*ezc3d::DATA_TYPE::WORD);
140  for (unsigned int i = 0; i < _eventsLabel.size(); ++i){
141  const char* event = _eventsLabel[i].c_str();
142  f.write(event, 2*ezc3d::DATA_TYPE::WORD);
143  }
144  for (int i=0; i<22; ++i)
145  f.write(reinterpret_cast<const char*>(&_emptyBlock4), 1*ezc3d::DATA_TYPE::WORD);
146 }
147 
148 void ezc3d::Header::read(ezc3d::c3d &c3d, std::fstream &file)
149 {
150  // Parameter address assuming Intel processor
151  _parametersAddress = c3d.readUint(PROCESSOR_TYPE::INTEL, file, 1*ezc3d::DATA_TYPE::BYTE, 0, std::ios::beg);
152 
153  // For some reason, some Vicon's file has lot of "0" at the beginning of the file
154  // This part loop up to the point no 0 is found
155  while (!_parametersAddress){
156  _parametersAddress = c3d.readUint(PROCESSOR_TYPE::INTEL,file, 1*ezc3d::DATA_TYPE::BYTE);
157  if (file.eof())
158  throw std::ios_base::failure("File is empty");
159  ++_nbOfZerosBeforeHeader;
160  }
161 
162  _checksum = c3d.readUint(PROCESSOR_TYPE::INTEL, file, 1*ezc3d::DATA_TYPE::BYTE);
163  if (_checksum != 0x50) // If checkbyte is wrong
164  throw std::ios_base::failure("File must be a valid c3d file");
165 
166  // Find which formatting is used
167  ezc3d::PROCESSOR_TYPE processorType(readProcessorType(c3d, file));
168 
169  // Number of data
170  _nb3dPoints = c3d.readUint(processorType, file, 1*ezc3d::DATA_TYPE::WORD);
171  _nbAnalogsMeasurement = c3d.readUint(processorType, file, 1*ezc3d::DATA_TYPE::WORD);
172 
173  // Idx of first and last frame
174  _firstFrame = c3d.readUint(processorType, file, 1*ezc3d::DATA_TYPE::WORD);
175  if (_firstFrame != 0) // First frame is 1-based, but some forgot hence they put 0..
176  _firstFrame -= 1;
177  _lastFrame = c3d.readUint(processorType, file, 1*ezc3d::DATA_TYPE::WORD) - 1;
178  if (_lastFrame != 0) // Las frame is 1-based, but some forgot hence they put 0..
179  _lastFrame -= 1;
180 
181  // Some info
182  _nbMaxInterpGap = c3d.readUint(processorType, file, 1*ezc3d::DATA_TYPE::WORD);
183  _scaleFactor = c3d.readFloat(processorType, file, 2*ezc3d::DATA_TYPE::WORD);
184 
185  // Parameters of analog data
186  _dataStart = c3d.readUint(processorType, file, 1*ezc3d::DATA_TYPE::WORD);
187  _nbAnalogByFrame = c3d.readUint(processorType, file, 1*ezc3d::DATA_TYPE::WORD);
188  _frameRate = c3d.readFloat(processorType, file);
189  _emptyBlock1 = c3d.readInt(processorType, file, 135*ezc3d::DATA_TYPE::WORD);
190 
191  // Parameters of keys
192  _keyLabelPresent = c3d.readUint(processorType, file, 1*ezc3d::DATA_TYPE::WORD);
193  _firstBlockKeyLabel = c3d.readUint(processorType, file, 1*ezc3d::DATA_TYPE::WORD);
194  _fourCharPresent = c3d.readUint(processorType, file, 1*ezc3d::DATA_TYPE::WORD);
195 
196  // Parameters of events
197  _nbEvents = c3d.readUint(processorType, file, 1*ezc3d::DATA_TYPE::WORD);
198  _emptyBlock2 = c3d.readInt(processorType, file, 1*ezc3d::DATA_TYPE::WORD);
199  for (unsigned int i = 0; i < _eventsTime.size(); ++i)
200  _eventsTime[i] = c3d.readFloat(processorType, file);
201  for (unsigned int i = 0; i < _eventsDisplay.size(); ++i)
202  _eventsDisplay[i] = c3d.readUint(processorType, file, 1*ezc3d::DATA_TYPE::WORD);
203  _emptyBlock3 = c3d.readInt(processorType, file, 1*ezc3d::DATA_TYPE::WORD);
204  for (unsigned int i = 0; i<_eventsLabel.size(); ++i)
205  _eventsLabel[i] = c3d.readString(file, 2*ezc3d::DATA_TYPE::WORD);
206  _emptyBlock4 = c3d.readInt(processorType, file, 22*ezc3d::DATA_TYPE::WORD);
207 }
208 
210 {
211  return _nbOfZerosBeforeHeader;
212 }
213 
215 {
216  return _parametersAddress;
217 }
218 
220 {
221  // Remember the current position of the cursor
222  std::streampos dataPos = file.tellg();
223 
224  // Read the processor type (assuming Intel type)
225  size_t parametersAddress(c3d.readUint(PROCESSOR_TYPE::INTEL, file, 1*ezc3d::DATA_TYPE::BYTE, 0, std::ios::beg));
226  size_t processorType = c3d.readUint(PROCESSOR_TYPE::INTEL, file, 1*ezc3d::DATA_TYPE::BYTE, static_cast<int>(256*ezc3d::DATA_TYPE::WORD*(parametersAddress-1)) + 3*ezc3d::DATA_TYPE::BYTE, std::ios::beg);
227 
228  // Put back the cursor in the file
229  file.seekg(dataPos);
230 
231  if (processorType == 84)
232  return ezc3d::PROCESSOR_TYPE::INTEL;
233  else if (processorType == 85)
234  return ezc3d::PROCESSOR_TYPE::DEC;
235  else if (processorType == 86)
236  return ezc3d::PROCESSOR_TYPE::MIPS;
237  else
238  throw std::runtime_error("Could not read the processor type");
239 }
240 
242 {
243  return _checksum;
244 }
245 
247 {
248  return _nb3dPoints;
249 }
250 
251 void ezc3d::Header::nb3dPoints(size_t numberOfPoints)
252 {
253  _nb3dPoints = numberOfPoints;
254 }
255 
257 {
258  if (_nbAnalogByFrame == 0)
259  return 0;
260  else
261  return _nbAnalogsMeasurement / _nbAnalogByFrame;
262 }
263 
264 void ezc3d::Header::nbAnalogs(size_t nbOfAnalogs)
265 {
266  _nbAnalogsMeasurement = nbOfAnalogs * _nbAnalogByFrame;
267 }
268 
270 {
271  return _nbAnalogsMeasurement;
272 }
273 
275 {
276  if (nb3dPoints() == 0 && nbAnalogs() == 0)
277  return 0;
278  else
279  return _lastFrame - _firstFrame + 1;
280 }
281 
283 {
284  return _firstFrame;
285 }
286 
287 void ezc3d::Header::firstFrame(size_t frame)
288 {
289  _firstFrame = frame;
290 }
291 
293 {
294  return _lastFrame;
295 }
296 
297 void ezc3d::Header::lastFrame(size_t frame)
298 {
299  _lastFrame = frame;
300 }
301 
303 {
304  return _nbMaxInterpGap;
305 }
306 
308 {
309  return _scaleFactor;
310 }
311 
313 {
314  return _dataStart;
315 }
316 
318 {
319  return _nbAnalogByFrame;
320 }
321 
322 void ezc3d::Header::nbAnalogByFrame(size_t nbOfAnalogsByFrame)
323 {
324  size_t analogs(nbAnalogs());
325  _nbAnalogByFrame = nbOfAnalogsByFrame;
326  nbAnalogs(analogs);
327 }
328 
330 {
331  return _frameRate;
332 }
333 
334 void ezc3d::Header::frameRate(float pointFrameRate)
335 {
336  _frameRate = pointFrameRate;
337 }
338 
340 {
341  return _emptyBlock1;
342 }
343 
345 {
346  return _emptyBlock2;
347 }
348 
350 {
351  return _emptyBlock3;
352 }
353 
355 {
356  return _emptyBlock4;
357 }
358 
360 {
361  return _keyLabelPresent;
362 }
363 
365 {
366  return _firstBlockKeyLabel;
367 }
368 
370 {
371  return _fourCharPresent;
372 }
373 
375 {
376  return _nbEvents;
377 }
378 
379 const std::vector<float>& ezc3d::Header::eventsTime() const
380 {
381  return _eventsTime;
382 }
383 
384 float ezc3d::Header::eventsTime(size_t idx) const
385 {
386  try {
387  return _eventsTime.at(idx);
388  } catch(std::out_of_range) {
389  throw std::out_of_range("Header::eventsTime method is trying to access the event "
390  + std::to_string(idx) +
391  " while the maximum number of events is "
392  + std::to_string(nbEvents()) + ".");
393  }
394 }
395 
396 std::vector<size_t> ezc3d::Header::eventsDisplay() const
397 {
398  return _eventsDisplay;
399 }
400 
401 size_t ezc3d::Header::eventsDisplay(size_t idx) const{
402  try {
403  return _eventsDisplay.at(idx);
404  } catch(std::out_of_range) {
405  throw std::out_of_range("Header::eventsDisplay method is trying to access the event "
406  + std::to_string(idx) +
407  " while the maximum number of events is "
408  + std::to_string(nbEvents()) + ".");
409  }
410 }
411 
412 const std::vector<std::string>& ezc3d::Header::eventsLabel() const
413 {
414  return _eventsLabel;
415 }
416 
417 const std::string& ezc3d::Header::eventsLabel(size_t idx) const
418 {
419  try {
420  return _eventsLabel.at(idx);
421  } catch(std::out_of_range) {
422  throw std::out_of_range("Header::eventsLabel method is trying to access the event "
423  + std::to_string(idx) +
424  " while the maximum number of events is "
425  + std::to_string(nbEvents()) + ".");
426  }
427 }
int emptyBlock3() const
Get the empty block 3.
Definition: Header.cpp:349
std::vector< size_t > _eventsDisplay
Definition: Header.h:335
int emptyBlock4() const
Get the empty block 4.
Definition: Header.cpp:354
void write(std::fstream &f, std::streampos &dataStartPosition) const
Write the header to an opened file.
Definition: Header.cpp:94
size_t nbFrames() const
Get the number of frames.
Definition: Header.cpp:274
size_t readUint(PROCESSOR_TYPE processorType, std::fstream &file, unsigned int nByteToRead, int nByteFromPrevious=0, const std::ios_base::seekdir &pos=std::ios::cur)
Read a unsigned integer of nByteToRead bytes at the position current + nByteFromPrevious from a file...
Definition: ezc3d.cpp:203
size_t nbMaxInterpGap() const
Get the maximal gap used for interpolation.
Definition: Header.cpp:302
float frameRate() const
Get the points frame rate in Hz.
Definition: Header.cpp:329
PROCESSOR_TYPE
The type of processor used to store the data.
Definition: ezc3d.h:85
Declaration of Header class.
int emptyBlock1() const
Get the empty block 1.
Definition: Header.cpp:339
size_t checksum() const
Get the checksum of the header.
Definition: Header.cpp:241
size_t keyLabelPresent() const
Get the present label flag.
Definition: Header.cpp:359
std::vector< float > _eventsTime
Definition: Header.h:331
size_t lastFrame() const
Get the last frame.
Definition: Header.cpp:292
float scaleFactor() const
Get the scaling factor to convert the 3D point.
Definition: Header.cpp:307
size_t firstBlockKeyLabel() const
Get the first block of key labels (if present)
Definition: Header.cpp:364
size_t nbEvents() const
Get the number of defined time events (0 to 18)
Definition: Header.cpp:374
std::vector< std::string > _eventsLabel
Definition: Header.h:340
std::vector< size_t > eventsDisplay() const
Get the display flags.
Definition: Header.cpp:396
size_t fourCharPresent() const
fourCharPresent
Definition: Header.cpp:369
Main class for C3D holder.
Definition: ezc3d.h:154
size_t parametersAddress() const
Get the byte at which the parameters start in the file.
Definition: Header.cpp:214
size_t nbAnalogByFrame() const
Get the number of analog by frame.
Definition: Header.cpp:317
int emptyBlock2() const
Get the empty block 2.
Definition: Header.cpp:344
void read(c3d &c3d, std::fstream &file)
Read and store a header from an opened C3D file.
Definition: Header.cpp:148
size_t nbOfZerosBeforeHeader() const
Get the number of zeros before the header starts in the file.
Definition: Header.cpp:209
size_t firstFrame() const
Get the first frame.
Definition: Header.cpp:282
size_t dataStart() const
Get the number of 256-byte blocks to get to the points and analogous data in the file.
Definition: Header.cpp:312
const std::vector< float > & eventsTime() const
Get the event times in seconds.
Definition: Header.cpp:379
size_t nbAnalogsMeasurement() const
Get the number of recorded analogs.
Definition: Header.cpp:269
int readInt(PROCESSOR_TYPE processorType, std::fstream &file, unsigned int nByteToRead, int nByteFromPrevious=0, const std::ios_base::seekdir &pos=std::ios::cur)
Read an integer of nByteToRead bytes at the position current + nByteFromPrevious from a file...
Definition: ezc3d.cpp:179
std::string readString(std::fstream &file, unsigned int nByteToRead, int nByteFromPrevious=0, const std::ios_base::seekdir &pos=std::ios::cur)
Read a string (array of char of nByteToRead bytes) at the position current + nByteFromPrevious from a...
Definition: ezc3d.cpp:256
size_t nb3dPoints() const
Get the number 3D points.
Definition: Header.cpp:246
void print() const
Print the header.
Definition: Header.cpp:68
PROCESSOR_TYPE readProcessorType(c3d &c3d, std::fstream &file)
Reads the processor type in the parameter section, returns the file pointer where it was at the beggi...
Definition: Header.cpp:219
const std::vector< std::string > & eventsLabel() const
Get the event labels.
Definition: Header.cpp:412
size_t nbAnalogs() const
Get the number of analogs.
Definition: Header.cpp:256
Declaration of Parameters class.
float readFloat(PROCESSOR_TYPE processorType, std::fstream &file, int nByteFromPrevious=0, const std::ios_base::seekdir &pos=std::ios::cur)
Read a float at the position current + nByteFromPrevious from a file.
Definition: ezc3d.cpp:228
Header()
Create a valid header with minimal informations.
Definition: Header.cpp:13