laswaveform13writer.cpp
Go to the documentation of this file.
1 /*
2 ===============================================================================
3 
4  FILE: laswaveform13writer.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 "laswaveform13writer.hpp"
32 
33 #include "bytestreamout_file.hpp"
34 #include "arithmeticencoder.hpp"
35 #include "integercompressor.hpp"
36 
38 {
39 public:
43 };
44 
46 {
47  waveforms = 0;
48  file = 0;
49  stream = 0;
50  enc = 0;
51  ic8 = 0;
52  ic16 = 0;
53 }
54 
56 {
57  if (waveforms)
58  {
59  I32 i;
60  for (i = 0; i < 256; i++)
61  {
62  if (waveforms[i]) delete waveforms[i];
63  }
64  delete [] waveforms;
65  }
66  if (enc) delete enc;
67  if (ic8) delete ic8;
68  if (ic16) delete ic16;
69 }
70 
71 
72 BOOL LASwaveform13writer::open(const char* file_name, const LASvlr_wave_packet_descr * const * wave_packet_descr)
73 {
74  if (file_name == 0)
75  {
76  fprintf(stderr,"ERROR: file name pointer is zero\n");
77  return FALSE;
78  }
79 
80  if (wave_packet_descr == 0)
81  {
82  fprintf(stderr,"ERROR: wave packet descriptor pointer is zero\n");
83  return FALSE;
84  }
85 
86  // copy relevant wave packet descriptions and check if compressed or not
87 
88  U16 i, number = 0;
89  BOOL compressed = FALSE;
90 
91  if (waveforms == 0)
92  {
93  waveforms = new LASwaveformDescription*[256];
94  for (i = 0; i < 256; i++) waveforms[i] = 0;
95  }
96 
97  for (i = 0; i < 256; i++)
98  {
99  if (wave_packet_descr[i])
100  {
101  if (waveforms[i] == 0)
102  {
103  waveforms[i] = new LASwaveformDescription;
104  }
105  waveforms[i]->compression = wave_packet_descr[i]->getCompressionType();
106  waveforms[i]->nbits = wave_packet_descr[i]->getBitsPerSample();
107  waveforms[i]->nsamples = wave_packet_descr[i]->getNumberOfSamples();
108  compressed = compressed || (waveforms[i]->compression > 0);
109  number++;
110  }
111  else
112  {
113  if (waveforms[i])
114  {
115  delete waveforms[i];
116  waveforms[i] = 0;
117  }
118  }
119  }
120 
121  // create file name and open file
122 
123  char* file_name_temp = strdup(file_name);
124 
125  int len = strlen(file_name_temp);
126  if (file_name_temp[len-3] == 'L' || file_name_temp[len-3] == 'W')
127  {
128  file_name_temp[len-3] = 'W';
129  file_name_temp[len-2] = 'D';
130  file_name_temp[len-1] = (compressed ? 'Z' : 'P');
131  }
132  else
133  {
134  file_name_temp[len-3] = 'w';
135  file_name_temp[len-2] = 'd';
136  file_name_temp[len-1] = (compressed ? 'z' : 'p');
137  }
138  file = fopen(file_name_temp, "wb");
139 
140  if (file == 0)
141  {
142  fprintf(stderr, "ERROR: cannot open waveform file '%s'\n", file_name_temp);
143  free(file_name_temp);
144  return FALSE;
145  }
146  free(file_name_temp);
147 
148  // create strea,
149 
150  if (IS_LITTLE_ENDIAN())
151  {
152  stream = new ByteStreamOutFileLE(file);
153  }
154  else
155  {
156  stream = new ByteStreamOutFileBE(file);
157  }
158 
159  // write extended variable length header variable after variable (to avoid alignment issues)
160 
161  U16 reserved = 0xAABB;
162  if (!stream->put16bitsLE((U8*)&reserved))
163  {
164  fprintf(stderr,"ERROR: writing EVLR reserved\n");
165  return FALSE;
166  }
167  I8 user_id[16];
168  memset(user_id, 0, 16);
169  strcpy(user_id, "LASF_Spec");
170  if (!stream->putBytes((U8*)user_id, 16))
171  {
172  fprintf(stderr,"ERROR: writing EVLR user_id\n");
173  return FALSE;
174  }
175  U16 record_id = 65535;
176  if (!stream->put16bitsLE((U8*)&record_id))
177  {
178  fprintf(stderr,"ERROR: writing EVLR record_id\n");
179  return FALSE;
180  }
181  I64 record_length_after_header = 0;
182  if (!stream->put64bitsLE((U8*)&record_length_after_header))
183  {
184  fprintf(stderr,"ERROR: writing EVLR record_length_after_header\n");
185  return FALSE;
186  }
187  I8 description[32];
188  memset(description, 0, 32);
189  sprintf(description, "%s by LAStools (%d)", (compressed ? "compressed" : "created"), LAS_TOOLS_VERSION);
190  if (!stream->putBytes((U8*)description, 32))
191  {
192  fprintf(stderr,"ERROR: writing EVLR description\n");
193  return FALSE;
194  }
195 
196  // write waveform descriptor cross-check
197 
198  char magic[25];
199  sprintf(magic, "LAStools waveform %d", LAS_TOOLS_VERSION);
200 
201  if (!stream->putBytes((U8*)magic, 24))
202  {
203  fprintf(stderr,"ERROR: writing waveform descriptor cross-check\n");
204  return FALSE;
205  }
206 
207  if (!stream->put16bitsLE((U8*)&number))
208  {
209  fprintf(stderr,"ERROR: writing number of waveform descriptors\n");
210  return FALSE;
211  }
212 
213  for (i = 0; i < 256; i++)
214  {
215  if (waveforms[i])
216  {
217  if (!stream->put16bitsLE((U8*)&i))
218  {
219  fprintf(stderr,"ERROR: writing index of waveform descriptor %d\n", i);
220  return FALSE;
221  }
222  if (!stream->putByte(waveforms[i]->compression))
223  {
224  fprintf(stderr,"ERROR: writing compression of waveform descriptor %d\n", i);
225  return FALSE;
226  }
227  if (!stream->putByte(waveforms[i]->nbits))
228  {
229  fprintf(stderr,"ERROR: writing nbits of waveform descriptor %d\n", i);
230  return FALSE;
231  }
232  if (!stream->put16bitsLE((U8*)&(waveforms[i]->nsamples)))
233  {
234  fprintf(stderr,"ERROR: writing nsamples of waveform descriptor %d\n", i);
235  return FALSE;
236  }
237  }
238  }
239 
240  // create compressor
241 
242  if (compressed)
243  {
244  if (enc == 0) enc = new ArithmeticEncoder();
245  if (ic8 == 0) ic8 = new IntegerCompressor(enc, 8);
246  if (ic16 == 0) ic16 = new IntegerCompressor(enc, 16);
247  }
248 
249  return TRUE;
250 }
251 
253 {
254  U32 index = point->wavepacket.getIndex();
255  if (index == 0)
256  {
257  return FALSE;
258  }
259 
260  U32 nbits = waveforms[index]->nbits;
261  if ((nbits != 8) && (nbits != 16))
262  {
263  fprintf(stderr, "ERROR: waveform with %d bits per samples not supported yet\n", nbits);
264  return FALSE;
265  }
266 
267  U32 nsamples = waveforms[index]->nsamples;
268  if (nsamples == 0)
269  {
270  fprintf(stderr, "ERROR: waveform has no samples\n");
271  return FALSE;
272  }
273 
274  // set offset to waveform data
275 
276  I64 offset = stream->tell();
277  point->wavepacket.setOffset(offset);
278 
279  // write waveform
280 
281  if (waveforms[index]->compression == 0)
282  {
283  U32 size = ((nbits/8) * nsamples);
284  if (!stream->putBytes(samples, size))
285  {
286  fprintf(stderr, "ERROR: cannot write %u bytes for waveform with %u samples of %u bits\n", size, nsamples, nbits);
287  return FALSE;
288  }
289  point->wavepacket.setSize(size);
290  }
291  else
292  {
293  U32 s_count;
294  if (nbits == 8)
295  {
296  stream->putBytes(samples, 1);
297  enc->init(stream);
298  ic8->initCompressor();
299  for (s_count = 1; s_count < nsamples; s_count++)
300  {
301  ic8->compress(samples[s_count-1], samples[s_count]);
302  }
303  }
304  else
305  {
306  stream->putBytes(samples, 2);
307  enc->init(stream);
308  ic16->initCompressor();
309  for (s_count = 1; s_count < nsamples; s_count++)
310  {
311  ic16->compress(((U16*)samples)[s_count-1], ((U16*)samples)[s_count]);
312  }
313  }
314  enc->done();
315  U32 size = (U32)(stream->tell() - offset);
316  point->wavepacket.setSize(size);
317  }
318 
319  return TRUE;
320 }
321 
323 {
324  if (stream->isSeekable())
325  {
326  I64 record_length_after_header = stream->tell();
327  record_length_after_header -= 60;
328  stream->seek(18);
329  if (!stream->put64bitsLE((U8*)&record_length_after_header))
330  {
331  fprintf(stderr,"ERROR: updating EVLR record_length_after_header\n");
332  }
333  stream->seekEnd();
334  }
335  if (stream)
336  {
337  delete stream;
338  stream = 0;
339  }
340  if (file)
341  {
342  fclose(file);
343  file = 0;
344  }
345 }
BOOL open(const char *file_name, const LASvlr_wave_packet_descr *const *wave_packet_descr)
BOOL IS_LITTLE_ENDIAN()
Definition: mydefs.hpp:144
int BOOL
Definition: mydefs.hpp:57
#define FALSE
Definition: mydefs.hpp:133
void setOffset(U64 offset)
unsigned int U32
Definition: mydefs.hpp:39
unsigned short U16
Definition: mydefs.hpp:40
long long I64
Definition: mydefs.hpp:48
LASwavepacket wavepacket
unsigned char U8
Definition: mydefs.hpp:41
U8 getIndex() const
char I8
Definition: mydefs.hpp:37
FILE * file
int I32
Definition: mydefs.hpp:35
BOOL write_waveform(LASpoint *point, U8 *samples)
void setSize(U32 size)
#define LAS_TOOLS_VERSION
#define TRUE
Definition: mydefs.hpp:137


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