laswritepoint.cpp
Go to the documentation of this file.
1 /*
2 ===============================================================================
3 
4  FILE: laswritepoint.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) 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 
32 #include "laswritepoint.hpp"
33 
34 #include "arithmeticencoder.hpp"
35 #include "laswriteitemraw.hpp"
38 
39 #include <string.h>
40 #include <stdlib.h>
41 
43 {
44  outstream = 0;
45  num_writers = 0;
46  writers = 0;
47  writers_raw = 0;
49  enc = 0;
50  // used for chunking
52  chunk_count = 0;
53  number_chunks = 0;
54  alloced_chunks = 0;
55  chunk_sizes = 0;
56  chunk_bytes = 0;
59 }
60 
61 BOOL LASwritePoint::setup(const U32 num_items, const LASitem* items, const LASzip* laszip)
62 {
63  U32 i;
64 
65  // is laszip exists then we must use its items
66  if (laszip)
67  {
68  if (num_items != laszip->num_items) return FALSE;
69  if (items != laszip->items) return FALSE;
70  }
71 
72  // create entropy encoder (if requested)
73  enc = 0;
74  if (laszip && laszip->compressor)
75  {
76  switch (laszip->coder)
77  {
79  enc = new ArithmeticEncoder();
80  break;
81  default:
82  // entropy decoder not supported
83  return FALSE;
84  }
85  }
86 
87  // initizalize the writers
88  writers = 0;
89  num_writers = num_items;
90 
91  // disable chunking
93 
94  // always create the raw writers
96  for (i = 0; i < num_writers; i++)
97  {
98  switch (items[i].type)
99  {
100  case LASitem::POINT10:
101  if (IS_LITTLE_ENDIAN())
103  else
105  break;
106  case LASitem::GPSTIME11:
107  if (IS_LITTLE_ENDIAN())
109  else
111  break;
112  case LASitem::RGB12:
113  if (IS_LITTLE_ENDIAN())
115  else
117  break;
119  if (IS_LITTLE_ENDIAN())
121  else
123  break;
124  case LASitem::BYTE:
125  writers_raw[i] = new LASwriteItemRaw_BYTE(items[i].size);
126  break;
127  case LASitem::POINT14:
128  if (IS_LITTLE_ENDIAN())
130  else
131  return FALSE;
132  break;
133  case LASitem::RGBNIR14:
134  if (IS_LITTLE_ENDIAN())
136  else
138  break;
139  default:
140  return FALSE;
141  }
142  }
143 
144  // if needed create the compressed writers and set versions
145  if (enc)
146  {
148  for (i = 0; i < num_writers; i++)
149  {
150  switch (items[i].type)
151  {
152  case LASitem::POINT10:
153  if (items[i].version == 1)
155  else if (items[i].version == 2)
157  else
158  return FALSE;
159  break;
160  case LASitem::GPSTIME11:
161  if (items[i].version == 1)
163  else if (items[i].version == 2)
165  else
166  return FALSE;
167  break;
168  case LASitem::RGB12:
169  if (items[i].version == 1)
171  else if (items[i].version == 2)
173  else
174  return FALSE;
175  break;
177  if (items[i].version == 1)
179  else
180  return FALSE;
181  break;
182  case LASitem::BYTE:
183  if (items[i].version == 1)
184  writers_compressed[i] = new LASwriteItemCompressed_BYTE_v1(enc, items[i].size);
185  else if (items[i].version == 2)
186  writers_compressed[i] = new LASwriteItemCompressed_BYTE_v2(enc, items[i].size);
187  else
188  return FALSE;
189  break;
190  default:
191  return FALSE;
192  }
193  }
195  {
196  if (laszip->chunk_size) chunk_size = laszip->chunk_size;
197  chunk_count = 0;
199  }
200  }
201  return TRUE;
202 }
203 
205 {
206  if (!outstream) return FALSE;
207  this->outstream = outstream;
208 
209  // if chunking is enabled
210  if (number_chunks == U32_MAX)
211  {
212  number_chunks = 0;
213  if (outstream->isSeekable())
214  {
215  chunk_table_start_position = outstream->tell();
216  }
217  else
218  {
220  }
222  chunk_start_position = outstream->tell();
223  }
224 
225  U32 i;
226  for (i = 0; i < num_writers; i++)
227  {
228  ((LASwriteItemRaw*)(writers_raw[i]))->init(outstream);
229  }
230 
231  if (enc)
232  {
233  writers = 0;
234  }
235  else
236  {
238  }
239 
240  return TRUE;
241 }
242 
243 BOOL LASwritePoint::write(const U8 * const * point)
244 {
245  U32 i;
246 
247  if (chunk_count == chunk_size)
248  {
249  enc->done();
251  init(outstream);
252  chunk_count = 0;
253  }
254  chunk_count++;
255 
256  if (writers)
257  {
258  for (i = 0; i < num_writers; i++)
259  {
260  writers[i]->write(point[i]);
261  }
262  }
263  else
264  {
265  for (i = 0; i < num_writers; i++)
266  {
267  writers_raw[i]->write(point[i]);
268  ((LASwriteItemCompressed*)(writers_compressed[i]))->init(point[i]);
269  }
271  enc->init(outstream);
272  }
273  return TRUE;
274 }
275 
277 {
278  if (chunk_start_position == 0 || chunk_size != U32_MAX)
279  {
280  return FALSE;
281  }
282  enc->done();
284  init(outstream);
285  chunk_count = 0;
286  return TRUE;
287 }
288 
290 {
292  {
293  enc->done();
295  {
297  return write_chunk_table();
298  }
299  }
300  else if (writers == 0)
301  {
303  {
304  return write_chunk_table();
305  }
306  }
307 
308  return TRUE;
309 }
310 
312 {
314  {
315  if (chunk_bytes == 0)
316  {
317  alloced_chunks = 1024;
318  if (chunk_size == U32_MAX) chunk_sizes = (U32*)malloc(sizeof(U32)*alloced_chunks);
319  chunk_bytes = (U32*)malloc(sizeof(U32)*alloced_chunks);
320  }
321  else
322  {
323  alloced_chunks *= 2;
324  if (chunk_size == U32_MAX) chunk_sizes = (U32*)realloc(chunk_sizes, sizeof(U32)*alloced_chunks);
325  chunk_bytes = (U32*)realloc(chunk_bytes, sizeof(U32)*alloced_chunks);
326  }
327  if (chunk_size == U32_MAX && chunk_sizes == 0) return FALSE;
328  if (chunk_bytes == 0) return FALSE;
329  }
330  I64 position = outstream->tell();
333  chunk_start_position = position;
334  number_chunks++;
335  return TRUE;
336 }
337 
339 {
340  U32 i;
341  I64 position = outstream->tell();
342  if (chunk_table_start_position != -1) // stream is seekable
343  {
345  {
346  return FALSE;
347  }
348  if (!outstream->put64bitsLE((U8*)&position))
349  {
350  return FALSE;
351  }
352  if (!outstream->seek(position))
353  {
354  return FALSE;
355  }
356  }
357  U32 version = 0;
358  if (!outstream->put32bitsLE((U8*)&version))
359  {
360  return FALSE;
361  }
363  {
364  return FALSE;
365  }
366  if (number_chunks > 0)
367  {
368  enc->init(outstream);
369  IntegerCompressor ic(enc, 32, 2);
370  ic.initCompressor();
371  for (i = 0; i < number_chunks; i++)
372  {
373  if (chunk_size == U32_MAX) ic.compress((i ? chunk_sizes[i-1] : 0), chunk_sizes[i], 0);
374  ic.compress((i ? chunk_bytes[i-1] : 0), chunk_bytes[i], 1);
375  }
376  enc->done();
377  }
378  if (chunk_table_start_position == -1) // stream is not-seekable
379  {
380  if (!outstream->put64bitsLE((U8*)&position))
381  {
382  return FALSE;
383  }
384  }
385  return TRUE;
386 }
387 
389 {
390  U32 i;
391 
392  if (writers_raw)
393  {
394  for (i = 0; i < num_writers; i++)
395  {
396  delete writers_raw[i];
397  }
398  delete [] writers_raw;
399  }
400  if (writers_compressed)
401  {
402  for (i = 0; i < num_writers; i++)
403  {
404  delete writers_compressed[i];
405  }
406  delete [] writers_compressed;
407  }
408  if (enc)
409  {
410  delete enc;
411  }
412 
413  if (chunk_bytes) free(chunk_bytes);
414 }
BOOL IS_LITTLE_ENDIAN()
Definition: mydefs.hpp:144
int BOOL
Definition: mydefs.hpp:57
#define FALSE
Definition: mydefs.hpp:133
LASwriteItem ** writers
ByteStreamOut * outstream
virtual BOOL init(ByteStreamOut *outstream)=0
LASwriteItem ** writers_raw
LASwriteItem ** writers_compressed
#define LASZIP_CODER_ARITHMETIC
Definition: laszip.hpp:63
virtual BOOL seek(const I64 position)=0
unsigned int chunk_size
Definition: laszip.hpp:117
unsigned int U32
Definition: mydefs.hpp:39
virtual I64 tell() const =0
unsigned short compressor
Definition: laszip.hpp:111
I64 chunk_table_start_position
BOOL init(ByteStreamOut *outstream)
long long I64
Definition: mydefs.hpp:48
unsigned short coder
Definition: laszip.hpp:112
unsigned char U8
Definition: mydefs.hpp:41
virtual BOOL put64bitsLE(const U8 *bytes)=0
virtual BOOL isSeekable() const =0
BOOL write_chunk_table()
#define U32_MAX
Definition: mydefs.hpp:75
BOOL setup(const U32 num_items, const LASitem *items, const LASzip *laszip=0)
virtual void done()=0
LASitem * items
Definition: laszip.hpp:121
BOOL add_chunk_to_table()
virtual BOOL put32bitsLE(const U8 *bytes)=0
virtual BOOL write(const U8 *item)=0
unsigned short num_items
Definition: laszip.hpp:120
EntropyEncoder * enc
#define TRUE
Definition: mydefs.hpp:137
void compress(I32 iPred, I32 iReal, U32 context=0)
#define LASZIP_COMPRESSOR_POINTWISE_CHUNKED
Definition: laszip.hpp:55
BOOL write(const U8 *const *point)


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