lasreader_bin.cpp
Go to the documentation of this file.
1 /*
2 ===============================================================================
3 
4  FILE: lasreader_bin.cpp
5 
6  CONTENTS:
7 
8  see corresponding header file
9 
10  PROGRAMMERS:
11 
12  martin.isenburg@gmail.com
13 
14  COPYRIGHT:
15 
16  (c) 2007-2011, Martin Isenburg, LASSO - tools to catch reality
17 
18  This is free software; you can redistribute and/or modify it under the
19  terms of the GNU Lesser General Licence as published by the Free Software
20  Foundation. See the COPYING file for more information.
21 
22  This software is distributed WITHOUT ANY WARRANTY and without even the
23  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
24 
25  CHANGE HISTORY:
26 
27  see corresponding header file
28 
29 ===============================================================================
30 */
31 #include "lasreader_bin.hpp"
32 
33 #include "bytestreamin.hpp"
34 #include "bytestreamin_file.hpp"
35 
36 #include <stdlib.h>
37 #include <string.h>
38 
39 #ifdef _WIN32
40 #include <windows.h>
41 #endif
42 
43 struct TSrow
44 {
48  I32 x;
49  I32 y;
50  I32 z;
51 };
52 
53 struct TSpoint
54 {
55  I32 x;
56  I32 y;
57  I32 z;
64 };
65 
66 struct TSheader
67 {
71  I8 recog_str[4];
79 };
80 
81 BOOL LASreaderBIN::open(const char* file_name)
82 {
83  if (file_name == 0)
84  {
85  fprintf(stderr,"ERROR: fine name pointer is zero\n");
86  return FALSE;
87  }
88 
89  // open file
90 
91  file = fopen(file_name, "rb");
92  if (file == 0)
93  {
94  fprintf(stderr, "ERROR: cannot open file '%s'\n", file_name);
95  return FALSE;
96  }
97 
98  // create input stream
99 
100  ByteStreamIn* in;
101  if (IS_LITTLE_ENDIAN())
102  in = new ByteStreamInFileLE(file);
103  else
104  in = new ByteStreamInFileBE(file);
105 
106  // clean header
107 
108  header.clean();
109 
110  // maybe set creation date
111 
112 #ifdef _WIN32
113  WIN32_FILE_ATTRIBUTE_DATA attr;
114  SYSTEMTIME creation;
115  GetFileAttributesEx(file_name, GetFileExInfoStandard, &attr);
116  FileTimeToSystemTime(&attr.ftCreationTime, &creation);
117  int startday[13] = {-1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
118  header.file_creation_day = startday[creation.wMonth] + creation.wDay;
119  header.file_creation_year = creation.wYear;
120  // leap year handling
121  if ((((creation.wYear)%4) == 0) && (creation.wMonth > 2)) header.file_creation_day++;
122 #else
123  header.file_creation_day = 333;
124  header.file_creation_year = 2011;
125 #endif
126 
127  return open(in);
128 }
129 
131 {
132  int i;
133 
134  if (stream == 0)
135  {
136  fprintf(stderr,"ERROR: ByteStreamIn* pointer is zero\n");
137  return FALSE;
138  }
139 
140  this->stream = stream;
141 
142  // read the TS header
143 
144  TSheader tsheader;
145  try { stream->getBytes((U8*)&tsheader, sizeof(TSheader)); } catch(...)
146  {
147  fprintf(stderr,"ERROR: reading terrasolid header\n");
148  return FALSE;
149  }
150 
151  // check the TS header
152 
153  if (tsheader.size != sizeof(TSheader))
154  {
155  fprintf(stderr,"ERROR: corrupt terrasolid header. size != 56.\n");
156  return FALSE;
157  }
158 
159  if (tsheader.recog_val != 970401)
160  {
161  fprintf(stderr,"ERROR: corrupt terrasolid header. recog_val != 979401.\n");
162  return FALSE;
163  }
164 
165  if (strncmp(tsheader.recog_str, "CXYZ", 4) != 0)
166  {
167  fprintf(stderr,"ERROR: corrupt terrasolid header. recog_str != CXYZ.\n");
168  return FALSE;
169  }
170 
171  version = tsheader.version;
172 
173  // populate the header as much as possible
174 
175  for (i = 0; i < 32; i++)
176  {
177  header.system_identifier[i] = '\0';
178  header.generating_software[i] = '\0';
179  }
180  sprintf(header.system_identifier, "LAStools (c) by Martin Isenburg");
181  sprintf(header.generating_software, "via LASreaderBIN (%d)", LAS_TOOLS_VERSION);
182 
183  if (tsheader.time)
184  {
185  if (tsheader.rgb)
186  {
187  header.point_data_format = 3;
188  header.point_data_record_length = 34;
189  }
190  else
191  {
192  header.point_data_format = 1;
193  header.point_data_record_length = 28;
194  }
195  }
196  else
197  {
198  if (tsheader.rgb)
199  {
200  header.point_data_format = 2;
201  header.point_data_record_length = 26;
202  }
203  else
204  {
205  header.point_data_format = 0;
206  header.point_data_record_length = 20;
207  }
208  }
209 
210  header.number_of_point_records = tsheader.npoints;
211  npoints = tsheader.npoints;
212 
213  F64 scale = 1.0/(F64)tsheader.units;
214  header.x_scale_factor = scale;
215  header.y_scale_factor = scale;
216  header.z_scale_factor = scale;
217  header.x_offset = -tsheader.origin_x*scale;
218  header.y_offset = -tsheader.origin_y*scale;
219  header.z_offset = -tsheader.origin_z*scale;
220 
221  // initialize point
222 
223  point.init(&header, header.point_data_format, header.point_data_record_length);
224 
225  // set point count to zero
226 
227  p_count = 0;
228 
229  // approximate bounding box init
230 
231  if (!read_point()) return FALSE;
232 
233  header.min_x = header.max_x = point.get_x();
234  header.min_y = header.max_y = point.get_y();
235  header.min_z = header.max_z = point.get_z();
236 
237  for (i = tsheader.npoints/10; i < tsheader.npoints; i += tsheader.npoints/10)
238  {
239  if (!seek(i)) return FALSE;
240  if (!read_point()) return FALSE;
241  }
242 
243  header.number_of_points_by_return[0] = 0;
244  header.number_of_points_by_return[1] = 0;
245 
246  return seek(0);
247 }
248 
250 {
251  if (p_index < npoints)
252  {
253  long pos = sizeof(TSheader);
254  if (version == 20020715)
255  pos += (sizeof(TSpoint)*(U32)p_index);
256  else
257  pos += (sizeof(TSrow)*(U32)p_index);
258  if (point.have_gps_time)
259  pos += (sizeof(U32)*(U32)p_index);
260  if (point.have_rgb)
261  pos += (sizeof(U32)*(U32)p_index);
262  p_count = p_index;
263  return stream->seek(pos);
264  }
265  return FALSE;
266 }
267 
269 {
270  if (p_count < npoints)
271  {
272  int echo;
273  if (version == 20020715)
274  {
275  TSpoint tspoint;
276  try { stream->getBytes((U8*)&tspoint, sizeof(TSpoint)); } catch(...)
277  {
278  fprintf(stderr,"ERROR: reading terrasolid point after %u of %u\n", (U32)p_count, (U32)npoints);
279  return FALSE;
280  }
281  point.x = tspoint.x;
282  point.y = tspoint.y;
283  point.z = tspoint.z;
284  point.intensity = tspoint.intensity;
285  point.classification = tspoint.code;
286  point.point_source_ID = tspoint.line;
287  echo = tspoint.echo;
288  }
289  else
290  {
291  TSrow tsrow;
292  try { stream->getBytes((U8*)&tsrow, sizeof(TSrow)); } catch(...)
293  {
294  fprintf(stderr,"ERROR: reading terrasolid row after %u of %u\n", (U32)p_count, (U32)npoints);
295  return FALSE;
296  }
297  point.x = tsrow.x;
298  point.y = tsrow.y;
299  point.z = tsrow.z;
300  point.intensity = tsrow.echo_intensity & 0x3FFF;
301  point.classification = tsrow.code;
302  point.point_source_ID = tsrow.line;
303  echo = tsrow.echo_intensity >> 14;
304  }
305 
306  if (header.min_x > point.get_x()) header.min_x = point.get_x();
307  else if (header.max_x < point.get_x()) header.max_x = point.get_x();
308  if (header.min_y > point.get_y()) header.min_y = point.get_y();
309  else if (header.max_y < point.get_y()) header.max_y = point.get_y();
310  if (header.min_z > point.get_z()) header.min_z = point.get_z();
311  else if (header.max_z < point.get_z()) header.max_z = point.get_z();
312 
313  if (echo == 0) // only echo
314  {
315  point.number_of_returns_of_given_pulse = 1;
316  point.return_number = 1;
317  header.number_of_points_by_return[0]++;
318  }
319  else if (echo == 1) // first (of many)
320  {
321  point.number_of_returns_of_given_pulse = 2;
322  point.return_number = 1;
323  header.number_of_points_by_return[0]++;
324  }
325  else if (echo == 3) // last (of many)
326  {
327  point.number_of_returns_of_given_pulse = 2;
328  point.return_number = 2;
329  header.number_of_points_by_return[1]++;
330  }
331  else // intermediate
332  {
333  point.number_of_returns_of_given_pulse = 3;
334  point.return_number = 2;
335  header.number_of_points_by_return[1]++;
336  }
337 
338  if (point.have_gps_time)
339  {
340  U32 time;
341  try { stream->getBytes((U8*)&time, sizeof(U32)); } catch(...)
342  {
343  fprintf(stderr,"ERROR: reading terrasolid time\n");
344  return FALSE;
345  }
346  point.gps_time = 0.0002*time;
347  }
348 
349  if (point.have_rgb)
350  {
351  U8 rgba[4];
352  try { stream->getBytes((U8*)rgba, sizeof(U8)*4); } catch(...)
353  {
354  fprintf(stderr,"ERROR: reading terrasolid color\n");
355  return FALSE;
356  }
357  point.rgb[0] = 256*rgba[0];
358  point.rgb[1] = 256*rgba[1];
359  point.rgb[2] = 256*rgba[2];
360  }
361  p_count++;
362  return TRUE;
363  }
364  return FALSE;
365 }
366 
368 {
369  return stream;
370 }
371 
372 void LASreaderBIN::close(BOOL close_stream)
373 {
374  if (close_stream)
375  {
376  if (stream)
377  {
378  delete stream;
379  stream = 0;
380  }
381  if (file)
382  {
383  fclose(file);
384  file = 0;
385  }
386  }
387 }
388 
390 {
391  file = 0;
392  stream = 0;
393 }
394 
396 {
397  if (stream) close();
398 }
399 
400 LASreaderBINrescale::LASreaderBINrescale(F64 x_scale_factor, F64 y_scale_factor, F64 z_scale_factor) : LASreaderBIN()
401 {
402  scale_factor[0] = x_scale_factor;
403  scale_factor[1] = y_scale_factor;
404  scale_factor[2] = z_scale_factor;
405 }
406 
408 {
409  if (!LASreaderBIN::open(stream)) return FALSE;
410  // do we need to change anything
412  {
414  }
416  {
418  }
420  {
422  }
423  return TRUE;
424 }
425 
427 {
428  this->offset[0] = x_offset;
429  this->offset[1] = y_offset;
430  this->offset[2] = z_offset;
431 }
432 
434 {
435  if (!LASreaderBIN::open(stream)) return FALSE;
436  // do we need to change anything
437  if (header.x_offset != offset[0])
438  {
439  header.x_offset = offset[0];
440  }
441  if (header.y_offset != offset[1])
442  {
443  header.y_offset = offset[1];
444  }
445  if (header.z_offset != offset[2])
446  {
447  header.z_offset = offset[2];
448  }
449  return TRUE;
450 }
451 
452 LASreaderBINrescalereoffset::LASreaderBINrescalereoffset(F64 x_scale_factor, F64 y_scale_factor, F64 z_scale_factor, F64 x_offset, F64 y_offset, F64 z_offset) : LASreaderBINrescale(x_scale_factor, y_scale_factor, z_scale_factor), LASreaderBINreoffset(x_offset, y_offset, z_offset)
453 {
454 }
455 
457 {
458  if (!LASreaderBIN::open(stream)) return FALSE;
459  // do we need to change anything
461  {
463  }
465  {
467  }
469  {
471  }
472  if (header.x_offset != offset[0])
473  {
474  header.x_offset = offset[0];
475  }
476  if (header.y_offset != offset[1])
477  {
478  header.y_offset = offset[1];
479  }
480  if (header.z_offset != offset[2])
481  {
482  header.z_offset = offset[2];
483  }
484  return TRUE;
485 }
BOOL IS_LITTLE_ENDIAN()
Definition: mydefs.hpp:144
LASreaderBINrescalereoffset(F64 x_scale_factor, F64 y_scale_factor, F64 z_scale_factor, F64 x_offset, F64 y_offset, F64 z_offset)
BOOL open(const char *file_name)
int BOOL
Definition: mydefs.hpp:57
virtual BOOL open(ByteStreamIn *stream)
#define FALSE
Definition: mydefs.hpp:133
LASreaderBINreoffset(F64 x_offset, F64 y_offset, F64 z_offset)
LASheader header
Definition: lasreader.hpp:52
U16 echo_intensity
unsigned int U32
Definition: mydefs.hpp:39
unsigned short U16
Definition: mydefs.hpp:40
long long I64
Definition: mydefs.hpp:48
unsigned char U8
Definition: mydefs.hpp:41
ByteStreamIn * get_stream() const
BOOL seek(const I64 p_index)
virtual void getBytes(U8 *bytes, const U32 num_bytes)=0
char I8
Definition: mydefs.hpp:37
ByteStreamIn * stream
FILE * file
int I32
Definition: mydefs.hpp:35
virtual ~LASreaderBIN()
virtual BOOL open(ByteStreamIn *stream)
void close(BOOL close_stream=TRUE)
BOOL read_point_default()
LASreaderBINrescale(F64 x_scale_factor, F64 y_scale_factor, F64 z_scale_factor)
#define LAS_TOOLS_VERSION
BOOL open(ByteStreamIn *stream)
#define TRUE
Definition: mydefs.hpp:137
std::shared_ptr< HighFive::File > open(const std::string &filename)
Definition: Hdf5Util.cpp:202
I8 recog_str[4]
double F64
Definition: mydefs.hpp:52


lvr2
Author(s): Thomas Wiemann , Sebastian Pütz , Alexander Mock , Lars Kiesow , Lukas Kalbertodt , Tristan Igelbrink , Johan M. von Behren , Dominik Feldschnieders , Alexander Löhr
autogenerated on Mon Feb 28 2022 22:46:07