lasreader_las.cpp
Go to the documentation of this file.
1 /*
2 ===============================================================================
3 
4  FILE: lasreader_las.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_las.hpp"
32 
33 #include "bytestreamin.hpp"
34 #include "bytestreamin_file.hpp"
35 #include "bytestreamin_istream.hpp"
36 #include "lasreadpoint.hpp"
37 
38 #ifdef _WIN32
39 #include <fcntl.h>
40 #include <io.h>
41 #endif
42 
43 #include <stdlib.h>
44 #include <string.h>
45 
46 BOOL LASreaderLAS::open(const char* file_name, U32 io_buffer_size)
47 {
48  if (file_name == 0)
49  {
50  fprintf(stderr,"ERROR: fine name pointer is zero\n");
51  return FALSE;
52  }
53 
54  file = fopen(file_name, "rb");
55  if (file == 0)
56  {
57  fprintf(stderr, "ERROR: cannot open file '%s'\n", file_name);
58  return FALSE;
59  }
60 
61  if (setvbuf(file, NULL, _IOFBF, io_buffer_size) != 0)
62  {
63  fprintf(stderr, "WARNING: setvbuf() failed with buffer size %u\n", io_buffer_size);
64  }
65 
66  // create input
67  ByteStreamIn* in;
68  if (IS_LITTLE_ENDIAN())
69  in = new ByteStreamInFileLE(file);
70  else
71  in = new ByteStreamInFileBE(file);
72 
73  return open(in);
74 }
75 
77 {
78  if (file == 0)
79  {
80  fprintf(stderr,"ERROR: file pointer is zero\n");
81  return FALSE;
82  }
83 
84 #ifdef _WIN32
85  if (file == stdin)
86  {
87  if(_setmode( _fileno( stdin ), _O_BINARY ) == -1 )
88  {
89  fprintf(stderr, "ERROR: cannot set stdin to binary (untranslated) mode\n");
90  return FALSE;
91  }
92  }
93 #endif
94 
95  // create input
96  ByteStreamIn* in;
97  if (IS_LITTLE_ENDIAN())
98  in = new ByteStreamInFileLE(file);
99  else
100  in = new ByteStreamInFileBE(file);
101 
102  return open(in);
103 }
104 
106 {
107  // create input
108  ByteStreamIn* in;
109  if (IS_LITTLE_ENDIAN())
110  in = new ByteStreamInIstreamLE(stream);
111  else
112  in = new ByteStreamInIstreamBE(stream);
113 
114  return open(in);
115 }
116 
118 {
119  U32 i,j;
120 
121  if (stream == 0)
122  {
123  fprintf(stderr,"ERROR: ByteStreamIn* pointer is zero\n");
124  return FALSE;
125  }
126 
127  this->stream = stream;
128 
129  // clean the header
130 
131  header.clean();
132 
133  // read the header variable after variable (to avoid alignment issues)
134 
135  try { stream->getBytes((U8*)&(header.file_signature), 4); } catch(...)
136  {
137  fprintf(stderr,"ERROR: reading header.file_signature\n");
138  return FALSE;
139  }
140  try { stream->get16bitsLE((U8*)&(header.file_source_id)); } catch(...)
141  {
142  fprintf(stderr,"ERROR: reading header.file_source_id\n");
143  return FALSE;
144  }
145  try { stream->get16bitsLE((U8*)&(header.global_encoding)); } catch(...)
146  {
147  fprintf(stderr,"ERROR: reading header.global_encoding\n");
148  return FALSE;
149  }
150  try { stream->get32bitsLE((U8*)&(header.project_ID_GUID_data_1)); } catch(...)
151  {
152  fprintf(stderr,"ERROR: reading header.project_ID_GUID_data_1\n");
153  return FALSE;
154  }
155  try { stream->get16bitsLE((U8*)&(header.project_ID_GUID_data_2)); } catch(...)
156  {
157  fprintf(stderr,"ERROR: reading header.project_ID_GUID_data_2\n");
158  return FALSE;
159  }
160  try { stream->get16bitsLE((U8*)&(header.project_ID_GUID_data_3)); } catch(...)
161  {
162  fprintf(stderr,"ERROR: reading header.project_ID_GUID_data_3\n");
163  return FALSE;
164  }
165  try { stream->getBytes((U8*)&(header.project_ID_GUID_data_4), 8); } catch(...)
166  {
167  fprintf(stderr,"ERROR: reading header.project_ID_GUID_data_4\n");
168  return FALSE;
169  }
170  try { stream->getBytes((U8*)&(header.version_major), 1); } catch(...)
171  {
172  fprintf(stderr,"ERROR: reading header.version_major\n");
173  return FALSE;
174  }
175  try { stream->getBytes((U8*)&(header.version_minor), 1); } catch(...)
176  {
177  fprintf(stderr,"ERROR: reading header.version_minor\n");
178  return FALSE;
179  }
180  try { stream->getBytes((U8*)&(header.system_identifier), 32); } catch(...)
181  {
182  fprintf(stderr,"ERROR: reading header.system_identifier\n");
183  return FALSE;
184  }
185  try { stream->getBytes((U8*)&(header.generating_software), 32); } catch(...)
186  {
187  fprintf(stderr,"ERROR: reading header.generating_software\n");
188  return FALSE;
189  }
190  try { stream->get16bitsLE((U8*)&(header.file_creation_day)); } catch(...)
191  {
192  fprintf(stderr,"ERROR: reading header.file_creation_day\n");
193  return FALSE;
194  }
195  try { stream->get16bitsLE((U8*)&(header.file_creation_year)); } catch(...)
196  {
197  fprintf(stderr,"ERROR: reading header.file_creation_year\n");
198  return FALSE;
199  }
200  try { stream->get16bitsLE((U8*)&(header.header_size)); } catch(...)
201  {
202  fprintf(stderr,"ERROR: reading header.header_size\n");
203  return FALSE;
204  }
205  try { stream->get32bitsLE((U8*)&(header.offset_to_point_data)); } catch(...)
206  {
207  fprintf(stderr,"ERROR: reading header.offset_to_point_data\n");
208  return FALSE;
209  }
210  try { stream->get32bitsLE((U8*)&(header.number_of_variable_length_records)); } catch(...)
211  {
212  fprintf(stderr,"ERROR: reading header.number_of_variable_length_records\n");
213  return FALSE;
214  }
215  try { stream->getBytes((U8*)&(header.point_data_format), 1); } catch(...)
216  {
217  fprintf(stderr,"ERROR: reading header.point_data_format\n");
218  return FALSE;
219  }
220  try { stream->get16bitsLE((U8*)&(header.point_data_record_length)); } catch(...)
221  {
222  fprintf(stderr,"ERROR: reading header.point_data_record_length\n");
223  return FALSE;
224  }
225  try { stream->get32bitsLE((U8*)&(header.number_of_point_records)); } catch(...)
226  {
227  fprintf(stderr,"ERROR: reading header.number_of_point_records\n");
228  return FALSE;
229  }
230  for (i = 0; i < 5; i++)
231  {
232  try { stream->get32bitsLE((U8*)&(header.number_of_points_by_return[i])); } catch(...)
233  {
234  fprintf(stderr,"ERROR: reading header.number_of_points_by_return %d\n", i);
235  return FALSE;
236  }
237  }
238  try { stream->get64bitsLE((U8*)&(header.x_scale_factor)); } catch(...)
239  {
240  fprintf(stderr,"ERROR: reading header.x_scale_factor\n");
241  return FALSE;
242  }
243  try { stream->get64bitsLE((U8*)&(header.y_scale_factor)); } catch(...)
244  {
245  fprintf(stderr,"ERROR: reading header.y_scale_factor\n");
246  return FALSE;
247  }
248  try { stream->get64bitsLE((U8*)&(header.z_scale_factor)); } catch(...)
249  {
250  fprintf(stderr,"ERROR: reading header.z_scale_factor\n");
251  return FALSE;
252  }
253  try { stream->get64bitsLE((U8*)&(header.x_offset)); } catch(...)
254  {
255  fprintf(stderr,"ERROR: reading header.x_offset\n");
256  return FALSE;
257  }
258  try { stream->get64bitsLE((U8*)&(header.y_offset)); } catch(...)
259  {
260  fprintf(stderr,"ERROR: reading header.y_offset\n");
261  return FALSE;
262  }
263  try { stream->get64bitsLE((U8*)&(header.z_offset)); } catch(...)
264  {
265  fprintf(stderr,"ERROR: reading header.z_offset\n");
266  return FALSE;
267  }
268  try { stream->get64bitsLE((U8*)&(header.max_x)); } catch(...)
269  {
270  fprintf(stderr,"ERROR: reading header.max_x\n");
271  return FALSE;
272  }
273  try { stream->get64bitsLE((U8*)&(header.min_x)); } catch(...)
274  {
275  fprintf(stderr,"ERROR: reading header.min_x\n");
276  return FALSE;
277  }
278  try { stream->get64bitsLE((U8*)&(header.max_y)); } catch(...)
279  {
280  fprintf(stderr,"ERROR: reading header.max_y\n");
281  return FALSE;
282  }
283  try { stream->get64bitsLE((U8*)&(header.min_y)); } catch(...)
284  {
285  fprintf(stderr,"ERROR: reading header.min_y\n");
286  return FALSE;
287  }
288  try { stream->get64bitsLE((U8*)&(header.max_z)); } catch(...)
289  {
290  fprintf(stderr,"ERROR: reading header.max_z\n");
291  return FALSE;
292  }
293  try { stream->get64bitsLE((U8*)&(header.min_z)); } catch(...)
294  {
295  fprintf(stderr,"ERROR: reading header.min_z\n");
296  return FALSE;
297  }
298 
299  // special handling for LAS 1.3
300  if ((header.version_major == 1) && (header.version_minor >= 3))
301  {
302  if (header.header_size < 235)
303  {
304  fprintf(stderr,"WARNING: for LAS 1.%d header_size should at least be 235 but it is only %d\n", header.version_minor, header.header_size);
306  }
307  else
308  {
309  try { stream->get64bitsLE((U8*)&(header.start_of_waveform_data_packet_record)); } catch(...)
310  {
311  fprintf(stderr,"ERROR: reading header.start_of_waveform_data_packet_record\n");
312  return FALSE;
313  }
315  }
316  }
317  else
318  {
320  }
321 
322  // special handling for LAS 1.4
323  if ((header.version_major == 1) && (header.version_minor >= 4))
324  {
325  if (header.header_size < 375)
326  {
327  fprintf(stderr,"ERROR: for LAS 1.%d header_size should at least be 375 but it is only %d\n", header.version_minor, header.header_size);
328  return FALSE;
329  }
330  else
331  {
332  try { stream->get64bitsLE((U8*)&(header.start_of_first_extended_variable_length_record)); } catch(...)
333  {
334  fprintf(stderr,"ERROR: reading header.start_of_first_extended_variable_length_record\n");
335  return FALSE;
336  }
337  try { stream->get32bitsLE((U8*)&(header.number_of_extended_variable_length_records)); } catch(...)
338  {
339  fprintf(stderr,"ERROR: reading header.number_of_extended_variable_length_records\n");
340  return FALSE;
341  }
342  try { stream->get64bitsLE((U8*)&(header.extended_number_of_point_records)); } catch(...)
343  {
344  fprintf(stderr,"ERROR: reading header.extended_number_of_point_records\n");
345  return FALSE;
346  }
348  {
350  {
352  }
353  }
354  for (i = 0; i < 15; i++)
355  {
356  try { stream->get64bitsLE((U8*)&(header.extended_number_of_points_by_return[i])); } catch(...)
357  {
358  fprintf(stderr,"ERROR: reading header.extended_number_of_points_by_return[%d]\n", i);
359  return FALSE;
360  }
361  if (i < 5)
362  {
364  {
366  {
368  }
369  }
370  }
371  }
373  }
374  if (header.point_data_format > 5)
375  {
376  fprintf(stderr,"WARNING: point type %d is cast to point type %d\n", header.point_data_format, (header.point_data_format == 6 ? 1 : (header.point_data_format == 7 || header.point_data_format == 8 ? 3 : (header.point_data_format == 9 ? 4 : 5))) );
377  }
378  }
379 
380  // load any number of user-defined bytes that might have been added to the header
382  {
384 
385  try { stream->getBytes((U8*)header.user_data_in_header, header.user_data_in_header_size); } catch(...)
386  {
387  fprintf(stderr,"ERROR: reading %d bytes of data into header.user_data_in_header\n", header.user_data_in_header_size);
388  return FALSE;
389  }
390  }
391 
392  // check header contents
393  if (!header.check())
394  {
395  return FALSE;
396  }
397 
398  // read the variable length records into the header
399 
400  U32 vlrs_size = 0;
401 
403  {
405 
406  for (i = 0; i < header.number_of_variable_length_records; i++)
407  {
408  // make sure there are enough bytes left to read a variable length record before the point block starts
409 
410  if (((int)header.offset_to_point_data - vlrs_size - header.header_size) < 54)
411  {
412  fprintf(stderr,"WARNING: only %d bytes until point block after reading %d of %d vlrs. skipping remaining vlrs ...\n", (int)header.offset_to_point_data - vlrs_size - header.header_size, i, header.number_of_variable_length_records);
414  break;
415  }
416 
417  // read variable length records variable after variable (to avoid alignment issues)
418 
419  try { stream->get16bitsLE((U8*)&(header.vlrs[i].reserved)); } catch(...)
420  {
421  fprintf(stderr,"ERROR: reading header.vlrs[%d].reserved\n", i);
422  return FALSE;
423  }
424 
425  try { stream->getBytes((U8*)header.vlrs[i].user_id, 16); } catch(...)
426  {
427  fprintf(stderr,"ERROR: reading header.vlrs[%d].user_id\n", i);
428  return FALSE;
429  }
430  try { stream->get16bitsLE((U8*)&(header.vlrs[i].record_id)); } catch(...)
431  {
432  fprintf(stderr,"ERROR: reading header.vlrs[%d].record_id\n", i);
433  return FALSE;
434  }
435  try { stream->get16bitsLE((U8*)&(header.vlrs[i].record_length_after_header)); } catch(...)
436  {
437  fprintf(stderr,"ERROR: reading header.vlrs[%d].record_length_after_header\n", i);
438  return FALSE;
439  }
440  try { stream->getBytes((U8*)header.vlrs[i].description, 32); } catch(...)
441  {
442  fprintf(stderr,"ERROR: reading header.vlrs[%d].description\n", i);
443  return FALSE;
444  }
445 
446  // keep track on the number of bytes we have read so far
447 
448  vlrs_size += 54;
449 
450  // check variable length record contents
451 
452  if (header.vlrs[i].reserved != 0xAABB)
453  {
454 // fprintf(stderr,"WARNING: wrong header.vlrs[%d].reserved: %d != 0xAABB\n", i, header.vlrs[i].reserved);
455  }
456 
457  // make sure there are enough bytes left to read the data of the variable length record before the point block starts
458 
460  {
461  fprintf(stderr,"WARNING: only %d bytes until point block when trying to read %d bytes into header.vlrs[%d].data\n", (int)header.offset_to_point_data - vlrs_size - header.header_size, header.vlrs[i].record_length_after_header, i);
463  }
464 
465  // load data following the header of the variable length record
466 
468  {
469  if (strcmp(header.vlrs[i].user_id, "laszip encoded") == 0)
470  {
471  header.laszip = new LASzip();
472 
473  // read this data following the header of the variable length record
474  // U16 compressor 2 bytes
475  // U32 coder 2 bytes
476  // U8 version_major 1 byte
477  // U8 version_minor 1 byte
478  // U16 version_revision 2 bytes
479  // U32 options 4 bytes
480  // I32 chunk_size 4 bytes
481  // I64 num_points 8 bytes
482  // I64 num_bytes 8 bytes
483  // U16 num_items 2 bytes
484  // U16 type 2 bytes * num_items
485  // U16 size 2 bytes * num_items
486  // U16 version 2 bytes * num_items
487  // which totals 34+6*num_items
488 
489  try { stream->get16bitsLE((U8*)&(header.laszip->compressor)); } catch(...)
490  {
491  fprintf(stderr,"ERROR: reading compressor %d\n", (I32)header.laszip->compressor);
492  return FALSE;
493  }
494  try { stream->get16bitsLE((U8*)&(header.laszip->coder)); } catch(...)
495  {
496  fprintf(stderr,"ERROR: reading coder %d\n", (I32)header.laszip->coder);
497  return FALSE;
498  }
499  try { stream->getBytes((U8*)&(header.laszip->version_major), 1); } catch(...)
500  {
501  fprintf(stderr,"ERROR: reading version_major %d\n", header.laszip->version_major);
502  return FALSE;
503  }
504  try { stream->getBytes((U8*)&(header.laszip->version_minor), 1); } catch(...)
505  {
506  fprintf(stderr,"ERROR: reading version_minor %d\n", header.laszip->version_minor);
507  return FALSE;
508  }
509  try { stream->get16bitsLE((U8*)&(header.laszip->version_revision)); } catch(...)
510  {
511  fprintf(stderr,"ERROR: reading version_revision %d\n", header.laszip->version_revision);
512  return FALSE;
513  }
514  try { stream->get32bitsLE((U8*)&(header.laszip->options)); } catch(...)
515  {
516  fprintf(stderr,"ERROR: reading options %d\n", (I32)header.laszip->options);
517  return FALSE;
518  }
519  try { stream->get32bitsLE((U8*)&(header.laszip->chunk_size)); } catch(...)
520  {
521  fprintf(stderr,"ERROR: reading chunk_size %d\n", header.laszip->chunk_size);
522  return FALSE;
523  }
524  try { stream->get64bitsLE((U8*)&(header.laszip->num_points)); } catch(...)
525  {
526  fprintf(stderr,"ERROR: reading num_points %d\n", (I32)header.laszip->num_points);
527  return FALSE;
528  }
529  try { stream->get64bitsLE((U8*)&(header.laszip->num_bytes)); } catch(...)
530  {
531  fprintf(stderr,"ERROR: reading num_bytes %d\n", (I32)header.laszip->num_bytes);
532  return FALSE;
533  }
534  try { stream->get16bitsLE((U8*)&(header.laszip->num_items)); } catch(...)
535  {
536  fprintf(stderr,"ERROR: reading num_items %d\n", header.laszip->num_items);
537  return FALSE;
538  }
540  for (j = 0; j < header.laszip->num_items; j++)
541  {
542  U16 type, size, version;
543  try { stream->get16bitsLE((U8*)&type); } catch(...)
544  {
545  fprintf(stderr,"ERROR: reading type %d of item %d\n", type, j);
546  return FALSE;
547  }
548  try { stream->get16bitsLE((U8*)&size); } catch(...)
549  {
550  fprintf(stderr,"ERROR: reading size %d of item %d\n", size, j);
551  return FALSE;
552  }
553  try { stream->get16bitsLE((U8*)&version); } catch(...)
554  {
555  fprintf(stderr,"ERROR: reading version %d of item %d\n", version, j);
556  return FALSE;
557  }
558  header.laszip->items[j].type = (LASitem::Type)type;
559  header.laszip->items[j].size = size;
560  header.laszip->items[j].version = version;
561  }
562  }
563  else if (strcmp(header.vlrs[i].user_id, "lastools tile") == 0 || strcmp(header.vlrs[i].user_id, "finalized tile") == 0 || strcmp(header.vlrs[i].user_id, "lastiling tile") == 0)
564  {
567 
568  // read this data following the header of the variable length record
569  // U32 level 4 bytes
570  // U32 level_index 4 bytes
571  // U32 implicit_levels + overlap bit + reversible bit 4 bytes
572  // F32 min_x 4 bytes
573  // F32 max_x 4 bytes
574  // F32 min_y 4 bytes
575  // F32 max_y 4 bytes
576  // which totals 28 bytes
577 
579  {
580  try { stream->get32bitsLE((U8*)&(header.vlr_lastiling->level)); } catch(...)
581  {
582  fprintf(stderr,"ERROR: reading vlr_lastiling->level %u\n", header.vlr_lastiling->level);
583  return FALSE;
584  }
585  try { stream->get32bitsLE((U8*)&(header.vlr_lastiling->level_index)); } catch(...)
586  {
587  fprintf(stderr,"ERROR: reading vlr_lastiling->level_index %u\n", header.vlr_lastiling->level_index);
588  return FALSE;
589  }
590  try { stream->get32bitsLE(((U8*)header.vlr_lastiling)+8); } catch(...)
591  {
592  fprintf(stderr,"ERROR: reading vlr_lastiling->implicit_levels %u\n", header.vlr_lastiling->implicit_levels);
593  return FALSE;
594  }
595  try { stream->get32bitsLE((U8*)&(header.vlr_lastiling->min_x)); } catch(...)
596  {
597  fprintf(stderr,"ERROR: reading vlr_lastiling->min_x %g\n", header.vlr_lastiling->min_x);
598  return FALSE;
599  }
600  try { stream->get32bitsLE((U8*)&(header.vlr_lastiling->max_x)); } catch(...)
601  {
602  fprintf(stderr,"ERROR: reading vlr_lastiling->max_x %g\n", header.vlr_lastiling->max_x);
603  return FALSE;
604  }
605  try { stream->get32bitsLE((U8*)&(header.vlr_lastiling->min_y)); } catch(...)
606  {
607  fprintf(stderr,"ERROR: reading vlr_lastiling->min_y %g\n", header.vlr_lastiling->min_y);
608  return FALSE;
609  }
610  try { stream->get32bitsLE((U8*)&(header.vlr_lastiling->max_y)); } catch(...)
611  {
612  fprintf(stderr,"ERROR: reading vlr_lastiling->max_y %g\n", header.vlr_lastiling->max_y);
613  return FALSE;
614  }
615  }
616  else
617  {
618  fprintf(stderr,"ERROR: record_length_after_header of %s VLR is %d instead of 28\n", header.vlrs[i].user_id, header.vlrs[i].record_length_after_header);
619  return FALSE;
620  }
621  }
622  else
623  {
625 
626  try { stream->getBytes((U8*)header.vlrs[i].data, header.vlrs[i].record_length_after_header); } catch(...)
627  {
628  fprintf(stderr,"ERROR: reading %d bytes of data into header.vlrs[%d].data\n", header.vlrs[i].record_length_after_header, i);
629  return FALSE;
630  }
631  }
632  }
633  else
634  {
635  header.vlrs[i].data = 0;
636  }
637 
638  // keep track on the number of bytes we have read so far
639 
640  vlrs_size += header.vlrs[i].record_length_after_header;
641 
642  // special handling for known variable header tags
643 
644  if (strcmp(header.vlrs[i].user_id, "LASF_Projection") == 0)
645  {
646  if (header.vlrs[i].record_id == 34735) // GeoKeyDirectoryTag
647  {
648  if (header.vlr_geo_keys)
649  {
650  fprintf(stderr,"WARNING: variable length records contain more than one GeoKeyDirectoryTag\n");
651  }
653 
654  // check variable header geo keys contents
655 
657  {
658  fprintf(stderr,"WARNING: wrong vlr_geo_keys->key_directory_version: %d != 1\n",header.vlr_geo_keys->key_directory_version);
659  }
660  if (header.vlr_geo_keys->key_revision != 1)
661  {
662  fprintf(stderr,"WARNING: wrong vlr_geo_keys->key_revision: %d != 1\n",header.vlr_geo_keys->key_revision);
663  }
665  {
666  fprintf(stderr,"WARNING: wrong vlr_geo_keys->minor_revision: %d != 0\n",header.vlr_geo_keys->minor_revision);
667  }
669  }
670  else if (header.vlrs[i].record_id == 34736) // GeoDoubleParamsTag
671  {
673  {
674  fprintf(stderr,"WARNING: variable length records contain more than one GeoF64ParamsTag\n");
675  }
677  }
678  else if (header.vlrs[i].record_id == 34737) // GeoAsciiParamsTag
679  {
681  {
682  fprintf(stderr,"WARNING: variable length records contain more than one GeoAsciiParamsTag\n");
683  }
685  }
686  }
687  else if (strcmp(header.vlrs[i].user_id, "LASF_Spec") == 0)
688  {
689  if (header.vlrs[i].record_id == 0) // ClassificationLookup
690  {
692  {
693  fprintf(stderr,"WARNING: variable length records contain more than one ClassificationLookup\n");
694  }
696  }
697  else if (header.vlrs[i].record_id == 2) // Histogram
698  {
699  }
700  else if (header.vlrs[i].record_id == 3) // TextAreaDescription
701  {
702  }
703  else if (header.vlrs[i].record_id == 4) // ExtraBytes
704  {
706  }
707  else if ((header.vlrs[i].record_id >= 100) && (header.vlrs[i].record_id < 355)) // WavePacketDescriptor
708  {
709  I32 idx = header.vlrs[i].record_id - 99;
710 
711  if (header.vlr_wave_packet_descr == 0)
712  {
714  for (j = 0; j < 256; j++) header.vlr_wave_packet_descr[j] = 0;
715  }
716  if (header.vlr_wave_packet_descr[idx])
717  {
718  fprintf(stderr,"WARNING: variable length records defines wave packet descr %d more than once\n", idx);
719  }
721  }
722  }
723  else if (strcmp(header.vlrs[i].user_id, "laszip encoded") == 0 || strcmp(header.vlrs[i].user_id, "lastools tile") == 0 || strcmp(header.vlrs[i].user_id, "finalized tile") == 0 || strcmp(header.vlrs[i].user_id, "lastiling tile") == 0)
724  {
725  // we take our own VLRs away from everywhere
727  vlrs_size -= (54+header.vlrs[i].record_length_after_header);
728  i--;
730  }
731  }
732  }
733 
734  if (header.laszip)
735  {
736  if (!header.laszip->check())
737  {
738  fprintf(stderr,"ERROR: %s\n", header.laszip->get_error());
739  fprintf(stderr," please upgrade to the latest release of LAStools (with LASzip)\n");
740  fprintf(stderr," or contact 'martin.isenburg@gmail.com' for assistance.\n");
741  return FALSE;
742  }
743  }
744 
745  // load any number of user-defined bytes that might have been added after the header
746 
749  {
751 
753  {
754  fprintf(stderr,"ERROR: reading %d bytes of data into header.user_data_after_header\n", header.user_data_after_header_size);
755  return FALSE;
756  }
757  }
758 
759  // remove extra bits in point data type
760 
761  if ((header.point_data_format & 128) || (header.point_data_format & 64))
762  {
763  if (!header.laszip)
764  {
765  fprintf(stderr,"ERROR: this file was compressed with an experimental version of laszip\n");
766  fprintf(stderr,"ERROR: please contact 'martin.isenburg@gmail.com' for assistance.\n");
767  return FALSE;
768  }
769  header.point_data_format &= 127;
770  }
771 
772  // create the point reader
773 
774  reader = new LASreadPoint();
775 
776  // initialize point and the reader
777 
778  if (header.laszip)
779  {
782  }
783  else
784  {
786  if (!reader->setup(point.num_items, point.items)) return FALSE;
787  }
788  if (!reader->init(stream)) return FALSE;
789 
791  p_count = 0;
792 
793  return TRUE;
794 }
795 
797 {
798  if (header.laszip)
799  {
801  }
802  return LAS_TOOLS_FORMAT_LAS;
803 }
804 
806 {
807  if (p_index < npoints)
808  {
809  if (reader->seek((U32)p_count, (U32)p_index))
810  {
811  p_count = p_index;
812  return TRUE;
813  }
814  }
815  return FALSE;
816 }
817 
819 {
820  if (p_count < npoints)
821  {
822  if (reader->read(point.point) == FALSE)
823  {
824  fprintf(stderr,"WARNING: end-of-file after %u of %u points\n", (U32)p_count, (U32)npoints);
825  return FALSE;
826  }
827  p_count++;
828  return TRUE;
829  }
830  return FALSE;
831 }
832 
834 {
835  return stream;
836 }
837 
838 void LASreaderLAS::close(BOOL close_stream)
839 {
840  if (reader)
841  {
842  reader->done();
843  delete reader;
844  reader = 0;
845  }
846  if (close_stream)
847  {
848  if (stream)
849  {
850  delete stream;
851  stream = 0;
852  }
853  if (file)
854  {
855  fclose(file);
856  file = 0;
857  }
858  }
859 }
860 
862 {
863  file = 0;
864  stream = 0;
865  reader = 0;
866 }
867 
869 {
870  if (reader || stream) close();
871 }
872 
873 LASreaderLASrescale::LASreaderLASrescale(F64 x_scale_factor, F64 y_scale_factor, F64 z_scale_factor) : LASreaderLAS()
874 {
875  scale_factor[0] = x_scale_factor;
876  scale_factor[1] = y_scale_factor;
877  scale_factor[2] = z_scale_factor;
878 }
879 
881 {
883  if (rescale_x)
884  {
886  point.x = I32_QUANTIZE(coordinate);
887  }
888  if (rescale_y)
889  {
891  point.y = I32_QUANTIZE(coordinate);
892  }
893  if (rescale_z)
894  {
896  point.z = I32_QUANTIZE(coordinate);
897  }
898  return TRUE;
899 }
900 
902 {
903  if (!LASreaderLAS::open(stream)) return FALSE;
904  // do we need to change anything
910  {
912  rescale_x = TRUE;
913  }
915  {
917  rescale_y = TRUE;
918  }
920  {
922  rescale_z = TRUE;
923  }
924  return TRUE;
925 }
926 
928 {
929  this->offset[0] = x_offset;
930  this->offset[1] = y_offset;
931  this->offset[2] = z_offset;
932 }
933 
935 {
937  if (reoffset_x)
938  {
940  point.x = I32_QUANTIZE(coordinate);
941  }
942  if (reoffset_y)
943  {
945  point.y = I32_QUANTIZE(coordinate);
946  }
947  if (reoffset_z)
948  {
950  point.z = I32_QUANTIZE(coordinate);
951  }
952  return TRUE;
953 }
954 
956 {
957  if (!LASreaderLAS::open(stream)) return FALSE;
958  // do we need to change anything
963  if (header.x_offset != offset[0])
964  {
965  header.x_offset = offset[0];
966  reoffset_x = TRUE;
967  }
968  if (header.y_offset != offset[1])
969  {
970  header.y_offset = offset[1];
971  reoffset_y = TRUE;
972  }
973  if (header.z_offset != offset[2])
974  {
975  header.z_offset = offset[2];
976  reoffset_z = TRUE;
977  }
978  return TRUE;
979 }
980 
981 LASreaderLASrescalereoffset::LASreaderLASrescalereoffset(F64 x_scale_factor, F64 y_scale_factor, F64 z_scale_factor, F64 x_offset, F64 y_offset, F64 z_offset) : LASreaderLASrescale(x_scale_factor, y_scale_factor, z_scale_factor), LASreaderLASreoffset(x_offset, y_offset, z_offset)
982 {
983 }
984 
986 {
988  if (reoffset_x)
989  {
991  point.x = I32_QUANTIZE(coordinate);
992  }
993  else if (rescale_x)
994  {
996  point.x = I32_QUANTIZE(coordinate);
997  }
998  if (reoffset_y)
999  {
1001  point.y = I32_QUANTIZE(coordinate);
1002  }
1003  else if (rescale_y)
1004  {
1006  point.y = I32_QUANTIZE(coordinate);
1007  }
1008  if (reoffset_z)
1009  {
1011  point.z = I32_QUANTIZE(coordinate);
1012  }
1013  else if (rescale_z)
1014  {
1016  point.z = I32_QUANTIZE(coordinate);
1017  }
1018  return TRUE;
1019 }
1020 
1022 {
1023  if (!LASreaderLASrescale::open(stream)) return FALSE;
1024  // do we need to change anything
1029  if (header.x_offset != offset[0])
1030  {
1031  header.x_offset = offset[0];
1032  reoffset_x = TRUE;
1033  }
1034  if (header.y_offset != offset[1])
1035  {
1036  header.y_offset = offset[1];
1037  reoffset_y = TRUE;
1038  }
1039  if (header.z_offset != offset[2])
1040  {
1041  header.z_offset = offset[2];
1042  reoffset_z = TRUE;
1043  }
1044  return TRUE;
1045 }
BOOL IS_LITTLE_ENDIAN()
Definition: mydefs.hpp:144
#define I32_QUANTIZE(n)
Definition: mydefs.hpp:111
SIGNED_INT64 num_bytes
Definition: laszip.hpp:119
int BOOL
Definition: mydefs.hpp:57
U64 start_of_first_extended_variable_length_record
U8 project_ID_GUID_data_4[8]
unsigned char version_minor
Definition: laszip.hpp:114
BOOL check() const
#define FALSE
Definition: mydefs.hpp:133
U32 number_of_point_records
I8 user_id[16]
F64 * vlr_geo_double_params
U16 point_data_record_length
U32 project_ID_GUID_data_1
LASheader header
Definition: lasreader.hpp:52
U16 record_length_after_header
U32 number_of_extended_variable_length_records
LASpoint point
Definition: lasreader.hpp:53
unsigned int chunk_size
Definition: laszip.hpp:117
unsigned int U32
Definition: mydefs.hpp:39
I64 p_count
Definition: lasreader.hpp:56
unsigned short compressor
Definition: laszip.hpp:111
U64 start_of_waveform_data_packet_record
U64 extended_number_of_point_records
BOOL open(ByteStreamIn *stream)
BOOL setup(const U32 num_items, const LASitem *items, const LASzip *laszip=0)
LASvlr * vlrs
I64 npoints
Definition: lasreader.hpp:55
LASreaderLASrescale(F64 x_scale_factor, F64 y_scale_factor, F64 z_scale_factor)
unsigned short U16
Definition: mydefs.hpp:40
BOOL init(const LASquantizer *quantizer, const U8 point_type, const U16 point_size, const LASattributer *attributer=0)
LASreaderLASrescalereoffset(F64 x_scale_factor, F64 y_scale_factor, F64 z_scale_factor, F64 x_offset, F64 y_offset, F64 z_offset)
#define LAS_TOOLS_FORMAT_LAS
LASvlr_key_entry * vlr_geo_key_entries
#define LAS_TOOLS_FORMAT_LAZ
const char * get_error() const
Definition: laszip.cpp:182
U32 number_of_variable_length_records
long long I64
Definition: mydefs.hpp:48
U64 extended_number_of_points_by_return[15]
unsigned short coder
Definition: laszip.hpp:112
bool check()
Definition: laszip.cpp:267
U32 number_of_points_by_return[5]
unsigned char U8
Definition: mydefs.hpp:41
BOOL read(U8 *const *point)
U16 project_ID_GUID_data_2
unsigned short version
Definition: laszip.hpp:75
BOOL seek(const U32 current, const U32 target)
LASvlr_geo_keys * vlr_geo_keys
LASvlr_wave_packet_descr ** vlr_wave_packet_descr
LASvlr_classification * vlr_classification
virtual void getBytes(U8 *bytes, const U32 num_bytes)=0
unsigned int options
Definition: laszip.hpp:116
ByteStreamIn * stream
LASzip * laszip
I8 * user_data_after_header
I8 system_identifier[32]
char I8
Definition: mydefs.hpp:37
U16 file_creation_year
unsigned short size
Definition: laszip.hpp:74
virtual BOOL read_point_default()
#define LASZIP_COMPRESSOR_NONE
Definition: laszip.hpp:53
I8 * vlr_geo_ascii_params
unsigned short version_revision
Definition: laszip.hpp:115
BOOL seek(const I64 p_index)
#define U32_MAX
Definition: mydefs.hpp:75
virtual void get64bitsLE(U8 *bytes)=0
int I32
Definition: mydefs.hpp:35
SIGNED_INT64 num_points
Definition: laszip.hpp:118
I8 file_signature[4]
virtual BOOL open(ByteStreamIn *stream)
virtual ~LASreaderLAS()
I8 description[32]
LASitem * items
Definition: laszip.hpp:121
U32 user_data_in_header_size
BOOL open(const char *file_name, U32 io_buffer_size=65536)
virtual void get32bitsLE(U8 *bytes)=0
unsigned short num_items
Definition: laszip.hpp:120
ByteStreamIn * get_stream() const
virtual BOOL read_point_default()
U32 offset_to_point_data
#define TRUE
Definition: mydefs.hpp:137
I8 * user_data_in_header
LASitem * items
U16 project_ID_GUID_data_3
BOOL init_extra_attributes(U32 number_extra_attributes, LASattribute *extra_attributes)
BOOL init(ByteStreamIn *instream)
LASvlr_lastiling * vlr_lastiling
I32 get_format() const
U32 user_data_after_header_size
virtual BOOL open(ByteStreamIn *stream)
virtual BOOL read_point_default()
void close(BOOL close_stream=TRUE)
#define NULL
Definition: mydefs.hpp:141
I8 generating_software[32]
enum LASitem::Type type
virtual void get16bitsLE(U8 *bytes)=0
unsigned char version_major
Definition: laszip.hpp:113
LASreaderLASreoffset(F64 x_offset, F64 y_offset, F64 z_offset)
double F64
Definition: mydefs.hpp:52
LASreadPoint * reader
void clean_lastiling()


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