laswriter_bin.cpp
Go to the documentation of this file.
1 /*
2 ===============================================================================
3 
4  FILE: laswriter_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 "laswriter_bin.hpp"
32 
33 #include "bytestreamout_file.hpp"
34 
35 #ifdef _WIN32
36 #include <fcntl.h>
37 #include <io.h>
38 #endif
39 
40 #include <stdlib.h>
41 #include <string.h>
42 
43 struct TSrow
44 {
45  U8 code;
46  U8 line;
48  I32 x;
49  I32 y;
50  I32 z;
51 };
52 
53 struct TSpoint
54 {
55  I32 x;
56  I32 y;
57  I32 z;
58  U8 code;
59  U8 echo;
60  U8 flag;
61  U8 mark;
62  U16 line;
63  U16 intensity;
64 };
65 
66 struct TSheader
67 {
68  I32 size;
69  I32 version;
70  I32 recog_val;
71  I8 recog_str[4];
72  I32 npoints;
73  I32 units;
74  F64 origin_x;
75  F64 origin_y;
76  F64 origin_z;
77  I32 time;
78  I32 rgb;
79 };
80 
82 {
83  if (stream == 0) return FALSE;
84  if (this->file) this->file = file;
85  return ((ByteStreamOutFile*)stream)->refile(file);
86 }
87 
88 BOOL LASwriterBIN::open(const char* file_name, const LASheader* header, const char* version, U32 io_buffer_size)
89 {
90  if (file_name == 0)
91  {
92  fprintf(stderr,"ERROR: file name pointer is zero\n");
93  return FALSE;
94  }
95 
96  file = fopen(file_name, "wb");
97 
98  if (file == 0)
99  {
100  fprintf(stderr, "ERROR: cannot open file '%s'\n", file_name);
101  return FALSE;
102  }
103 
104  if (setvbuf(file, NULL, _IOFBF, io_buffer_size) != 0)
105  {
106  fprintf(stderr, "WARNING: setvbuf() failed with buffer size %u\n", io_buffer_size);
107  }
108 
109  ByteStreamOut* out;
110  if (IS_LITTLE_ENDIAN())
111  out = new ByteStreamOutFileLE(file);
112  else
113  out = new ByteStreamOutFileBE(file);
114 
115  return open(out, header, version);
116 }
117 
118 BOOL LASwriterBIN::open(FILE* file, const LASheader* header, const char* version)
119 {
120  if (file == 0)
121  {
122  fprintf(stderr,"ERROR: file pointer is zero\n");
123  return FALSE;
124  }
125 
126 #ifdef _WIN32
127  if (file == stdout)
128  {
129  if(_setmode( _fileno( stdout ), _O_BINARY ) == -1 )
130  {
131  fprintf(stderr, "ERROR: cannot set stdout to binary (untranslated) mode\n");
132  }
133  }
134 #endif
135 
136  ByteStreamOut* out;
137  if (IS_LITTLE_ENDIAN())
138  out = new ByteStreamOutFileLE(file);
139  else
140  out = new ByteStreamOutFileBE(file);
141 
142  return open(out, header, version);
143 }
144 
145 BOOL LASwriterBIN::open(ByteStreamOut* stream, const LASheader* header, const char* version)
146 {
147  if (stream == 0)
148  {
149  fprintf(stderr,"ERROR: ByteStreamOut pointer is zero\n");
150  return FALSE;
151  }
152  this->stream = stream;
153 
154  if (header == 0)
155  {
156  fprintf(stderr,"ERROR: LASheader pointer is zero\n");
157  return FALSE;
158  }
159 
160  if (strstr(version, "ts16"))
161  {
162  this->version = 20020715;
163  }
164  else
165  {
166  this->version = 20010712;
167  }
168 
169  TSheader tsheader;
170  tsheader.size = sizeof(TSheader);
171  tsheader.version = this->version;
172  tsheader.recog_val = 970401;
173  strncpy(tsheader.recog_str, "CXYZ", 4);
174  tsheader.npoints = header->number_of_point_records;
175  double scale = header->x_scale_factor;
176  if (header->y_scale_factor < scale) scale = header->y_scale_factor;
177  if (header->z_scale_factor < scale) scale = header->z_scale_factor;
178  units = tsheader.units = (I32)(1.0 / scale);
179  origin_x = tsheader.origin_x = -header->x_offset/scale;
180  origin_y = tsheader.origin_y = -header->y_offset/scale;
181  origin_z = tsheader.origin_z = -header->z_offset/scale;
182  tsheader.time = (header->point_data_format == 1) || (header->point_data_format == 3) || (header->point_data_format == 4) || (header->point_data_format == 5);
183  tsheader.rgb = (header->point_data_format == 2) || (header->point_data_format == 3) || (header->point_data_format == 5);
184 
185  return stream->putBytes((U8*)&tsheader, sizeof(TSheader));
186 }
187 
189 {
190  U16 echo;
191 
192  if (point->number_of_returns_of_given_pulse <= 1)
193  echo = 0;
194  else if (point->return_number == 1)
195  echo = 1;
196  else if (point->return_number >= point->number_of_returns_of_given_pulse)
197  echo = 3;
198  else
199  echo = 2;
200 
201  if (version == 20020715)
202  {
203  TSpoint tspoint;
204  tspoint.x = I32_QUANTIZE(point->get_x()*units+origin_x);
205  tspoint.y = I32_QUANTIZE(point->get_y()*units+origin_y);
206  tspoint.z = I32_QUANTIZE(point->get_z()*units+origin_z);
207  tspoint.code = point->classification;
208  tspoint.echo = (U8)echo;
209  tspoint.flag = 0;
210  tspoint.mark = 0;
211  tspoint.line = point->point_source_ID;
212  tspoint.intensity = point->intensity;
213  if (!stream->putBytes((U8*)&tspoint, sizeof(TSpoint))) return FALSE;
214  }
215  else
216  {
217  TSrow tsrow;
218  tsrow.code = point->classification;
219  tsrow.line = (U8)(point->point_source_ID);
220  tsrow.echo_intensity = (echo << 14) | (point->intensity & 0x3FFF);
221  tsrow.x = I32_QUANTIZE(point->get_x()*units+origin_x);
222  tsrow.y = I32_QUANTIZE(point->get_y()*units+origin_y);
223  tsrow.z = I32_QUANTIZE(point->get_z()*units+origin_z);
224  if (!stream->putBytes((U8*)&tsrow, sizeof(TSrow))) return FALSE;
225  }
226 
227  if (point->have_gps_time)
228  {
229  U32 time = (U32)(point->gps_time/0.0002+0.5);
230  if (!stream->putBytes((U8*)&time, sizeof(U32))) return FALSE;
231  }
232  if (point->have_rgb)
233  {
234  U8 rgba[4];
235  rgba[0] = point->rgb[0]/256;
236  rgba[1] = point->rgb[1]/256;
237  rgba[2] = point->rgb[2]/256;
238  rgba[3] = 0;
239  if (!stream->putBytes((U8*)&rgba, sizeof(U32))) return FALSE;
240  }
241  p_count++;
242  return TRUE;
243 }
244 
245 BOOL LASwriterBIN::update_header(const LASheader* header, BOOL use_inventory, BOOL update_extra_bytes)
246 {
247  return TRUE;
248 }
249 
251 {
252  I64 bytes = 0;
253 
254  if (stream)
255  {
256  if (update_header && p_count != npoints)
257  {
258  if (!stream->isSeekable())
259  {
260 #ifdef _WIN32
261  fprintf(stderr, "ERROR: stream not seekable. cannot update header from %I64d to %I64d points.\n", npoints, p_count);
262 #else
263  fprintf(stderr, "ERROR: stream not seekable. cannot update header from %lld to %lld points.\n", npoints, p_count);
264 #endif
265  }
266  else
267  {
268  stream->seek(16);
269  stream->put32bitsLE((U8*)&p_count);
270  stream->seekEnd();
271  }
272  }
273  bytes = stream->tell();
274  delete stream;
275  stream = 0;
276  }
277 
278  if (file)
279  {
280  fclose(file);
281  file = 0;
282  }
283 
284  npoints = p_count;
285  p_count = 0;
286 
287  return bytes;
288 }
289 
291 {
292  stream = 0;
293  file = 0;
294 }
295 
297 {
298  if (file) close();
299 }
BOOL IS_LITTLE_ENDIAN()
Definition: mydefs.hpp:144
BOOL refile(FILE *file)
virtual BOOL putBytes(const U8 *bytes, U32 num_bytes)=0
#define I32_QUANTIZE(n)
Definition: mydefs.hpp:111
int BOOL
Definition: mydefs.hpp:57
#define FALSE
Definition: mydefs.hpp:133
I64 close(BOOL update_npoints=true)
U32 number_of_point_records
BOOL open(const char *file_name, const LASheader *header, const char *version, U32 io_buffer_size=65536)
U16 echo_intensity
unsigned int U32
Definition: mydefs.hpp:39
F64 get_y() const
BOOL have_gps_time
unsigned short U16
Definition: mydefs.hpp:40
long long I64
Definition: mydefs.hpp:48
BOOL write_point(const LASpoint *point)
unsigned char U8
Definition: mydefs.hpp:41
F64 get_x() const
char I8
Definition: mydefs.hpp:37
FILE * file
int I32
Definition: mydefs.hpp:35
BOOL update_header(const LASheader *header, BOOL use_inventory=TRUE, BOOL update_extra_bytes=FALSE)
F64 get_z() const
#define TRUE
Definition: mydefs.hpp:137
std::shared_ptr< HighFive::File > open(const std::string &filename)
Definition: Hdf5Util.cpp:202
I8 recog_str[4]
#define NULL
Definition: mydefs.hpp:141
double F64
Definition: mydefs.hpp:52
U8 number_of_returns_of_given_pulse


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