laswriter_las.cpp
Go to the documentation of this file.
1 /*
2 ===============================================================================
3 
4  FILE: laswriter_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 "laswriter_las.hpp"
32 
33 #include "bytestreamout_nil.hpp"
34 #include "bytestreamout_file.hpp"
36 #include "laswritepoint.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 
47 {
48  if (stream == 0) return FALSE;
49  if (this->file) this->file = file;
50  return ((ByteStreamOutFile*)stream)->refile(file);
51 }
52 
53 BOOL LASwriterLAS::open(const LASheader* header, U32 compressor, I32 requested_version, I32 chunk_size)
54 {
55  ByteStreamOut* out = new ByteStreamOutNil();
56  return open(out, header, compressor, requested_version, chunk_size);
57 }
58 
59 BOOL LASwriterLAS::open(const char* file_name, const LASheader* header, U32 compressor, I32 requested_version, I32 chunk_size, U32 io_buffer_size)
60 {
61  if (file_name == 0)
62  {
63  fprintf(stderr,"ERROR: file name pointer is zero\n");
64  return FALSE;
65  }
66 
67  file = fopen(file_name, "wb");
68  if (file == 0)
69  {
70  fprintf(stderr, "ERROR: cannot open file '%s'\n", file_name);
71  return FALSE;
72  }
73 
74  if (setvbuf(file, NULL, _IOFBF, io_buffer_size) != 0)
75  {
76  fprintf(stderr, "WARNING: setvbuf() failed with buffer size %u\n", io_buffer_size);
77  }
78 
79  ByteStreamOut* out;
80  if (IS_LITTLE_ENDIAN())
81  out = new ByteStreamOutFileLE(file);
82  else
83  out = new ByteStreamOutFileBE(file);
84 
85  return open(out, header, compressor, requested_version, chunk_size);
86 }
87 
88 BOOL LASwriterLAS::open(FILE* file, const LASheader* header, U32 compressor, I32 requested_version, I32 chunk_size)
89 {
90  if (file == 0)
91  {
92  fprintf(stderr,"ERROR: file pointer is zero\n");
93  return FALSE;
94  }
95 
96 #ifdef _WIN32
97  if (file == stdout)
98  {
99  if(_setmode( _fileno( stdout ), _O_BINARY ) == -1 )
100  {
101  fprintf(stderr, "ERROR: cannot set stdout to binary (untranslated) mode\n");
102  }
103  }
104 #endif
105 
106  ByteStreamOut* out;
107  if (IS_LITTLE_ENDIAN())
108  out = new ByteStreamOutFileLE(file);
109  else
110  out = new ByteStreamOutFileBE(file);
111 
112  return open(out, header, compressor, requested_version, chunk_size);
113 }
114 
115 BOOL LASwriterLAS::open(ostream& stream, const LASheader* header, U32 compressor, I32 requested_version, I32 chunk_size)
116 {
117  ByteStreamOut* out;
118  if (IS_LITTLE_ENDIAN())
119  out = new ByteStreamOutOstreamLE(stream);
120  else
121  out = new ByteStreamOutOstreamBE(stream);
122 
123  return open(out, header, compressor, requested_version, chunk_size);
124 }
125 
126 BOOL LASwriterLAS::open(ByteStreamOut* stream, const LASheader* header, U32 compressor, I32 requested_version, I32 chunk_size)
127 {
128  U32 i;
129 
130  if (stream == 0)
131  {
132  fprintf(stderr,"ERROR: ByteStreamOut pointer is zero\n");
133  return FALSE;
134  }
135  this->stream = stream;
136 
137  if (header == 0)
138  {
139  fprintf(stderr,"ERROR: LASheader pointer is zero\n");
140  return FALSE;
141  }
142 
143  // check header contents
144 
145  if (!header->check()) return FALSE;
146 
147  // copy scale_and_offset
151  quantizer.x_offset = header->x_offset;
152  quantizer.y_offset = header->y_offset;
153  quantizer.z_offset = header->z_offset;
154 
155  // check if the requested point type is supported
156 
157  BOOL point_is_standard = TRUE;
158  U8 point_data_format;
159  U16 point_data_record_length;
160  LASpoint point;
161  if (header->laszip)
162  {
163  if (!point.init(&quantizer, header->laszip->num_items, header->laszip->items, header)) return FALSE;
164  point_is_standard = header->laszip->is_standard(&point_data_format, &point_data_record_length);
165  }
166  else
167  {
168  if (!point.init(&quantizer, header->point_data_format, header->point_data_record_length, header)) return FALSE;
169  point_data_format = header->point_data_format;
170  point_data_record_length = header->point_data_record_length;
171  }
172 
173  // do we need a laszip VLR (because we compress or use non-standard points?)
174 
175  LASzip* laszip = 0;
176  U32 laszip_vlr_data_size = 0;
177  if (compressor || point_is_standard == FALSE)
178  {
179  laszip = new LASzip();
180  laszip->setup(point.num_items, point.items, compressor);
181  if (chunk_size > -1) laszip->set_chunk_size((U32)chunk_size);
182  if (compressor == LASZIP_COMPRESSOR_NONE) laszip->request_version(0);
183  else if (requested_version) laszip->request_version(requested_version);
184  else laszip->request_version(2);
185  laszip_vlr_data_size = 34 + 6*laszip->num_items;
186  }
187 
188  // create and setup the point writer
189 
190  writer = new LASwritePoint();
191  if (laszip)
192  {
193  if (!writer->setup(laszip->num_items, laszip->items, laszip)) return FALSE;
194  }
195  else
196  {
197  if (!writer->setup(point.num_items, point.items)) return FALSE;
198  }
199 
200  // save the position where we start writing the header
201 
202  header_start_position = stream->tell();
203 
204  // write header variable after variable (to avoid alignment issues)
205 
206  if (!stream->putBytes((U8*)&(header->file_signature), 4))
207  {
208  fprintf(stderr,"ERROR: writing header->file_signature\n");
209  return FALSE;
210  }
211  if (!stream->put16bitsLE((U8*)&(header->file_source_id)))
212  {
213  fprintf(stderr,"ERROR: writing header->file_source_id\n");
214  return FALSE;
215  }
216  if (!stream->put16bitsLE((U8*)&(header->global_encoding)))
217  {
218  fprintf(stderr,"ERROR: writing header->global_encoding\n");
219  return FALSE;
220  }
221  if (!stream->put32bitsLE((U8*)&(header->project_ID_GUID_data_1)))
222  {
223  fprintf(stderr,"ERROR: writing header->project_ID_GUID_data_1\n");
224  return FALSE;
225  }
226  if (!stream->put16bitsLE((U8*)&(header->project_ID_GUID_data_2)))
227  {
228  fprintf(stderr,"ERROR: writing header->project_ID_GUID_data_2\n");
229  return FALSE;
230  }
231  if (!stream->put16bitsLE((U8*)&(header->project_ID_GUID_data_3)))
232  {
233  fprintf(stderr,"ERROR: writing header->project_ID_GUID_data_3\n");
234  return FALSE;
235  }
236  if (!stream->putBytes((U8*)&(header->project_ID_GUID_data_4), 8))
237  {
238  fprintf(stderr,"ERROR: writing header->project_ID_GUID_data_4\n");
239  return FALSE;
240  }
241  // check version major
242  if (header->version_major != 1)
243  {
244  fprintf(stderr,"WARNING: header->version_major is %d. writing 1 instead.\n", header->version_major);
245  if (!stream->putByte(1))
246  {
247  fprintf(stderr,"ERROR: writing header->version_major\n");
248  return FALSE;
249  }
250  }
251  else
252  {
253  if (!stream->putByte(header->version_major))
254  {
255  fprintf(stderr,"ERROR: writing header->version_major\n");
256  return FALSE;
257  }
258  }
259  // check version major
260  if (header->version_minor > 4)
261  {
262  fprintf(stderr,"WARNING: header->version_minor is %d. writing 4 instead.\n", header->version_minor);
263  if (!stream->putByte(4))
264  {
265  fprintf(stderr,"ERROR: writing header->version_minor\n");
266  return FALSE;
267  }
268  }
269  else
270  {
271  if (!stream->putByte(header->version_minor))
272  {
273  fprintf(stderr,"ERROR: writing header->version_minor\n");
274  return FALSE;
275  }
276  }
277  if (!stream->putBytes((U8*)&(header->system_identifier), 32))
278  {
279  fprintf(stderr,"ERROR: writing header->system_identifier\n");
280  return FALSE;
281  }
282  if (!stream->putBytes((U8*)&(header->generating_software), 32))
283  {
284  fprintf(stderr,"ERROR: writing header->generating_software\n");
285  return FALSE;
286  }
287  if (!stream->put16bitsLE((U8*)&(header->file_creation_day)))
288  {
289  fprintf(stderr,"ERROR: writing header->file_creation_day\n");
290  return FALSE;
291  }
292  if (!stream->put16bitsLE((U8*)&(header->file_creation_year)))
293  {
294  fprintf(stderr,"ERROR: writing header->file_creation_year\n");
295  return FALSE;
296  }
297  if (!stream->put16bitsLE((U8*)&(header->header_size)))
298  {
299  fprintf(stderr,"ERROR: writing header->header_size\n");
300  return FALSE;
301  }
302  U32 offset_to_point_data = header->offset_to_point_data;
303  if (laszip) offset_to_point_data += (54 + laszip_vlr_data_size);
304  if (header->vlr_lastiling) offset_to_point_data += (54 + 28);
305  if (!stream->put32bitsLE((U8*)&offset_to_point_data))
306  {
307  fprintf(stderr,"ERROR: writing header->offset_to_point_data\n");
308  return FALSE;
309  }
310  U32 number_of_variable_length_records = header->number_of_variable_length_records;
311  if (laszip) number_of_variable_length_records++;
312  if (header->vlr_lastiling) number_of_variable_length_records++;
313  if (!stream->put32bitsLE((U8*)&(number_of_variable_length_records)))
314  {
315  fprintf(stderr,"ERROR: writing header->number_of_variable_length_records\n");
316  return FALSE;
317  }
318  if (compressor) point_data_format |= 128;
319  if (!stream->putByte(point_data_format))
320  {
321  fprintf(stderr,"ERROR: writing header->point_data_format\n");
322  return FALSE;
323  }
324  if (!stream->put16bitsLE((U8*)&(header->point_data_record_length)))
325  {
326  fprintf(stderr,"ERROR: writing header->point_data_record_length\n");
327  return FALSE;
328  }
329  if (!stream->put32bitsLE((U8*)&(header->number_of_point_records)))
330  {
331  fprintf(stderr,"ERROR: writing header->number_of_point_records\n");
332  return FALSE;
333  }
334  for (i = 0; i < 5; i++)
335  {
336  if (!stream->put32bitsLE((U8*)&(header->number_of_points_by_return[i])))
337  {
338  fprintf(stderr,"ERROR: writing header->number_of_points_by_return[%d]\n", i);
339  return FALSE;
340  }
341  }
342  if (!stream->put64bitsLE((U8*)&(header->x_scale_factor)))
343  {
344  fprintf(stderr,"ERROR: writing header->x_scale_factor\n");
345  return FALSE;
346  }
347  if (!stream->put64bitsLE((U8*)&(header->y_scale_factor)))
348  {
349  fprintf(stderr,"ERROR: writing header->y_scale_factor\n");
350  return FALSE;
351  }
352  if (!stream->put64bitsLE((U8*)&(header->z_scale_factor)))
353  {
354  fprintf(stderr,"ERROR: writing header->z_scale_factor\n");
355  return FALSE;
356  }
357  if (!stream->put64bitsLE((U8*)&(header->x_offset)))
358  {
359  fprintf(stderr,"ERROR: writing header->x_offset\n");
360  return FALSE;
361  }
362  if (!stream->put64bitsLE((U8*)&(header->y_offset)))
363  {
364  fprintf(stderr,"ERROR: writing header->y_offset\n");
365  return FALSE;
366  }
367  if (!stream->put64bitsLE((U8*)&(header->z_offset)))
368  {
369  fprintf(stderr,"ERROR: writing header->z_offset\n");
370  return FALSE;
371  }
372  if (!stream->put64bitsLE((U8*)&(header->max_x)))
373  {
374  fprintf(stderr,"ERROR: writing header->max_x\n");
375  return FALSE;
376  }
377  if (!stream->put64bitsLE((U8*)&(header->min_x)))
378  {
379  fprintf(stderr,"ERROR: writing header->min_x\n");
380  return FALSE;
381  }
382  if (!stream->put64bitsLE((U8*)&(header->max_y)))
383  {
384  fprintf(stderr,"ERROR: writing header->max_y\n");
385  return FALSE;
386  }
387  if (!stream->put64bitsLE((U8*)&(header->min_y)))
388  {
389  fprintf(stderr,"ERROR: writing header->min_y\n");
390  return FALSE;
391  }
392  if (!stream->put64bitsLE((U8*)&(header->max_z)))
393  {
394  fprintf(stderr,"ERROR: writing header->max_z\n");
395  return FALSE;
396  }
397  if (!stream->put64bitsLE((U8*)&(header->min_z)))
398  {
399  fprintf(stderr,"ERROR: writing header->min_z\n");
400  return FALSE;
401  }
402 
403  // special handling for LAS 1.3 or higher.
404  if (header->version_minor >= 3)
405  {
406  // nobody currently includes waveform. we set the field always to zero
407  if (header->start_of_waveform_data_packet_record != 0)
408  {
409 #ifdef _WIN32
410  fprintf(stderr,"WARNING: header->start_of_waveform_data_packet_record is %I64d. writing 0 instead.\n", header->start_of_waveform_data_packet_record);
411 #else
412  fprintf(stderr,"WARNING: header->start_of_waveform_data_packet_record is %lld. writing 0 instead.\n", header->start_of_waveform_data_packet_record);
413 #endif
414  U64 start_of_waveform_data_packet_record = 0;
415  if (!stream->put64bitsLE((U8*)&start_of_waveform_data_packet_record))
416  {
417  fprintf(stderr,"ERROR: writing start_of_waveform_data_packet_record\n");
418  return FALSE;
419  }
420  }
421  else
422  {
423  if (!stream->put64bitsLE((U8*)&(header->start_of_waveform_data_packet_record)))
424  {
425  fprintf(stderr,"ERROR: writing header->start_of_waveform_data_packet_record\n");
426  return FALSE;
427  }
428  }
429  }
430 
431  // special handling for LAS 1.4 or higher.
432  if (header->version_minor >= 4)
433  {
435  {
436  fprintf(stderr,"ERROR: writing header->start_of_first_extended_variable_length_record\n");
437  return FALSE;
438  }
439  if (!stream->put32bitsLE((U8*)&(header->number_of_extended_variable_length_records)))
440  {
441  fprintf(stderr,"ERROR: writing header->number_of_extended_variable_length_records\n");
442  return FALSE;
443  }
444  U64 value;
445  if (header->number_of_point_records)
446  value = header->number_of_point_records;
447  else
448  value = header->extended_number_of_point_records;
449  if (!stream->put64bitsLE((U8*)&value))
450  {
451  fprintf(stderr,"ERROR: writing header->extended_number_of_point_records\n");
452  return FALSE;
453  }
454  for (i = 0; i < 15; i++)
455  {
456  if ((i < 5) && header->number_of_points_by_return[i])
457  value = header->number_of_points_by_return[i];
458  else
459  value = header->extended_number_of_points_by_return[i];
460  if (!stream->put64bitsLE((U8*)&value))
461  {
462  fprintf(stderr,"ERROR: writing header->extended_number_of_points_by_return[%d]\n", i);
463  return FALSE;
464  }
465  }
466  }
467 
468  // write any number of user-defined bytes that might have been added into the header
469 
470  if (header->user_data_in_header_size)
471  {
472  if (header->user_data_in_header)
473  {
474  if (!stream->putBytes((U8*)header->user_data_in_header, header->user_data_in_header_size))
475  {
476  fprintf(stderr,"ERROR: writing %d bytes of data from header->user_data_in_header\n", header->user_data_in_header_size);
477  return FALSE;
478  }
479  }
480  else
481  {
482  fprintf(stderr,"ERROR: there should be %d bytes of data in header->user_data_in_header\n", header->user_data_in_header_size);
483  return FALSE;
484  }
485  }
486 
487  // write variable length records variable after variable (to avoid alignment issues)
488 
489  for (i = 0; i < header->number_of_variable_length_records; i++)
490  {
491  // check variable length records contents
492 
493  if (header->vlrs[i].reserved != 0xAABB)
494  {
495 // fprintf(stderr,"WARNING: wrong header->vlrs[%d].reserved: %d != 0xAABB\n", i, header->vlrs[i].reserved);
496  }
497 
498  // write variable length records variable after variable (to avoid alignment issues)
499 
500  if (!stream->put16bitsLE((U8*)&(header->vlrs[i].reserved)))
501  {
502  fprintf(stderr,"ERROR: writing header->vlrs[%d].reserved\n", i);
503  return FALSE;
504  }
505  if (!stream->putBytes((U8*)header->vlrs[i].user_id, 16))
506  {
507  fprintf(stderr,"ERROR: writing header->vlrs[%d].user_id\n", i);
508  return FALSE;
509  }
510  if (!stream->put16bitsLE((U8*)&(header->vlrs[i].record_id)))
511  {
512  fprintf(stderr,"ERROR: writing header->vlrs[%d].record_id\n", i);
513  return FALSE;
514  }
515  if (!stream->put16bitsLE((U8*)&(header->vlrs[i].record_length_after_header)))
516  {
517  fprintf(stderr,"ERROR: writing header->vlrs[%d].record_length_after_header\n", i);
518  return FALSE;
519  }
520  if (!stream->putBytes((U8*)header->vlrs[i].description, 32))
521  {
522  fprintf(stderr,"ERROR: writing header->vlrs[%d].description\n", i);
523  return FALSE;
524  }
525 
526  // write the data following the header of the variable length record
527 
528  if (header->vlrs[i].record_length_after_header)
529  {
530  if (header->vlrs[i].data)
531  {
532  if (!stream->putBytes((U8*)header->vlrs[i].data, header->vlrs[i].record_length_after_header))
533  {
534  fprintf(stderr,"ERROR: writing %d bytes of data from header->vlrs[%d].data\n", header->vlrs[i].record_length_after_header, i);
535  return FALSE;
536  }
537  }
538  else
539  {
540  fprintf(stderr,"ERROR: there should be %d bytes of data in header->vlrs[%d].data\n", header->vlrs[i].record_length_after_header, i);
541  return FALSE;
542  }
543  }
544  }
545 
546  // write laszip VLR with compression parameters
547 
548  if (laszip)
549  {
550  // write variable length records variable after variable (to avoid alignment issues)
551 
552  U16 reserved = 0xAABB;
553  if (!stream->put16bitsLE((U8*)&(reserved)))
554  {
555  fprintf(stderr,"ERROR: writing reserved %d\n", (I32)reserved);
556  return FALSE;
557  }
558  U8 user_id[16] = "laszip encoded\0";
559  if (!stream->putBytes((U8*)user_id, 16))
560  {
561  fprintf(stderr,"ERROR: writing user_id %s\n", user_id);
562  return FALSE;
563  }
564  U16 record_id = 22204;
565  if (!stream->put16bitsLE((U8*)&(record_id)))
566  {
567  fprintf(stderr,"ERROR: writing record_id %d\n", (I32)record_id);
568  return FALSE;
569  }
570  U16 record_length_after_header = laszip_vlr_data_size;
571  if (!stream->put16bitsLE((U8*)&(record_length_after_header)))
572  {
573  fprintf(stderr,"ERROR: writing record_length_after_header %d\n", (I32)record_length_after_header);
574  return FALSE;
575  }
576  char description[32];
577  memset(description, 0, 32);
578  sprintf(description, "by laszip of LAStools (%d)", LAS_TOOLS_VERSION);
579  if (!stream->putBytes((U8*)description, 32))
580  {
581  fprintf(stderr,"ERROR: writing description %s\n", description);
582  return FALSE;
583  }
584  // write the data following the header of the variable length record
585  // U16 compressor 2 bytes
586  // U16 coder 2 bytes
587  // U8 version_major 1 byte
588  // U8 version_minor 1 byte
589  // U16 version_revision 2 bytes
590  // U32 options 4 bytes
591  // U32 chunk_size 4 bytes
592  // I64 num_points 8 bytes
593  // I64 num_bytes 8 bytes
594  // U16 num_items 2 bytes
595  // U16 type 2 bytes * num_items
596  // U16 size 2 bytes * num_items
597  // U16 version 2 bytes * num_items
598  // which totals 34+6*num_items
599 
600  if (!stream->put16bitsLE((U8*)&(laszip->compressor)))
601  {
602  fprintf(stderr,"ERROR: writing compressor %d\n", (I32)compressor);
603  return FALSE;
604  }
605  if (!stream->put16bitsLE((U8*)&(laszip->coder)))
606  {
607  fprintf(stderr,"ERROR: writing coder %d\n", (I32)laszip->coder);
608  return FALSE;
609  }
610  if (!stream->putByte(laszip->version_major))
611  {
612  fprintf(stderr,"ERROR: writing version_major %d\n", laszip->version_major);
613  return FALSE;
614  }
615  if (!stream->putByte(laszip->version_minor))
616  {
617  fprintf(stderr,"ERROR: writing version_minor %d\n", laszip->version_minor);
618  return FALSE;
619  }
620  if (!stream->put16bitsLE((U8*)&(laszip->version_revision)))
621  {
622  fprintf(stderr,"ERROR: writing version_revision %d\n", laszip->version_revision);
623  return FALSE;
624  }
625  if (!stream->put32bitsLE((U8*)&(laszip->options)))
626  {
627  fprintf(stderr,"ERROR: writing options %d\n", (I32)laszip->options);
628  return FALSE;
629  }
630  if (!stream->put32bitsLE((U8*)&(laszip->chunk_size)))
631  {
632  fprintf(stderr,"ERROR: writing chunk_size %d\n", laszip->chunk_size);
633  return FALSE;
634  }
635  if (!stream->put64bitsLE((U8*)&(laszip->num_points)))
636  {
637  fprintf(stderr,"ERROR: writing num_points %d\n", (I32)laszip->num_points);
638  return FALSE;
639  }
640  if (!stream->put64bitsLE((U8*)&(laszip->num_bytes)))
641  {
642  fprintf(stderr,"ERROR: writing num_bytes %d\n", (I32)laszip->num_bytes);
643  return FALSE;
644  }
645  if (!stream->put16bitsLE((U8*)&(laszip->num_items)))
646  {
647  fprintf(stderr,"ERROR: writing num_items %d\n", laszip->num_items);
648  return FALSE;
649  }
650  for (i = 0; i < laszip->num_items; i++)
651  {
652  if (!stream->put16bitsLE((U8*)&(laszip->items[i].type)))
653  {
654  fprintf(stderr,"ERROR: writing type %d of item %d\n", laszip->items[i].type, i);
655  return FALSE;
656  }
657  if (!stream->put16bitsLE((U8*)&(laszip->items[i].size)))
658  {
659  fprintf(stderr,"ERROR: writing size %d of item %d\n", laszip->items[i].size, i);
660  return FALSE;
661  }
662  if (!stream->put16bitsLE((U8*)&(laszip->items[i].version)))
663  {
664  fprintf(stderr,"ERROR: writing version %d of item %d\n", laszip->items[i].version, i);
665  return FALSE;
666  }
667  }
668  }
669 
670  // write laszip VLR with compression parameters
671 
672  if (header->vlr_lastiling)
673  {
674  // write variable length records variable after variable (to avoid alignment issues)
675 
676  U16 reserved = 0xAABB;
677  if (!stream->put16bitsLE((U8*)&(reserved)))
678  {
679  fprintf(stderr,"ERROR: writing reserved %d\n", (I32)reserved);
680  return FALSE;
681  }
682  U8 user_id[16] = "lastools tile\0\0";
683  if (!stream->putBytes((U8*)user_id, 16))
684  {
685  fprintf(stderr,"ERROR: writing user_id %s\n", user_id);
686  return FALSE;
687  }
688  U16 record_id = 22204;
689  if (!stream->put16bitsLE((U8*)&(record_id)))
690  {
691  fprintf(stderr,"ERROR: writing record_id %d\n", (I32)record_id);
692  return FALSE;
693  }
694  U16 record_length_after_header = 28;
695  if (!stream->put16bitsLE((U8*)&(record_length_after_header)))
696  {
697  fprintf(stderr,"ERROR: writing record_length_after_header %d\n", (I32)record_length_after_header);
698  return FALSE;
699  }
700  U8 description[32] = "LAStools tile for streaming TIN";
701  if (!stream->putBytes((U8*)description, 32))
702  {
703  fprintf(stderr,"ERROR: writing description %s\n", description);
704  return FALSE;
705  }
706 
707  // write the data following the header of the variable length record
708  // U32 level 4 bytes
709  // U32 level_index 4 bytes
710  // U32 implicit_levels + overlap bit + reversible bit 4 bytes
711  // F32 min_x 4 bytes
712  // F32 max_x 4 bytes
713  // F32 min_y 4 bytes
714  // F32 max_y 4 bytes
715  // which totals 28 bytes
716 
717  if (!stream->put32bitsLE((U8*)&(header->vlr_lastiling->level)))
718  {
719  fprintf(stderr,"ERROR: writing header->vlr_lastiling->level %u\n", header->vlr_lastiling->level);
720  return FALSE;
721  }
722  if (!stream->put32bitsLE((U8*)&(header->vlr_lastiling->level_index)))
723  {
724  fprintf(stderr,"ERROR: writing header->vlr_lastiling->level_index %u\n", header->vlr_lastiling->level_index);
725  return FALSE;
726  }
727  if (!stream->put32bitsLE(((U8*)header->vlr_lastiling)+8))
728  {
729  fprintf(stderr,"ERROR: writing header->vlr_lastiling->implicit_levels %u\n", header->vlr_lastiling->implicit_levels);
730  return FALSE;
731  }
732  if (!stream->put32bitsLE((U8*)&(header->vlr_lastiling->min_x)))
733  {
734  fprintf(stderr,"ERROR: writing header->vlr_lastiling->min_x %g\n", header->vlr_lastiling->min_x);
735  return FALSE;
736  }
737  if (!stream->put32bitsLE((U8*)&(header->vlr_lastiling->max_x)))
738  {
739  fprintf(stderr,"ERROR: writing header->vlr_lastiling->max_x %g\n", header->vlr_lastiling->max_x);
740  return FALSE;
741  }
742  if (!stream->put32bitsLE((U8*)&(header->vlr_lastiling->min_y)))
743  {
744  fprintf(stderr,"ERROR: writing header->vlr_lastiling->min_y %g\n", header->vlr_lastiling->min_y);
745  return FALSE;
746  }
747  if (!stream->put32bitsLE((U8*)&(header->vlr_lastiling->max_y)))
748  {
749  fprintf(stderr,"ERROR: writing header->vlr_lastiling->max_y %g\n", header->vlr_lastiling->max_y);
750  return FALSE;
751  }
752  }
753 
754  // write any number of user-defined bytes that might have been added after the header
755 
756  if (header->user_data_after_header_size)
757  {
758  if (header->user_data_after_header)
759  {
760  if (!stream->putBytes((U8*)header->user_data_after_header, header->user_data_after_header_size))
761  {
762  fprintf(stderr,"ERROR: writing %d bytes of data from header->user_data_after_header\n", header->user_data_after_header_size);
763  return FALSE;
764  }
765  }
766  else
767  {
768  fprintf(stderr,"ERROR: there should be %d bytes of data in header->user_data_after_header\n", header->user_data_after_header_size);
769  return FALSE;
770  }
771  }
772 
773  // initialize the point writer
774 
775  if (!writer->init(stream)) return FALSE;
776 
778  p_count = 0;
779 
780  return TRUE;
781 }
782 
784 {
785  p_count++;
786  return writer->write(point->point);
787 }
788 
790 {
791  return writer->chunk();
792 }
793 
794 BOOL LASwriterLAS::update_header(const LASheader* header, BOOL use_inventory, BOOL update_extra_bytes)
795 {
796  I32 i;
797  if (header == 0)
798  {
799  fprintf(stderr,"ERROR: header pointer is zero\n");
800  return FALSE;
801  }
802  if (stream == 0)
803  {
804  fprintf(stderr,"ERROR: stream pointer is zero\n");
805  return FALSE;
806  }
807  if (!stream->isSeekable())
808  {
809  fprintf(stderr,"ERROR: stream is not seekable\n");
810  return FALSE;
811  }
812  if (use_inventory && inventory.active())
813  {
816  {
817  fprintf(stderr,"ERROR: updating header->number_of_point_records\n");
818  return FALSE;
819  }
821  for (i = 0; i < 5; i++)
822  {
824  {
825  fprintf(stderr,"ERROR: updating header->number_of_points_by_return[%d]\n", i);
826  return FALSE;
827  }
828  }
830  F64 value;
831  value = header->get_x(inventory.raw_max_x);
832  if (!stream->put64bitsLE((U8*)&value))
833  {
834  fprintf(stderr,"ERROR: updating header->max_x\n");
835  return FALSE;
836  }
837  value = header->get_x(inventory.raw_min_x);
838  if (!stream->put64bitsLE((U8*)&value))
839  {
840  fprintf(stderr,"ERROR: updating header->min_x\n");
841  return FALSE;
842  }
843  value = header->get_y(inventory.raw_max_y);
844  if (!stream->put64bitsLE((U8*)&value))
845  {
846  fprintf(stderr,"ERROR: updating header->max_y\n");
847  return FALSE;
848  }
849  value = header->get_y(inventory.raw_min_y);
850  if (!stream->put64bitsLE((U8*)&value))
851  {
852  fprintf(stderr,"ERROR: updating header->min_y\n");
853  return FALSE;
854  }
855  value = header->get_z(inventory.raw_max_z);
856  if (!stream->put64bitsLE((U8*)&value))
857  {
858  fprintf(stderr,"ERROR: updating header->max_z\n");
859  return FALSE;
860  }
861  value = header->get_z(inventory.raw_min_z);
862  if (!stream->put64bitsLE((U8*)&value))
863  {
864  fprintf(stderr,"ERROR: updating header->min_z\n");
865  return FALSE;
866  }
867  }
868  else
869  {
871  if (!stream->put32bitsLE((U8*)&(header->number_of_point_records)))
872  {
873  fprintf(stderr,"ERROR: updating header->number_of_point_records\n");
874  return FALSE;
875  }
877  for (i = 0; i < 5; i++)
878  {
879  if (!stream->put32bitsLE((U8*)&(header->number_of_points_by_return[i])))
880  {
881  fprintf(stderr,"ERROR: updating header->number_of_points_by_return[%d]\n", i);
882  return FALSE;
883  }
884  }
886  if (!stream->put64bitsLE((U8*)&(header->max_x)))
887  {
888  fprintf(stderr,"ERROR: updating header->max_x\n");
889  return FALSE;
890  }
891  if (!stream->put64bitsLE((U8*)&(header->min_x)))
892  {
893  fprintf(stderr,"ERROR: updating header->min_x\n");
894  return FALSE;
895  }
896  if (!stream->put64bitsLE((U8*)&(header->max_y)))
897  {
898  fprintf(stderr,"ERROR: updating header->max_y\n");
899  return FALSE;
900  }
901  if (!stream->put64bitsLE((U8*)&(header->min_y)))
902  {
903  fprintf(stderr,"ERROR: updating header->min_y\n");
904  return FALSE;
905  }
906  if (!stream->put64bitsLE((U8*)&(header->max_z)))
907  {
908  fprintf(stderr,"ERROR: updating header->max_z\n");
909  return FALSE;
910  }
911  if (!stream->put64bitsLE((U8*)&(header->min_z)))
912  {
913  fprintf(stderr,"ERROR: updating header->min_z\n");
914  return FALSE;
915  }
916  }
917  if (update_extra_bytes)
918  {
919  if (header->number_extra_attributes)
920  {
921  I64 start = header_start_position + header->header_size;
922  for (i = 0; i < (I32)header->number_of_variable_length_records; i++)
923  {
924  start += 54;
925  if (header->vlrs[i].data == (char*)header->extra_attributes)
926  {
927  break;
928  }
929  else
930  {
931  start += header->vlrs[i].record_length_after_header;
932  }
933  }
934  stream->seek(start);
935  if (!stream->putBytes((U8*)header->vlrs[i].data, header->vlrs[i].record_length_after_header))
936  {
937  fprintf(stderr,"ERROR: writing %d bytes of data from header->vlrs[%d].data\n", header->vlrs[i].record_length_after_header, i);
938  return FALSE;
939  }
940  }
941  }
942  stream->seekEnd();
943  return TRUE;
944 }
945 
947 {
948  I64 bytes = 0;
949 
950  if (p_count != npoints)
951  {
952 #ifdef _WIN32
953  fprintf(stderr,"WARNING: written %I64d points but expected %I64d points\n", p_count, npoints);
954 #else
955  fprintf(stderr,"WARNING: written %lld points but expected %lld points\n", p_count, npoints);
956 #endif
957  }
958 
959  if (writer)
960  {
961  writer->done();
962  delete writer;
963  writer = 0;
964  }
965 
966  if (stream)
967  {
968  if (update_header && p_count != npoints)
969  {
970  if (!stream->isSeekable())
971  {
972 #ifdef _WIN32
973  fprintf(stderr, "ERROR: stream not seekable. cannot update header from %I64d to %I64d points.\n", npoints, p_count);
974 #else
975  fprintf(stderr, "ERROR: stream not seekable. cannot update header from %lld to %lld points.\n", npoints, p_count);
976 #endif
977  }
978  else
979  {
982  stream->seekEnd();
983  }
984  }
985  bytes = stream->tell() - header_start_position;
986  delete stream;
987  stream = 0;
988  }
989 
990  if (file)
991  {
992  fclose(file);
993  file = 0;
994  }
995 
996  npoints = p_count;
997  p_count = 0;
998 
999  return bytes;
1000 }
1001 
1003 {
1004  file = 0;
1005  stream = 0;
1006  writer = 0;
1007 }
1008 
1010 {
1011  if (writer || stream) close();
1012 }
BOOL IS_LITTLE_ENDIAN()
Definition: mydefs.hpp:144
BOOL write_point(const LASpoint *point)
virtual BOOL putBytes(const U8 *bytes, U32 num_bytes)=0
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]
BOOL update_header(const LASheader *header, BOOL use_inventory=TRUE, BOOL update_extra_bytes=FALSE)
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]
U16 point_data_record_length
LASquantizer quantizer
Definition: laswriter.hpp:50
U32 project_ID_GUID_data_1
U16 record_length_after_header
BOOL refile(FILE *file)
virtual BOOL seek(const I64 position)=0
U32 number_of_extended_variable_length_records
bool set_chunk_size(const unsigned int chunk_size)
Definition: laszip.cpp:462
unsigned int chunk_size
Definition: laszip.hpp:117
bool setup(unsigned short *num_items, LASitem **items, const unsigned char point_type, const unsigned short point_size, const unsigned short compressor=LASZIP_COMPRESSOR_NONE)
Definition: laszip.cpp:320
unsigned int U32
Definition: mydefs.hpp:39
virtual I64 tell() const =0
unsigned short compressor
Definition: laszip.hpp:111
U64 start_of_waveform_data_packet_record
U64 extended_number_of_point_records
LASvlr * vlrs
unsigned short U16
Definition: mydefs.hpp:40
BOOL init(const LASquantizer *quantizer, const U8 point_type, const U16 point_size, const LASattributer *attributer=0)
U32 number_of_point_records
Definition: lasutility.hpp:39
BOOL open(const LASheader *header, U32 compressor=LASZIP_COMPRESSOR_NONE, I32 requested_version=0, I32 chunk_size=50000)
BOOL init(ByteStreamOut *outstream)
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
U32 number_of_points_by_return[5]
unsigned char U8
Definition: mydefs.hpp:41
virtual BOOL put16bitsLE(const U8 *bytes)=0
U16 project_ID_GUID_data_2
I64 header_start_position
bool is_standard(const unsigned short num_items, const LASitem *items, unsigned char *point_type=0, unsigned short *record_length=0)
Definition: laszip.cpp:511
virtual BOOL putByte(U8 byte)=0
unsigned short version
Definition: laszip.hpp:75
virtual BOOL put64bitsLE(const U8 *bytes)=0
BOOL active() const
Definition: lasutility.hpp:39
unsigned int options
Definition: laszip.hpp:116
LASzip * laszip
I8 * user_data_after_header
I8 system_identifier[32]
U16 file_creation_year
unsigned short size
Definition: laszip.hpp:74
#define LASZIP_COMPRESSOR_NONE
Definition: laszip.hpp:53
unsigned short version_revision
Definition: laszip.hpp:115
U32 number_of_points_by_return[8]
Definition: lasutility.hpp:41
F64 get_y(const I32 y) const
virtual BOOL isSeekable() const =0
FILE * file
int I32
Definition: mydefs.hpp:35
SIGNED_INT64 num_points
Definition: laszip.hpp:118
I8 file_signature[4]
I64 npoints
Definition: laswriter.hpp:51
I8 description[32]
BOOL setup(const U32 num_items, const LASitem *items, const LASzip *laszip=0)
LASwritePoint * writer
LASitem * items
Definition: laszip.hpp:121
F64 get_z(const I32 z) const
virtual BOOL put32bitsLE(const U8 *bytes)=0
U32 user_data_in_header_size
unsigned short num_items
Definition: laszip.hpp:120
virtual BOOL seekEnd()=0
#define LAS_TOOLS_VERSION
LASinventory inventory
Definition: laswriter.hpp:53
U32 offset_to_point_data
#define TRUE
Definition: mydefs.hpp:137
unsigned long long U64
Definition: mydefs.hpp:47
I8 * user_data_in_header
LASitem * items
U16 project_ID_GUID_data_3
LASvlr_lastiling * vlr_lastiling
bool request_version(const unsigned short requested_version)
Definition: laszip.cpp:473
F64 get_x(const I32 x) const
ByteStreamOut * stream
U32 user_data_after_header_size
I64 close(BOOL update_npoints=true)
BOOL write(const U8 *const *point)
#define NULL
Definition: mydefs.hpp:141
I8 generating_software[32]
enum LASitem::Type type
I64 p_count
Definition: laswriter.hpp:52
LASattribute * extra_attributes
unsigned char version_major
Definition: laszip.hpp:113
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