1 /*
2 ===============================================================================
3 
4   FILE:  lasreader.cpp
5 
6   CONTENTS:
7 
8     see corresponding header file
9 
10   PROGRAMMERS:
11 
12     martin.isenburg@rapidlasso.com  -  http://rapidlasso.com
13 
14   COPYRIGHT:
15 
16     (c) 2005-2013, martin isenburg, rapidlasso - fast 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 LICENSE.txt 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.hpp"
32 
33 #include "lasindex.hpp"
34 #include "lasfilter.hpp"
35 #include "lastransform.hpp"
36 
37 #include "lasreader_las.hpp"
38 #include "lasreader_bin.hpp"
39 #include "lasreader_shp.hpp"
40 #include "lasreader_qfit.hpp"
41 #include "lasreader_asc.hpp"
42 #include "lasreader_bil.hpp"
43 #include "lasreader_dtm.hpp"
44 #include "lasreader_txt.hpp"
45 #include "lasreader_ply.hpp"
46 #include "lasreadermerged.hpp"
47 #include "lasreaderbuffered.hpp"
48 #include "lasreaderstored.hpp"
49 #include "lasreaderpipeon.hpp"
50 
51 #include <stdlib.h>
52 #include <string.h>
53 
LASreader()54 LASreader::LASreader()
55 {
56   npoints = 0;
57   p_count = 0;
58   read_simple = &LASreader::read_point_default;
59   read_complex = 0;
60   index = 0;
61   filter = 0;
62   transform = 0;
63   inside = 0;
64   t_ll_x = 0;
65   t_ll_y = 0;
66   t_size = 0;
67   t_ur_x = 0;
68   t_ur_y = 0;
69   c_center_x = 0;
70   c_center_y = 0;
71   c_radius = 0;
72   c_radius_squared = 0;
73   r_min_x = 0;
74   r_min_y = 0;
75   r_max_x = 0;
76   r_max_y = 0;
77   orig_min_x = 0;
78   orig_min_y = 0;
79   orig_max_x = 0;
80   orig_max_y = 0;
81 }
82 
~LASreader()83 LASreader::~LASreader()
84 {
85   if (index) delete index;
86 }
87 
set_index(LASindex * index)88 void LASreader::set_index(LASindex* index)
89 {
90   if (this->index) delete this->index;
91   this->index = index;
92 }
93 
set_filter(LASfilter * filter)94 void LASreader::set_filter(LASfilter* filter)
95 {
96   this->filter = filter;
97   if (filter && transform)
98   {
99     read_simple = &LASreader::read_point_filtered_and_transformed;
100   }
101   else if (filter)
102   {
103     read_simple = &LASreader::read_point_filtered;
104   }
105   else if (transform)
106   {
107     read_simple = &LASreader::read_point_transformed;
108   }
109   else
110   {
111     read_simple = &LASreader::read_point_default;
112   }
113   read_complex = &LASreader::read_point_default;
114 }
115 
set_transform(LAStransform * transform)116 void LASreader::set_transform(LAStransform* transform)
117 {
118   this->transform = transform;
119   if (filter && transform)
120   {
121     read_simple = &LASreader::read_point_filtered_and_transformed;
122   }
123   else if (filter)
124   {
125     read_simple = &LASreader::read_point_filtered;
126   }
127   else if (transform)
128   {
129     read_simple = &LASreader::read_point_transformed;
130   }
131   else
132   {
133     read_simple = &LASreader::read_point_default;
134   }
135   read_complex = &LASreader::read_point_default;
136 }
137 
inside_none()138 BOOL LASreader::inside_none()
139 {
140   if (filter || transform)
141   {
142     read_complex = &LASreader::read_point_default;
143   }
144   else
145   {
146     read_simple = &LASreader::read_point_default;
147   }
148   if (inside)
149   {
150     header.min_x = orig_min_x;
151     header.min_y = orig_min_y;
152     header.max_x = orig_max_x;
153     header.max_y = orig_max_y;
154     inside = 0;
155   }
156   return TRUE;
157 }
158 
inside_tile(const F32 ll_x,const F32 ll_y,const F32 size)159 BOOL LASreader::inside_tile(const F32 ll_x, const F32 ll_y, const F32 size)
160 {
161   inside = 1;
162   t_ll_x = ll_x;
163   t_ll_y = ll_y;
164   t_size = size;
165   t_ur_x = ll_x + size;
166   t_ur_y = ll_y + size;
167   orig_min_x = header.min_x;
168   orig_min_y = header.min_y;
169   orig_max_x = header.max_x;
170   orig_max_y = header.max_y;
171   header.min_x = ll_x;
172   header.min_y = ll_y;
173   header.max_x = ll_x + size;
174   header.max_y = ll_y + size;
175   header.max_x -= header.x_scale_factor;
176   header.max_y -= header.y_scale_factor;
177   if (((orig_min_x > header.max_x) || (orig_min_y > header.max_y) || (orig_max_x < header.min_x) || (orig_max_y < header.min_y)))
178   {
179     if (filter || transform)
180     {
181       read_complex = &LASreader::read_point_none;
182     }
183     else
184     {
185       read_simple = &LASreader::read_point_none;
186     }
187   }
188   else if (filter || transform)
189   {
190     if (index)
191     {
192       if (index) index->intersect_tile(ll_x, ll_y, size);
193       read_complex = &LASreader::read_point_inside_tile_indexed;
194     }
195     else
196     {
197       read_complex = &LASreader::read_point_inside_tile;
198     }
199   }
200   else
201   {
202     if (index)
203     {
204       if (index) index->intersect_tile(ll_x, ll_y, size);
205       read_simple = &LASreader::read_point_inside_tile_indexed;
206     }
207     else
208     {
209       read_simple = &LASreader::read_point_inside_tile;
210     }
211   }
212   return TRUE;
213 }
214 
inside_circle(const F64 center_x,const F64 center_y,const F64 radius)215 BOOL LASreader::inside_circle(const F64 center_x, const F64 center_y, const F64 radius)
216 {
217   inside = 2;
218   c_center_x = center_x;
219   c_center_y = center_y;
220   c_radius = radius;
221   c_radius_squared = radius*radius;
222   orig_min_x = header.min_x;
223   orig_min_y = header.min_y;
224   orig_max_x = header.max_x;
225   orig_max_y = header.max_y;
226   header.min_x = center_x - radius;
227   header.min_y = center_y - radius;
228   header.max_x = center_x + radius;
229   header.max_y = center_y + radius;
230   if (((orig_min_x > header.max_x) || (orig_min_y > header.max_y) || (orig_max_x < header.min_x) || (orig_max_y < header.min_y)))
231   {
232     if (filter || transform)
233     {
234       read_complex = &LASreader::read_point_none;
235     }
236     else
237     {
238       read_simple = &LASreader::read_point_none;
239     }
240   }
241   else if (filter || transform)
242   {
243     if (index)
244     {
245       if (index) index->intersect_circle(center_x, center_y, radius);
246       read_complex = &LASreader::read_point_inside_circle_indexed;
247     }
248     else
249     {
250       read_complex = &LASreader::read_point_inside_circle;
251     }
252   }
253   else
254   {
255     if (index)
256     {
257       if (index) index->intersect_circle(center_x, center_y, radius);
258       read_simple = &LASreader::read_point_inside_circle_indexed;
259     }
260     else
261     {
262       read_simple = &LASreader::read_point_inside_circle;
263     }
264   }
265   return TRUE;
266 }
267 
inside_rectangle(const F64 min_x,const F64 min_y,const F64 max_x,const F64 max_y)268 BOOL LASreader::inside_rectangle(const F64 min_x, const F64 min_y, const F64 max_x, const F64 max_y)
269 {
270   inside = 3;
271   r_min_x = min_x;
272   r_min_y = min_y;
273   r_max_x = max_x;
274   r_max_y = max_y;
275   orig_min_x = header.min_x;
276   orig_min_y = header.min_y;
277   orig_max_x = header.max_x;
278   orig_max_y = header.max_y;
279   header.min_x = min_x;
280   header.min_y = min_y;
281   header.max_x = max_x;
282   header.max_y = max_y;
283   if (((orig_min_x > max_x) || (orig_min_y > max_y) || (orig_max_x < min_x) || (orig_max_y < min_y)))
284   {
285     if (filter || transform)
286     {
287       read_complex = &LASreader::read_point_none;
288     }
289     else
290     {
291       read_simple = &LASreader::read_point_none;
292     }
293   }
294   else if (filter || transform)
295   {
296     if (index)
297     {
298       index->intersect_rectangle(min_x, min_y, max_x, max_y);
299       read_complex = &LASreader::read_point_inside_rectangle_indexed;
300     }
301     else
302     {
303       read_complex = &LASreader::read_point_inside_rectangle;
304     }
305   }
306   else
307   {
308     if (index)
309     {
310       index->intersect_rectangle(min_x, min_y, max_x, max_y);
311       read_simple = &LASreader::read_point_inside_rectangle_indexed;
312     }
313     else
314     {
315       read_simple = &LASreader::read_point_inside_rectangle;
316     }
317   }
318   return TRUE;
319 }
320 
read_point_inside_tile()321 BOOL LASreader::read_point_inside_tile()
322 {
323   while (read_point_default())
324   {
325     if (point.inside_tile(t_ll_x, t_ll_y, t_ur_x, t_ur_y)) return TRUE;
326   }
327   return FALSE;
328 }
329 
read_point_inside_tile_indexed()330 BOOL LASreader::read_point_inside_tile_indexed()
331 {
332   while (index->seek_next((LASreader*)this))
333   {
334     if (read_point_default() && point.inside_tile(t_ll_x, t_ll_y, t_ur_x, t_ur_y)) return TRUE;
335   }
336   return FALSE;
337 }
338 
read_point_inside_circle()339 BOOL LASreader::read_point_inside_circle()
340 {
341   while (read_point_default())
342   {
343     if (point.inside_circle(c_center_x, c_center_y, c_radius_squared)) return TRUE;
344   }
345   return FALSE;
346 }
347 
read_point_inside_circle_indexed()348 BOOL LASreader::read_point_inside_circle_indexed()
349 {
350   while (index->seek_next((LASreader*)this))
351   {
352     if (read_point_default() && point.inside_circle(c_center_x, c_center_y, c_radius_squared)) return TRUE;
353   }
354   return FALSE;
355 }
356 
read_point_inside_rectangle()357 BOOL LASreader::read_point_inside_rectangle()
358 {
359   while (read_point_default())
360   {
361     if (point.inside_rectangle(r_min_x, r_min_y, r_max_x, r_max_y)) return TRUE;
362   }
363   return FALSE;
364 }
365 
read_point_inside_rectangle_indexed()366 BOOL LASreader::read_point_inside_rectangle_indexed()
367 {
368   while (index->seek_next((LASreader*)this))
369   {
370     if (read_point_default() && point.inside_rectangle(r_min_x, r_min_y, r_max_x, r_max_y)) return TRUE;
371   }
372   return FALSE;
373 }
374 
read_point_none()375 BOOL LASreader::read_point_none()
376 {
377   return FALSE;
378 }
379 
read_point_filtered()380 BOOL LASreader::read_point_filtered()
381 {
382   while ((this->*read_complex)())
383   {
384     if (!filter->filter(&point)) return TRUE;
385   }
386   return FALSE;
387 }
388 
read_point_transformed()389 BOOL LASreader::read_point_transformed()
390 {
391   if ((this->*read_complex)())
392   {
393     transform->transform(&point);
394     return TRUE;
395   }
396   return FALSE;
397 }
398 
read_point_filtered_and_transformed()399 BOOL LASreader::read_point_filtered_and_transformed()
400 {
401   if (read_point_filtered())
402   {
403     transform->transform(&point);
404     return TRUE;
405   }
406   return FALSE;
407 }
408 
is_piped() const409 BOOL LASreadOpener::is_piped() const
410 {
411   return (!file_names && use_stdin);
412 }
413 
is_inside() const414 BOOL LASreadOpener::is_inside() const
415 {
416   return (inside_tile != 0 || inside_circle != 0 || inside_rectangle != 0);
417 }
418 
unparse(CHAR * string) const419 I32 LASreadOpener::unparse(CHAR* string) const
420 {
421   I32 n = 0;
422   if (inside_tile)
423   {
424     n = sprintf(string, "-inside_tile %g %g %g ", inside_tile[0], inside_tile[1], inside_tile[2]);
425   }
426   else if (inside_circle)
427   {
428     n = sprintf(string, "-inside_circle %lf %lf %lf ", inside_circle[0], inside_circle[1], inside_circle[2]);
429   }
430   else if (inside_rectangle)
431   {
432     n = sprintf(string, "-inside_rectangle %lf %lf %lf %lf ", inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
433   }
434   if (stored)
435   {
436     n += sprintf(string + n, "-stored ");
437   }
438   if (files_are_flightlines)
439   {
440     if (files_are_flightlines == 1)
441     {
442       n += sprintf(string + n, "-faf ");
443     }
444     else
445     {
446       n += sprintf(string + n, "-faf %d ", files_are_flightlines);
447     }
448   }
449   if (apply_file_source_ID)
450   {
451     n += sprintf(string + n, "-apply_file_source_ID ");
452   }
453   if (scale_factor)
454   {
455     if (scale_factor[2] == 0.0)
456     {
457       if ((scale_factor[0] != 0.0) && (scale_factor[1] != 0.0))
458       {
459         n += sprintf(string + n, "-rescale_xy %lf %lf ", scale_factor[0], scale_factor[1]);
460       }
461     }
462     else
463     {
464       if ((scale_factor[0] == 0.0) && (scale_factor[1] == 0.0))
465       {
466         n += sprintf(string + n, "-rescale_z %lf ", scale_factor[2]);
467       }
468       else
469       {
470         n += sprintf(string + n, "-rescale %lf %lf %lf ", scale_factor[0], scale_factor[1], scale_factor[2]);
471       }
472     }
473   }
474   if (offset)
475   {
476     n += sprintf(string + n, "-reoffset %lf %lf %lf ", offset[0], offset[1], offset[2]);
477   }
478   else if (auto_reoffset)
479   {
480     n += sprintf(string + n, "-auto_reoffset ");
481   }
482   if (populate_header)
483   {
484     n += sprintf(string + n, "-populate ");
485   }
486   if (io_ibuffer_size != LAS_TOOLS_IO_IBUFFER_SIZE)
487   {
488     n += sprintf(string + n, "-io_ibuffer %d ", io_ibuffer_size);
489   }
490   if (temp_file_base)
491   {
492     n += sprintf(string + n, "-temp_files \"%s\" ", temp_file_base);
493   }
494   return n;
495 }
496 
is_buffered() const497 BOOL LASreadOpener::is_buffered() const
498 {
499   return ((buffer_size > 0) && ((file_name_number > 1) || (neighbor_file_name_number > 0)));
500 }
501 
is_header_populated() const502 BOOL LASreadOpener::is_header_populated() const
503 {
504   return (populate_header || (file_name && (strstr(file_name, ".las") || strstr(file_name, ".laz") || strstr(file_name, ".LAS") || strstr(file_name, ".LAZ"))));
505 }
506 
reset()507 void LASreadOpener::reset()
508 {
509   file_name_current = 0;
510   file_name = 0;
511 }
512 
open(const CHAR * other_file_name,BOOL reset_after_other)513 LASreader* LASreadOpener::open(const CHAR* other_file_name, BOOL reset_after_other)
514 {
515   if (filter) filter->reset();
516   if (transform) transform->reset();
517 
518   if (file_names || other_file_name)
519   {
520     use_stdin = FALSE;
521     if (file_name_current == file_name_number && other_file_name == 0) return 0;
522     if ((file_name_number > 1) && merged)
523     {
524       LASreaderMerged* lasreadermerged = new LASreaderMerged();
525       lasreadermerged->set_scale_factor(scale_factor);
526       lasreadermerged->set_offset(offset);
527       lasreadermerged->set_parse_string(parse_string);
528       lasreadermerged->set_skip_lines(skip_lines);
529       lasreadermerged->set_populate_header(populate_header);
530       lasreadermerged->set_keep_lastiling(keep_lastiling);
531       lasreadermerged->set_translate_intensity(translate_intensity);
532       lasreadermerged->set_scale_intensity(scale_intensity);
533       lasreadermerged->set_translate_scan_angle(translate_scan_angle);
534       lasreadermerged->set_scale_scan_angle(scale_scan_angle);
535       lasreadermerged->set_io_ibuffer_size(io_ibuffer_size);
536       for (file_name_current = 0; file_name_current < file_name_number; file_name_current++) lasreadermerged->add_file_name(file_names[file_name_current]);
537       if (!lasreadermerged->open())
538       {
539         fprintf(stderr,"ERROR: cannot open lasreadermerged with %d file names\n", file_name_number);
540         delete lasreadermerged;
541         return 0;
542       }
543       if (files_are_flightlines) lasreadermerged->set_files_are_flightlines(files_are_flightlines);
544       if (apply_file_source_ID) lasreadermerged->set_apply_file_source_ID(TRUE);
545       if (filter) lasreadermerged->set_filter(filter);
546       if (transform) lasreadermerged->set_transform(transform);
547       if (inside_tile) lasreadermerged->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
548       if (inside_circle) lasreadermerged->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
549       if (inside_rectangle) lasreadermerged->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
550       LASreader* lasreader = 0;
551       if (stored)
552       {
553         LASreaderStored* lasreaderstored = new LASreaderStored();
554         if (!lasreaderstored->open(lasreadermerged))
555         {
556           fprintf(stderr, "ERROR: could not open lasreaderstored with lasreadermerged\n");
557           delete lasreaderstored;
558           return 0;
559         }
560         lasreader = lasreaderstored;
561       }
562       else
563       {
564         lasreader = lasreadermerged;
565       }
566       if (pipe_on)
567       {
568         LASreaderPipeOn* lasreaderpipeon = new LASreaderPipeOn();
569         if (!lasreaderpipeon->open(lasreader))
570         {
571           fprintf(stderr,"ERROR: cannot open lasreaderpipeon with lasreadermerged\n");
572           delete lasreaderpipeon;
573           return 0;
574         }
575         return lasreaderpipeon;
576       }
577       else
578       {
579         return lasreader;
580       }
581     }
582     else if ((buffer_size > 0) && ((file_name_number > 1) || (neighbor_file_name_number > 0)))
583     {
584       U32 i;
585       if (other_file_name)
586       {
587         file_name = other_file_name;
588         if (reset_after_other)
589         {
590           file_name_current = 0;
591         }
592       }
593       else
594       {
595         file_name = file_names[file_name_current];
596         file_name_current++;
597       }
598       LASreaderBuffered* lasreaderbuffered = new LASreaderBuffered();
599       lasreaderbuffered->set_buffer_size(buffer_size);
600       lasreaderbuffered->set_scale_factor(scale_factor);
601       lasreaderbuffered->set_offset(offset);
602       lasreaderbuffered->set_parse_string(parse_string);
603       lasreaderbuffered->set_skip_lines(skip_lines);
604       lasreaderbuffered->set_populate_header(populate_header);
605       lasreaderbuffered->set_translate_intensity(translate_intensity);
606       lasreaderbuffered->set_scale_intensity(scale_intensity);
607       lasreaderbuffered->set_translate_scan_angle(translate_scan_angle);
608       lasreaderbuffered->set_scale_scan_angle(scale_scan_angle);
609       lasreaderbuffered->set_file_name(file_name);
610       for (i = 0; i < file_name_number; i++)
611       {
612         if (file_name != file_names[i])
613         {
614           lasreaderbuffered->add_neighbor_file_name(file_names[i]);
615         }
616       }
617       for (i = 0; i < neighbor_file_name_number; i++)
618       {
619         if (strcmp(file_name, neighbor_file_names[i]))
620         {
621           lasreaderbuffered->add_neighbor_file_name(neighbor_file_names[i]);
622         }
623       }
624       if (filter) lasreaderbuffered->set_filter(filter);
625       if (transform) lasreaderbuffered->set_transform(transform);
626       if (!lasreaderbuffered->open())
627       {
628         fprintf(stderr,"ERROR: cannot open lasreaderbuffered with %d file names\n", file_name_number+neighbor_file_name_number);
629         delete lasreaderbuffered;
630         return 0;
631       }
632       if (inside_tile) lasreaderbuffered->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
633       if (inside_circle) lasreaderbuffered->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
634       if (inside_rectangle) lasreaderbuffered->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
635       LASreader* lasreader = 0;
636       if (stored)
637       {
638         LASreaderStored* lasreaderstored = new LASreaderStored();
639         if (!lasreaderstored->open(lasreaderbuffered))
640         {
641           fprintf(stderr, "ERROR: could not open lasreaderstored with lasreaderbuffered\n");
642           delete lasreaderstored;
643           return 0;
644         }
645         lasreader = lasreaderstored;
646       }
647       else
648       {
649         lasreader = lasreaderbuffered;
650       }
651       if (pipe_on)
652       {
653         LASreaderPipeOn* lasreaderpipeon = new LASreaderPipeOn();
654         if (!lasreaderpipeon->open(lasreader))
655         {
656           fprintf(stderr,"ERROR: cannot open lasreaderpipeon with lasreaderbuffered\n");
657           delete lasreaderpipeon;
658           return 0;
659         }
660         return lasreaderpipeon;
661       }
662       else
663       {
664         return lasreader;
665       }
666     }
667     else
668     {
669       if (other_file_name)
670       {
671         file_name = other_file_name;
672         if (reset_after_other)
673         {
674           file_name_current = 0;
675         }
676       }
677       else
678       {
679         file_name = file_names[file_name_current];
680         file_name_current++;
681       }
682       if (files_are_flightlines)
683       {
684         transform->setPointSource(file_name_current + files_are_flightlines + files_are_flightlines_index);
685       }
686       if (strstr(file_name, ".las") || strstr(file_name, ".laz") || strstr(file_name, ".LAS") || strstr(file_name, ".LAZ"))
687       {
688         LASreaderLAS* lasreaderlas;
689         if (scale_factor == 0 && offset == 0)
690         {
691           if (auto_reoffset)
692             lasreaderlas = new LASreaderLASreoffset();
693           else
694             lasreaderlas = new LASreaderLAS();
695         }
696         else if (scale_factor != 0 && offset == 0)
697         {
698           if (auto_reoffset)
699             lasreaderlas = new LASreaderLASrescalereoffset(scale_factor[0], scale_factor[1], scale_factor[2]);
700           else
701             lasreaderlas = new LASreaderLASrescale(scale_factor[0], scale_factor[1], scale_factor[2]);
702         }
703         else if (scale_factor == 0 && offset != 0)
704           lasreaderlas = new LASreaderLASreoffset(offset[0], offset[1], offset[2]);
705         else
706           lasreaderlas = new LASreaderLASrescalereoffset(scale_factor[0], scale_factor[1], scale_factor[2], offset[0], offset[1], offset[2]);
707         if (!lasreaderlas->open(file_name, io_ibuffer_size, FALSE, decompress_selective))
708         {
709           fprintf(stderr,"ERROR: cannot open lasreaderlas with file name '%s'\n", file_name);
710           delete lasreaderlas;
711           return 0;
712         }
713         LASindex* index = new LASindex();
714         if (index->read(file_name))
715           lasreaderlas->set_index(index);
716         else
717           delete index;
718         if (files_are_flightlines)
719         {
720           lasreaderlas->header.file_source_ID = file_name_current + files_are_flightlines + files_are_flightlines_index;
721         }
722         else if (apply_file_source_ID)
723         {
724           transform->setPointSource(lasreaderlas->header.file_source_ID);
725         }
726         if (filter) lasreaderlas->set_filter(filter);
727         if (transform) lasreaderlas->set_transform(transform);
728         if (inside_rectangle) lasreaderlas->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
729         else if (inside_tile) lasreaderlas->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
730         else if (inside_circle) lasreaderlas->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
731         LASreader* lasreader = 0;
732         if (stored)
733         {
734           LASreaderStored* lasreaderstored = new LASreaderStored();
735           if (!lasreaderstored->open(lasreaderlas))
736           {
737             fprintf(stderr, "ERROR: could not open lasreaderstored with lasreaderlas\n");
738             delete lasreaderstored;
739             return 0;
740           }
741           lasreader = lasreaderstored;
742         }
743         else
744         {
745           lasreader = lasreaderlas;
746         }
747         if (pipe_on)
748         {
749           LASreaderPipeOn* lasreaderpipeon = new LASreaderPipeOn();
750           if (!lasreaderpipeon->open(lasreader))
751           {
752             fprintf(stderr,"ERROR: cannot open lasreaderpipeon with lasreaderlas\n");
753             delete lasreaderpipeon;
754             return 0;
755           }
756           return lasreaderpipeon;
757         }
758         else
759         {
760           return lasreader;
761         }
762       }
763       else if (strstr(file_name, ".bin") || strstr(file_name, ".BIN"))
764       {
765         LASreaderBIN* lasreaderbin;
766         if (scale_factor == 0 && offset == 0)
767           lasreaderbin = new LASreaderBIN();
768         else if (scale_factor != 0 && offset == 0)
769           lasreaderbin = new LASreaderBINrescale(scale_factor[0], scale_factor[1], scale_factor[2]);
770         else if (scale_factor == 0 && offset != 0)
771           lasreaderbin = new LASreaderBINreoffset(offset[0], offset[1], offset[2]);
772         else
773           lasreaderbin = new LASreaderBINrescalereoffset(scale_factor[0], scale_factor[1], scale_factor[2], offset[0], offset[1], offset[2]);
774         if (!lasreaderbin->open(file_name))
775         {
776           fprintf(stderr,"ERROR: cannot open lasreaderbin with file name '%s'\n", file_name);
777           delete lasreaderbin;
778           return 0;
779         }
780         LASindex* index = new LASindex();
781         if (index->read(file_name))
782           lasreaderbin->set_index(index);
783         else
784           delete index;
785         if (files_are_flightlines) lasreaderbin->header.file_source_ID = file_name_current + files_are_flightlines + files_are_flightlines_index;
786         if (filter) lasreaderbin->set_filter(filter);
787         if (transform) lasreaderbin->set_transform(transform);
788         if (inside_tile) lasreaderbin->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
789         if (inside_circle) lasreaderbin->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
790         if (inside_rectangle) lasreaderbin->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
791         LASreader* lasreader = 0;
792         if (stored)
793         {
794           LASreaderStored* lasreaderstored = new LASreaderStored();
795           if (!lasreaderstored->open(lasreaderbin))
796           {
797             fprintf(stderr, "ERROR: could not open lasreaderstored with lasreaderbin\n");
798             delete lasreaderstored;
799             return 0;
800           }
801           lasreader = lasreaderstored;
802         }
803         else
804         {
805           lasreader = lasreaderbin;
806         }
807         if (pipe_on)
808         {
809           LASreaderPipeOn* lasreaderpipeon = new LASreaderPipeOn();
810           if (!lasreaderpipeon->open(lasreader))
811           {
812             fprintf(stderr,"ERROR: cannot open lasreaderpipeon with lasreaderbin\n");
813             delete lasreaderpipeon;
814             return 0;
815           }
816           return lasreaderpipeon;
817         }
818         else
819         {
820           return lasreader;
821         }
822       }
823       else if (strstr(file_name, ".shp") || strstr(file_name, ".SHP"))
824       {
825         LASreaderSHP* lasreadershp;
826         if (scale_factor == 0 && offset == 0)
827           lasreadershp = new LASreaderSHP();
828         else if (scale_factor != 0 && offset == 0)
829           lasreadershp = new LASreaderSHPrescale(scale_factor[0], scale_factor[1], scale_factor[2]);
830         else if (scale_factor == 0 && offset != 0)
831           lasreadershp = new LASreaderSHPreoffset(offset[0], offset[1], offset[2]);
832         else
833           lasreadershp = new LASreaderSHPrescalereoffset(scale_factor[0], scale_factor[1], scale_factor[2], offset[0], offset[1], offset[2]);
834         if (!lasreadershp->open(file_name))
835         {
836           fprintf(stderr,"ERROR: cannot open lasreadershp with file name '%s'\n", file_name);
837           delete lasreadershp;
838           return 0;
839         }
840         if (files_are_flightlines) lasreadershp->header.file_source_ID = file_name_current + files_are_flightlines + files_are_flightlines_index;
841         if (filter) lasreadershp->set_filter(filter);
842         if (transform) lasreadershp->set_transform(transform);
843         if (inside_tile) lasreadershp->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
844         if (inside_circle) lasreadershp->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
845         if (inside_rectangle) lasreadershp->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
846         LASreader* lasreader = 0;
847         if (stored)
848         {
849           LASreaderStored* lasreaderstored = new LASreaderStored();
850           if (!lasreaderstored->open(lasreadershp))
851           {
852             fprintf(stderr, "ERROR: could not open lasreaderstored with lasreadershp\n");
853             delete lasreaderstored;
854             return 0;
855           }
856           lasreader = lasreaderstored;
857         }
858         else
859         {
860           lasreader = lasreadershp;
861         }
862         if (pipe_on)
863         {
864           LASreaderPipeOn* lasreaderpipeon = new LASreaderPipeOn();
865           if (!lasreaderpipeon->open(lasreader))
866           {
867             fprintf(stderr,"ERROR: cannot open lasreaderpipeon with lasreadershp\n");
868             delete lasreaderpipeon;
869             return 0;
870           }
871           return lasreaderpipeon;
872         }
873         else
874         {
875           return lasreader;
876         }
877       }
878       else if (strstr(file_name, ".asc") || strstr(file_name, ".ASC"))
879       {
880         LASreaderASC* lasreaderasc;
881         if (scale_factor == 0 && offset == 0)
882           lasreaderasc = new LASreaderASC();
883         else if (scale_factor != 0 && offset == 0)
884           lasreaderasc = new LASreaderASCrescale(scale_factor[0], scale_factor[1], scale_factor[2]);
885         else if (scale_factor == 0 && offset != 0)
886           lasreaderasc = new LASreaderASCreoffset(offset[0], offset[1], offset[2]);
887         else
888           lasreaderasc = new LASreaderASCrescalereoffset(scale_factor[0], scale_factor[1], scale_factor[2], offset[0], offset[1], offset[2]);
889         if (!lasreaderasc->open(file_name, comma_not_point))
890         {
891           fprintf(stderr,"ERROR: cannot open lasreaderasc with file name '%s'\n", file_name);
892           delete lasreaderasc;
893           return 0;
894         }
895         if (files_are_flightlines) lasreaderasc->header.file_source_ID = file_name_current + files_are_flightlines + files_are_flightlines_index;
896         if (filter) lasreaderasc->set_filter(filter);
897         if (transform) lasreaderasc->set_transform(transform);
898         if (inside_tile) lasreaderasc->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
899         if (inside_circle) lasreaderasc->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
900         if (inside_rectangle) lasreaderasc->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
901         LASreader* lasreader = 0;
902         if (stored)
903         {
904           LASreaderStored* lasreaderstored = new LASreaderStored();
905           if (!lasreaderstored->open(lasreaderasc))
906           {
907             fprintf(stderr, "ERROR: could not open lasreaderstored with lasreaderasc\n");
908             delete lasreaderstored;
909             return 0;
910           }
911           lasreader = lasreaderstored;
912         }
913         else
914         {
915           lasreader = lasreaderasc;
916         }
917         if (pipe_on)
918         {
919           LASreaderPipeOn* lasreaderpipeon = new LASreaderPipeOn();
920           if (!lasreaderpipeon->open(lasreader))
921           {
922             fprintf(stderr,"ERROR: cannot open lasreaderpipeon with lasreaderasc\n");
923             delete lasreaderpipeon;
924             return 0;
925           }
926           return lasreaderpipeon;
927         }
928         else
929         {
930           return lasreader;
931         }
932       }
933       else if (strstr(file_name, ".bil") || strstr(file_name, ".BIL"))
934       {
935         LASreaderBIL* lasreaderbil;
936         if (scale_factor == 0 && offset == 0)
937           lasreaderbil = new LASreaderBIL();
938         else if (scale_factor != 0 && offset == 0)
939           lasreaderbil = new LASreaderBILrescale(scale_factor[0], scale_factor[1], scale_factor[2]);
940         else if (scale_factor == 0 && offset != 0)
941           lasreaderbil = new LASreaderBILreoffset(offset[0], offset[1], offset[2]);
942         else
943           lasreaderbil = new LASreaderBILrescalereoffset(scale_factor[0], scale_factor[1], scale_factor[2], offset[0], offset[1], offset[2]);
944         if (!lasreaderbil->open(file_name))
945         {
946           fprintf(stderr,"ERROR: cannot open lasreaderbil with file name '%s'\n", file_name);
947           delete lasreaderbil;
948           return 0;
949         }
950         if (files_are_flightlines) lasreaderbil->header.file_source_ID = file_name_current + files_are_flightlines + files_are_flightlines_index;
951         if (filter) lasreaderbil->set_filter(filter);
952         if (transform) lasreaderbil->set_transform(transform);
953         if (inside_tile) lasreaderbil->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
954         if (inside_circle) lasreaderbil->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
955         if (inside_rectangle) lasreaderbil->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
956         LASreader* lasreader = 0;
957         if (stored)
958         {
959           LASreaderStored* lasreaderstored = new LASreaderStored();
960           if (!lasreaderstored->open(lasreaderbil))
961           {
962             fprintf(stderr, "ERROR: could not open lasreaderstored with lasreaderbil\n");
963             delete lasreaderstored;
964             return 0;
965           }
966           lasreader = lasreaderstored;
967         }
968         else
969         {
970           lasreader = lasreaderbil;
971         }
972         if (pipe_on)
973         {
974           LASreaderPipeOn* lasreaderpipeon = new LASreaderPipeOn();
975           if (!lasreaderpipeon->open(lasreader))
976           {
977             fprintf(stderr,"ERROR: cannot open lasreaderpipeon with lasreaderbil\n");
978             delete lasreaderpipeon;
979             return 0;
980           }
981           return lasreaderpipeon;
982         }
983         else
984         {
985           return lasreader;
986         }
987       }
988       else if (strstr(file_name, ".dtm") || strstr(file_name, ".DTM"))
989       {
990         LASreaderDTM* lasreaderdtm;
991         if (scale_factor == 0 && offset == 0)
992           lasreaderdtm = new LASreaderDTM();
993         else if (scale_factor != 0 && offset == 0)
994           lasreaderdtm = new LASreaderDTMrescale(scale_factor[0], scale_factor[1], scale_factor[2]);
995         else if (scale_factor == 0 && offset != 0)
996           lasreaderdtm = new LASreaderDTMreoffset(offset[0], offset[1], offset[2]);
997         else
998           lasreaderdtm = new LASreaderDTMrescalereoffset(scale_factor[0], scale_factor[1], scale_factor[2], offset[0], offset[1], offset[2]);
999         if (!lasreaderdtm->open(file_name))
1000         {
1001           fprintf(stderr,"ERROR: cannot open lasreaderdtm with file name '%s'\n", file_name);
1002           delete lasreaderdtm;
1003           return 0;
1004         }
1005         if (files_are_flightlines) lasreaderdtm->header.file_source_ID = file_name_current + files_are_flightlines + files_are_flightlines_index;
1006         if (filter) lasreaderdtm->set_filter(filter);
1007         if (transform) lasreaderdtm->set_transform(transform);
1008         if (inside_tile) lasreaderdtm->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1009         if (inside_circle) lasreaderdtm->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1010         if (inside_rectangle) lasreaderdtm->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1011         LASreader* lasreader = 0;
1012         if (stored)
1013         {
1014           LASreaderStored* lasreaderstored = new LASreaderStored();
1015           if (!lasreaderstored->open(lasreaderdtm))
1016           {
1017             fprintf(stderr, "ERROR: could not open lasreaderstored with lasreaderdtm\n");
1018             delete lasreaderstored;
1019             return 0;
1020           }
1021           lasreader = lasreaderstored;
1022         }
1023         else
1024         {
1025           lasreader = lasreaderdtm;
1026         }
1027         if (pipe_on)
1028         {
1029           LASreaderPipeOn* lasreaderpipeon = new LASreaderPipeOn();
1030           if (!lasreaderpipeon->open(lasreader))
1031           {
1032             fprintf(stderr,"ERROR: cannot open lasreaderpipeon with lasreaderdtm\n");
1033             delete lasreaderpipeon;
1034             return 0;
1035           }
1036           return lasreaderpipeon;
1037         }
1038         else
1039         {
1040           return lasreader;
1041         }
1042       }
1043       else if (strstr(file_name, ".ply") || strstr(file_name, ".PLY"))
1044       {
1045         LASreaderPLY* lasreaderply = new LASreaderPLY();
1046         if (translate_intensity != 0.0f) lasreaderply->set_translate_intensity(translate_intensity);
1047         if (scale_intensity != 1.0f) lasreaderply->set_scale_intensity(scale_intensity);
1048         lasreaderply->set_scale_factor(scale_factor);
1049         lasreaderply->set_offset(offset);
1050         if (!lasreaderply->open(file_name, point_type, populate_header))
1051         {
1052           fprintf(stderr,"ERROR: cannot open lasreaderply with file name '%s'\n", file_name);
1053           delete lasreaderply;
1054           return 0;
1055         }
1056         if (files_are_flightlines) lasreaderply->header.file_source_ID = file_name_current + files_are_flightlines + files_are_flightlines_index;
1057         if (filter) lasreaderply->set_filter(filter);
1058         if (transform) lasreaderply->set_transform(transform);
1059         if (inside_tile) lasreaderply->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1060         if (inside_circle) lasreaderply->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1061         if (inside_rectangle) lasreaderply->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1062         LASreader* lasreader = 0;
1063         if (stored)
1064         {
1065           LASreaderStored* lasreaderstored = new LASreaderStored();
1066           if (!lasreaderstored->open(lasreaderply))
1067           {
1068             fprintf(stderr, "ERROR: could not open lasreaderstored with lasreaderply\n");
1069             delete lasreaderstored;
1070             return 0;
1071           }
1072           lasreader = lasreaderstored;
1073         }
1074         else
1075         {
1076           lasreader = lasreaderply;
1077         }
1078         if (pipe_on)
1079         {
1080           LASreaderPipeOn* lasreaderpipeon = new LASreaderPipeOn();
1081           if (!lasreaderpipeon->open(lasreader))
1082           {
1083             fprintf(stderr,"ERROR: cannot open lasreaderpipeon with lasreaderply\n");
1084             delete lasreaderpipeon;
1085             return 0;
1086           }
1087           return lasreaderpipeon;
1088         }
1089         else
1090         {
1091           return lasreader;
1092         }
1093       }
1094       else if (strstr(file_name, ".qi") || strstr(file_name, ".QI"))
1095       {
1096         LASreaderQFIT* lasreaderqfit;
1097         if (scale_factor == 0 && offset == 0)
1098           lasreaderqfit = new LASreaderQFIT();
1099         else if (scale_factor != 0 && offset == 0)
1100           lasreaderqfit = new LASreaderQFITrescale(scale_factor[0], scale_factor[1], scale_factor[2]);
1101         else if (scale_factor == 0 && offset != 0)
1102           lasreaderqfit = new LASreaderQFITreoffset(offset[0], offset[1], offset[2]);
1103         else
1104           lasreaderqfit = new LASreaderQFITrescalereoffset(scale_factor[0], scale_factor[1], scale_factor[2], offset[0], offset[1], offset[2]);
1105         if (!lasreaderqfit->open(file_name))
1106         {
1107           fprintf(stderr,"ERROR: cannot open lasreaderqfit with file name '%s'\n", file_name);
1108           delete lasreaderqfit;
1109           return 0;
1110         }
1111         LASindex* index = new LASindex();
1112         if (index->read(file_name))
1113           lasreaderqfit->set_index(index);
1114         else
1115           delete index;
1116         if (files_are_flightlines) lasreaderqfit->header.file_source_ID = file_name_current + files_are_flightlines + files_are_flightlines_index;
1117         if (filter) lasreaderqfit->set_filter(filter);
1118         if (transform) lasreaderqfit->set_transform(transform);
1119         if (inside_tile) lasreaderqfit->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1120         if (inside_circle) lasreaderqfit->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1121         if (inside_rectangle) lasreaderqfit->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1122         LASreader* lasreader = 0;
1123         if (stored)
1124         {
1125           LASreaderStored* lasreaderstored = new LASreaderStored();
1126           if (!lasreaderstored->open(lasreaderqfit))
1127           {
1128             fprintf(stderr, "ERROR: could not open lasreaderstored with lasreaderqfit\n");
1129             delete lasreaderstored;
1130             return 0;
1131           }
1132           lasreader = lasreaderstored;
1133         }
1134         else
1135         {
1136           lasreader = lasreaderqfit;
1137         }
1138         if (pipe_on)
1139         {
1140           LASreaderPipeOn* lasreaderpipeon = new LASreaderPipeOn();
1141           if (!lasreaderpipeon->open(lasreader))
1142           {
1143             fprintf(stderr,"ERROR: cannot open lasreaderpipeon with lasreaderqfit\n");
1144             delete lasreaderpipeon;
1145             return 0;
1146           }
1147           return lasreaderpipeon;
1148         }
1149         else
1150         {
1151           return lasreader;
1152         }
1153       }
1154       else
1155       {
1156         LASreaderTXT* lasreadertxt = new LASreaderTXT();
1157         if (ipts) lasreadertxt->set_pts(TRUE);
1158         else if (iptx) lasreadertxt->set_ptx(TRUE);
1159         if (translate_intensity != 0.0f) lasreadertxt->set_translate_intensity(translate_intensity);
1160         if (scale_intensity != 1.0f) lasreadertxt->set_scale_intensity(scale_intensity);
1161         if (translate_scan_angle != 0.0f) lasreadertxt->set_translate_scan_angle(translate_scan_angle);
1162         if (scale_scan_angle != 1.0f) lasreadertxt->set_scale_scan_angle(scale_scan_angle);
1163         lasreadertxt->set_scale_factor(scale_factor);
1164         lasreadertxt->set_offset(offset);
1165         if (number_attributes)
1166         {
1167           for (I32 i = 0; i < number_attributes; i++)
1168           {
1169             lasreadertxt->add_attribute(attribute_data_types[i], attribute_names[i], attribute_descriptions[i], attribute_scales[i], attribute_offsets[i], attribute_pre_scales[i], attribute_pre_offsets[i], attribute_no_datas[i]);
1170           }
1171         }
1172         if (!lasreadertxt->open(file_name, point_type, parse_string, skip_lines, populate_header))
1173         {
1174           fprintf(stderr,"ERROR: cannot open lasreadertxt with file name '%s'\n", file_name);
1175           delete lasreadertxt;
1176           return 0;
1177         }
1178         if (files_are_flightlines) lasreadertxt->header.file_source_ID = file_name_current + files_are_flightlines + files_are_flightlines_index;
1179         if (filter) lasreadertxt->set_filter(filter);
1180         if (transform) lasreadertxt->set_transform(transform);
1181         if (inside_tile) lasreadertxt->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1182         if (inside_circle) lasreadertxt->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1183         if (inside_rectangle) lasreadertxt->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1184         LASreader* lasreader = 0;
1185         if (stored)
1186         {
1187           LASreaderStored* lasreaderstored = new LASreaderStored();
1188           if (!lasreaderstored->open(lasreadertxt))
1189           {
1190             fprintf(stderr, "ERROR: could not open lasreaderstored with lasreadertxt\n");
1191             delete lasreaderstored;
1192             return 0;
1193           }
1194           lasreader = lasreaderstored;
1195         }
1196         else
1197         {
1198           lasreader = lasreadertxt;
1199         }
1200         if (pipe_on)
1201         {
1202           LASreaderPipeOn* lasreaderpipeon = new LASreaderPipeOn();
1203           if (!lasreaderpipeon->open(lasreader))
1204           {
1205             fprintf(stderr,"ERROR: cannot open lasreaderpipeon with lasreadertxt\n");
1206             delete lasreaderpipeon;
1207             return 0;
1208           }
1209           return lasreaderpipeon;
1210         }
1211         else
1212         {
1213           return lasreader;
1214         }
1215       }
1216     }
1217   }
1218   else if (use_stdin)
1219   {
1220     use_stdin = FALSE; populate_header = TRUE;
1221     if (itxt)
1222     {
1223       LASreaderTXT* lasreadertxt = new LASreaderTXT();
1224       if (ipts) lasreadertxt->set_pts(TRUE);
1225       else if (iptx) lasreadertxt->set_ptx(TRUE);
1226       if (translate_intensity != 0.0f) lasreadertxt->set_translate_intensity(translate_intensity);
1227       if (scale_intensity != 1.0f) lasreadertxt->set_scale_intensity(scale_intensity);
1228       if (translate_scan_angle != 0.0f) lasreadertxt->set_translate_scan_angle(translate_scan_angle);
1229       if (scale_scan_angle != 1.0f) lasreadertxt->set_scale_scan_angle(scale_scan_angle);
1230       lasreadertxt->set_scale_factor(scale_factor);
1231       lasreadertxt->set_offset(offset);
1232       if (number_attributes)
1233       {
1234         for (I32 i = 0; i < number_attributes; i++)
1235         {
1236           lasreadertxt->add_attribute(attribute_data_types[i], attribute_names[i], attribute_descriptions[i], attribute_scales[i], attribute_offsets[i], attribute_pre_scales[i], attribute_pre_offsets[i], attribute_no_datas[i]);
1237         }
1238       }
1239       if (!lasreadertxt->open(stdin, 0, point_type, parse_string, skip_lines, FALSE))
1240       {
1241         fprintf(stderr,"ERROR: cannot open lasreadertxt with file name '%s'\n", file_name);
1242         delete lasreadertxt;
1243         return 0;
1244       }
1245       if (files_are_flightlines) lasreadertxt->header.file_source_ID = file_name_current + files_are_flightlines + files_are_flightlines_index;
1246       if (filter) lasreadertxt->set_filter(filter);
1247       if (transform) lasreadertxt->set_transform(transform);
1248       if (inside_tile) lasreadertxt->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1249       if (inside_circle) lasreadertxt->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1250       if (inside_rectangle) lasreadertxt->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1251       LASreader* lasreader = 0;
1252       if (stored)
1253       {
1254         LASreaderStored* lasreaderstored = new LASreaderStored();
1255         if (!lasreaderstored->open(lasreadertxt))
1256         {
1257           fprintf(stderr, "ERROR: could not open lasreaderstored with lasreadertxt\n");
1258           delete lasreaderstored;
1259           return 0;
1260         }
1261         lasreader = lasreaderstored;
1262       }
1263       else
1264       {
1265         lasreader = lasreadertxt;
1266       }
1267       if (pipe_on)
1268       {
1269         LASreaderPipeOn* lasreaderpipeon = new LASreaderPipeOn();
1270         if (!lasreaderpipeon->open(lasreader))
1271         {
1272           fprintf(stderr,"ERROR: cannot open lasreaderpipeon with lasreadertxt\n");
1273           delete lasreaderpipeon;
1274           return 0;
1275         }
1276         return lasreaderpipeon;
1277       }
1278       else
1279       {
1280         return lasreader;
1281       }
1282     }
1283     else
1284     {
1285       LASreaderLAS* lasreaderlas;
1286       if (scale_factor == 0 && offset == 0)
1287         lasreaderlas = new LASreaderLAS();
1288       else if (scale_factor != 0 && offset == 0)
1289         lasreaderlas = new LASreaderLASrescale(scale_factor[0], scale_factor[1], scale_factor[2]);
1290       else if (scale_factor == 0 && offset != 0)
1291         lasreaderlas = new LASreaderLASreoffset(offset[0], offset[1], offset[2]);
1292       else
1293         lasreaderlas = new LASreaderLASrescalereoffset(scale_factor[0], scale_factor[1], scale_factor[2], offset[0], offset[1], offset[2]);
1294       if (!lasreaderlas->open(stdin))
1295       {
1296         fprintf(stderr,"ERROR: cannot open lasreaderlas from stdin \n");
1297         delete lasreaderlas;
1298         return 0;
1299       }
1300       if (filter) lasreaderlas->set_filter(filter);
1301       if (transform) lasreaderlas->set_transform(transform);
1302       if (inside_tile) lasreaderlas->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1303       if (inside_circle) lasreaderlas->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1304       if (inside_rectangle) lasreaderlas->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1305       LASreader* lasreader = 0;
1306       if (stored)
1307       {
1308         LASreaderStored* lasreaderstored = new LASreaderStored();
1309         if (!lasreaderstored->open(lasreaderlas))
1310         {
1311           fprintf(stderr, "ERROR: could not open lasreaderstored with lasreaderlas\n");
1312           delete lasreaderstored;
1313           return 0;
1314         }
1315         lasreader = lasreaderstored;
1316       }
1317       else
1318       {
1319         lasreader = lasreaderlas;
1320       }
1321       if (pipe_on)
1322       {
1323         LASreaderPipeOn* lasreaderpipeon = new LASreaderPipeOn();
1324         if (!lasreaderpipeon->open(lasreader))
1325         {
1326           fprintf(stderr,"ERROR: cannot open lasreaderpipeon with lasreaderlas from stdin\n");
1327           delete lasreaderpipeon;
1328           return 0;
1329         }
1330         return lasreaderpipeon;
1331       }
1332       else
1333       {
1334         return lasreader;
1335       }
1336     }
1337   }
1338   else
1339   {
1340     return 0;
1341   }
1342 }
1343 
reopen(LASreader * lasreader,BOOL remain_buffered)1344 BOOL LASreadOpener::reopen(LASreader* lasreader, BOOL remain_buffered)
1345 {
1346   if (lasreader == 0)
1347   {
1348     fprintf(stderr,"ERROR: pointer to LASreader is NULL\n");
1349   }
1350 
1351   // make sure the LASreader was closed
1352 
1353   lasreader->close();
1354 
1355   if (filter) filter->reset();
1356   if (transform) transform->reset();
1357 
1358   if (pipe_on)
1359   {
1360     LASreaderPipeOn* lasreaderpipeon = (LASreaderPipeOn*)lasreader;
1361     lasreaderpipeon->p_count = 0;
1362     lasreader = lasreaderpipeon->get_lasreader();
1363   }
1364 
1365   if (stored)
1366   {
1367     LASreaderStored* lasreaderstored = (LASreaderStored*)lasreader;
1368     if (!lasreaderstored->reopen())
1369     {
1370       fprintf(stderr, "ERROR: could not reopen lasreaderstored for stored input\n");
1371       return FALSE;
1372     }
1373     return TRUE;
1374   }
1375   else if (file_names)
1376   {
1377     if ((file_name_number > 1) && merged)
1378     {
1379       LASreaderMerged* lasreadermerged = (LASreaderMerged*)lasreader;
1380       if (!lasreadermerged->reopen())
1381       {
1382         fprintf(stderr,"ERROR: cannot reopen lasreadermerged\n");
1383         return FALSE;
1384       }
1385       if (inside_rectangle || inside_tile || inside_circle)
1386       {
1387         lasreadermerged->inside_none();
1388         if (inside_rectangle) lasreadermerged->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1389         else if (inside_tile) lasreadermerged->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1390         else lasreadermerged->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1391       }
1392       return TRUE;
1393     }
1394     else if ((buffer_size > 0) && ((file_name_number > 1) || (neighbor_file_name_number > 0)))
1395     {
1396       LASreaderBuffered* lasreaderbuffered = (LASreaderBuffered*)lasreader;
1397       if (!lasreaderbuffered->reopen())
1398       {
1399         fprintf(stderr,"ERROR: cannot reopen lasreaderbuffered\n");
1400         return FALSE;
1401       }
1402       if (inside_rectangle || inside_tile || inside_circle)
1403       {
1404         lasreaderbuffered->inside_none();
1405         if (inside_rectangle) lasreaderbuffered->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1406         else if (inside_tile) lasreaderbuffered->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1407         else lasreaderbuffered->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1408       }
1409       if (!remain_buffered) lasreaderbuffered->remove_buffer();
1410       return TRUE;
1411     }
1412     else
1413     {
1414       if (!file_name) return FALSE;
1415       if (strstr(file_name, ".las") || strstr(file_name, ".laz") || strstr(file_name, ".LAS") || strstr(file_name, ".LAZ"))
1416       {
1417         LASreaderLAS* lasreaderlas = (LASreaderLAS*)lasreader;
1418         if (!lasreaderlas->open(file_name, io_ibuffer_size, FALSE, decompress_selective))
1419         {
1420           fprintf(stderr,"ERROR: cannot reopen lasreaderlas with file name '%s'\n", file_name);
1421           return FALSE;
1422         }
1423         if (inside_rectangle || inside_tile || inside_circle)
1424         {
1425           lasreaderlas->inside_none();
1426           if (inside_rectangle) lasreaderlas->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1427           else if (inside_tile) lasreaderlas->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1428           else lasreaderlas->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1429         }
1430         return TRUE;
1431       }
1432       else if (strstr(file_name, ".bin") || strstr(file_name, ".BIN"))
1433       {
1434         LASreaderBIN* lasreaderbin = (LASreaderBIN*)lasreader;
1435         if (!lasreaderbin->open(file_name))
1436         {
1437           fprintf(stderr,"ERROR: cannot reopen lasreaderbin with file name '%s'\n", file_name);
1438           return FALSE;
1439         }
1440         if (inside_rectangle || inside_tile || inside_circle)
1441         {
1442           lasreaderbin->inside_none();
1443           if (inside_rectangle) lasreaderbin->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1444           else if (inside_tile) lasreaderbin->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1445           else lasreaderbin->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1446         }
1447         return TRUE;
1448       }
1449       else if (strstr(file_name, ".shp") || strstr(file_name, ".SHP"))
1450       {
1451         LASreaderSHP* lasreadershp = (LASreaderSHP*)lasreader;
1452         if (!lasreadershp->reopen(file_name))
1453         {
1454           fprintf(stderr,"ERROR: cannot reopen lasreadershp with file name '%s'\n", file_name);
1455           return FALSE;
1456         }
1457         if (inside_rectangle || inside_tile || inside_circle)
1458         {
1459           lasreadershp->inside_none();
1460           if (inside_rectangle) lasreadershp->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1461           else if (inside_tile) lasreadershp->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1462           else lasreadershp->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1463         }
1464         return TRUE;
1465       }
1466       else if (strstr(file_name, ".qi") || strstr(file_name, ".QI"))
1467       {
1468         LASreaderQFIT* lasreaderqfit = (LASreaderQFIT*)lasreader;
1469         if (!lasreaderqfit->reopen(file_name))
1470         {
1471           fprintf(stderr,"ERROR: cannot reopen lasreaderqfit with file name '%s'\n", file_name);
1472           return FALSE;
1473         }
1474         if (inside_rectangle || inside_tile || inside_circle)
1475         {
1476           lasreaderqfit->inside_none();
1477           if (inside_rectangle) lasreaderqfit->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1478           else if (inside_tile) lasreaderqfit->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1479           else lasreaderqfit->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1480         }
1481         return TRUE;
1482       }
1483       else if (strstr(file_name, ".asc") || strstr(file_name, ".ASC"))
1484       {
1485         LASreaderASC* lasreaderasc = (LASreaderASC*)lasreader;
1486         if (!lasreaderasc->reopen(file_name))
1487         {
1488           fprintf(stderr,"ERROR: cannot reopen lasreaderasc with file name '%s'\n", file_name);
1489           return FALSE;
1490         }
1491         if (inside_rectangle || inside_tile || inside_circle)
1492         {
1493           lasreaderasc->inside_none();
1494           if (inside_rectangle) lasreaderasc->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1495           else if (inside_tile) lasreaderasc->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1496           else lasreaderasc->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1497         }
1498         return TRUE;
1499       }
1500       else if (strstr(file_name, ".bil") || strstr(file_name, ".BIL"))
1501       {
1502         LASreaderBIL* lasreaderbil = (LASreaderBIL*)lasreader;
1503         if (!lasreaderbil->reopen(file_name))
1504         {
1505           fprintf(stderr,"ERROR: cannot reopen lasreaderbil with file name '%s'\n", file_name);
1506           return FALSE;
1507         }
1508         if (inside_rectangle || inside_tile || inside_circle)
1509         {
1510           lasreaderbil->inside_none();
1511           if (inside_rectangle) lasreaderbil->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1512           else if (inside_tile) lasreaderbil->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1513           else lasreaderbil->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1514         }
1515         return TRUE;
1516       }
1517       else if (strstr(file_name, ".dtm") || strstr(file_name, ".DTM"))
1518       {
1519         LASreaderDTM* lasreaderdtm = (LASreaderDTM*)lasreader;
1520         if (!lasreaderdtm->reopen(file_name))
1521         {
1522           fprintf(stderr,"ERROR: cannot reopen lasreaderdtm with file name '%s'\n", file_name);
1523           return FALSE;
1524         }
1525         if (inside_rectangle || inside_tile || inside_circle)
1526         {
1527           lasreaderdtm->inside_none();
1528           if (inside_rectangle) lasreaderdtm->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1529           else if (inside_tile) lasreaderdtm->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1530           else lasreaderdtm->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1531         }
1532         return TRUE;
1533       }
1534       else
1535       {
1536         LASreaderTXT* lasreadertxt = (LASreaderTXT*)lasreader;
1537         if (!lasreadertxt->reopen(file_name))
1538         {
1539           fprintf(stderr,"ERROR: cannot reopen lasreadertxt with file name '%s'\n", file_name);
1540           return FALSE;
1541         }
1542         if (inside_rectangle || inside_tile || inside_circle)
1543         {
1544           lasreadertxt->inside_none();
1545           if (inside_rectangle) lasreadertxt->inside_rectangle(inside_rectangle[0], inside_rectangle[1], inside_rectangle[2], inside_rectangle[3]);
1546           else if (inside_tile) lasreadertxt->inside_tile(inside_tile[0], inside_tile[1], inside_tile[2]);
1547           else lasreadertxt->inside_circle(inside_circle[0], inside_circle[1], inside_circle[2]);
1548         }
1549         return TRUE;
1550       }
1551     }
1552   }
1553   else
1554   {
1555     fprintf(stderr,"ERROR: no lasreader input specified\n");
1556     return FALSE;
1557   }
1558 }
1559 
open_waveform13(const LASheader * lasheader)1560 LASwaveform13reader* LASreadOpener::open_waveform13(const LASheader* lasheader)
1561 {
1562   if (lasheader->point_data_format < 4) return 0;
1563   if ((lasheader->point_data_format > 5) && (lasheader->point_data_format < 9)) return 0;
1564   if (lasheader->vlr_wave_packet_descr == 0) return 0;
1565   if (get_file_name() == 0) return 0;
1566   LASwaveform13reader* waveform13reader = new LASwaveform13reader();
1567   if ((lasheader->global_encoding & 2) && (lasheader->start_of_waveform_data_packet_record > lasheader->offset_to_point_data))
1568   {
1569     if (waveform13reader->open(get_file_name(), lasheader->start_of_waveform_data_packet_record, lasheader->vlr_wave_packet_descr))
1570     {
1571       return waveform13reader;
1572     }
1573   }
1574   else
1575   {
1576     if (waveform13reader->open(get_file_name(), 0, lasheader->vlr_wave_packet_descr))
1577     {
1578       return waveform13reader;
1579     }
1580   }
1581   delete waveform13reader;
1582   return 0;
1583 }
1584 
usage() const1585 void LASreadOpener::usage() const
1586 {
1587   fprintf(stderr,"Supported LAS Inputs\n");
1588   fprintf(stderr,"  -i lidar.las\n");
1589   fprintf(stderr,"  -i lidar.laz\n");
1590   fprintf(stderr,"  -i lidar1.las lidar2.las lidar3.las -merged\n");
1591   fprintf(stderr,"  -i *.las - merged\n");
1592   fprintf(stderr,"  -i flight0??.laz flight1??.laz\n");
1593   fprintf(stderr,"  -i terrasolid.bin\n");
1594   fprintf(stderr,"  -i esri.shp\n");
1595   fprintf(stderr,"  -i nasa.qi\n");
1596   fprintf(stderr,"  -i lidar.txt -iparse xyzti -iskip 2 (on-the-fly from ASCII)\n");
1597   fprintf(stderr,"  -i lidar.txt -iparse xyzi -itranslate_intensity 1024\n");
1598   fprintf(stderr,"  -lof file_list.txt\n");
1599   fprintf(stderr,"  -stdin (pipe from stdin)\n");
1600   fprintf(stderr,"  -rescale 0.01 0.01 0.001\n");
1601   fprintf(stderr,"  -rescale_xy 0.01 0.01\n");
1602   fprintf(stderr,"  -rescale_z 0.01\n");
1603   fprintf(stderr,"  -reoffset 600000 4000000 0\n");
1604   fprintf(stderr,"Fast AOI Queries for LAS/LAZ with spatial indexing LAX files\n");
1605   fprintf(stderr,"  -inside min_x min_y max_x max_y\n");
1606   fprintf(stderr,"  -inside_tile ll_x ll_y size\n");
1607   fprintf(stderr,"  -inside_circle center_x center_y radius\n");
1608 }
1609 
parse(int argc,char * argv[])1610 BOOL LASreadOpener::parse(int argc, char* argv[])
1611 {
1612   int i;
1613   for (i = 1; i < argc; i++)
1614   {
1615     if (argv[i][0] == '\0')
1616     {
1617       continue;
1618     }
1619     else if (strcmp(argv[i],"-h") == 0)
1620     {
1621       LASfilter().usage();
1622       LAStransform().usage();
1623       usage();
1624       return TRUE;
1625     }
1626     else if (strcmp(argv[i],"-i") == 0)
1627     {
1628       if ((i+1) >= argc)
1629       {
1630         fprintf(stderr,"ERROR: '%s' needs at least 1 argument: file_name or wild_card\n", argv[i]);
1631         return FALSE;
1632       }
1633       *argv[i]='\0';
1634       i+=1;
1635       do
1636       {
1637         add_file_name(argv[i], unique);
1638         *argv[i]='\0';
1639         i+=1;
1640       } while ((i < argc) && (*argv[i] != '-') && (*argv[i] != '\0'));
1641       i-=1;
1642     }
1643     else if (strcmp(argv[i],"-unique") == 0)
1644     {
1645       unique = TRUE;
1646       *argv[i]='\0';
1647     }
1648     else if (strncmp(argv[i],"-inside", 7) == 0)
1649     {
1650       if (strcmp(argv[i],"-inside_tile") == 0)
1651       {
1652         if ((i+3) >= argc)
1653         {
1654           fprintf(stderr,"ERROR: '%s' needs 3 arguments: ll_x, ll_y, size\n", argv[i]);
1655           return FALSE;
1656         }
1657         set_inside_tile((F32)atof(argv[i+1]), (F32)atof(argv[i+2]), (F32)atof(argv[i+3]));
1658         *argv[i]='\0'; *argv[i+1]='\0'; *argv[i+2]='\0'; *argv[i+3]='\0'; i+=3;
1659       }
1660       else if (strcmp(argv[i],"-inside_circle") == 0)
1661       {
1662         if ((i+3) >= argc)
1663         {
1664           fprintf(stderr,"ERROR: '%s' needs 3 arguments: center_x, center_y, radius\n", argv[i]);
1665           return FALSE;
1666         }
1667         set_inside_circle(atof(argv[i+1]), atof(argv[i+2]), atof(argv[i+3]));
1668         *argv[i]='\0'; *argv[i+1]='\0'; *argv[i+2]='\0'; *argv[i+3]='\0'; i+=3;
1669       }
1670       else if (strcmp(argv[i],"-inside") == 0 || strcmp(argv[i],"-inside_rectangle") == 0)
1671       {
1672         if ((i+4) >= argc)
1673         {
1674           fprintf(stderr,"ERROR: '%s' needs 4 arguments: min_x, min_y, max_x, max_y\n", argv[i]);
1675           return FALSE;
1676         }
1677         set_inside_rectangle(atof(argv[i+1]), atof(argv[i+2]), atof(argv[i+3]), atof(argv[i+4]));
1678         *argv[i]='\0'; *argv[i+1]='\0'; *argv[i+2]='\0'; *argv[i+3]='\0'; *argv[i+4]='\0'; i+=4;
1679       }
1680       else
1681       {
1682         fprintf(stderr,"ERROR: unknown '-inside' option '%s'\n", argv[i]);
1683         return FALSE;
1684       }
1685     }
1686     else if (strcmp(argv[i],"-comma_not_point") == 0)
1687     {
1688       comma_not_point = TRUE;
1689       *argv[i]='\0';
1690     }
1691     else if (strcmp(argv[i],"-stdin") == 0)
1692     {
1693       use_stdin = TRUE;
1694       *argv[i]='\0';
1695     }
1696     else if (strcmp(argv[i],"-lof") == 0)
1697     {
1698       if ((i+1) >= argc)
1699       {
1700         fprintf(stderr,"ERROR: '%s' needs 1 argument: list_of_files\n", argv[i]);
1701         return FALSE;
1702       }
1703       if (!add_list_of_files(argv[i+1]), unique)
1704       {
1705         fprintf(stderr, "ERROR: cannot load list of files '%s'\n", argv[i+1]);
1706         return FALSE;
1707       }
1708       *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
1709     }
1710     else if (strcmp(argv[i],"-rescale") == 0)
1711     {
1712       if ((i+3) >= argc)
1713       {
1714         fprintf(stderr,"ERROR: '%s' needs 3 arguments: rescale_x rescale_y rescale_z\n", argv[i]);
1715         return FALSE;
1716       }
1717       F64 scale_factor[3];
1718       scale_factor[0] = atof(argv[i+1]);
1719       scale_factor[1] = atof(argv[i+2]);
1720       scale_factor[2] = atof(argv[i+3]);
1721       set_scale_factor(scale_factor);
1722       *argv[i]='\0'; *argv[i+1]='\0'; *argv[i+2]='\0'; *argv[i+3]='\0'; i+=3;
1723     }
1724     else if (strcmp(argv[i],"-rescale_xy") == 0)
1725     {
1726       if ((i+2) >= argc)
1727       {
1728         fprintf(stderr,"ERROR: '%s' needs 2 argument: rescale_x rescale_y\n", argv[i]);
1729         return FALSE;
1730       }
1731       F64 scale_factor[3];
1732       scale_factor[0] = atof(argv[i+1]);
1733       scale_factor[1] = atof(argv[i+2]);
1734       scale_factor[2] = 0;
1735       set_scale_factor(scale_factor);
1736       *argv[i]='\0'; *argv[i+1]='\0'; *argv[i+2]='\0'; i+=2;
1737     }
1738     else if (strcmp(argv[i],"-rescale_z") == 0)
1739     {
1740       if ((i+1) >= argc)
1741       {
1742         fprintf(stderr,"ERROR: '%s' needs 1 argument: scale\n", argv[i]);
1743         return FALSE;
1744       }
1745       F64 scale_factor[3];
1746       scale_factor[0] = 0;
1747       scale_factor[1] = 0;
1748       scale_factor[2] = atof(argv[i+1]);
1749       set_scale_factor(scale_factor);
1750       *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
1751     }
1752     else if (strcmp(argv[i],"-reoffset") == 0)
1753     {
1754       if ((i+3) >= argc)
1755       {
1756         fprintf(stderr,"ERROR: '%s' needs 3 arguments: reoffset_x, reoffset_y, reoffset_z\n", argv[i]);
1757         return FALSE;
1758       }
1759       F64 offset[3];
1760 			offset[0] = atof(argv[i+1]);
1761 			offset[1] = atof(argv[i+2]);
1762 			offset[2] = atof(argv[i+3]);
1763       set_offset(offset);
1764       *argv[i]='\0'; *argv[i+1]='\0'; *argv[i+2]='\0'; *argv[i+3]='\0'; i+=3;
1765     }
1766     else if (strcmp(argv[i],"-auto_reoffset") == 0)
1767     {
1768       set_auto_reoffset(TRUE);
1769       *argv[i]='\0';
1770     }
1771     else if (strcmp(argv[i],"-files_are_flightlines") == 0 || strcmp(argv[i],"-faf") == 0)
1772     {
1773       if (((i+1) < argc) && ('1' <= argv[i+1][0]) && (argv[i+1][0] <= '9'))
1774       {
1775         set_files_are_flightlines(atoi(argv[i+1]));
1776         *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
1777       }
1778       else
1779       {
1780         set_files_are_flightlines(1);
1781         *argv[i]='\0';
1782       }
1783     }
1784     else if (strcmp(argv[i],"-faf_index") == 0)
1785     {
1786       if ((i+1) >= argc)
1787       {
1788         fprintf(stderr,"ERROR: '%s' needs 1 argument: index\n", argv[i]);
1789         return FALSE;
1790       }
1791       set_files_are_flightlines_index(atoi(argv[i+1]));
1792       *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
1793     }
1794     else if (strcmp(argv[i],"-apply_file_source_ID") == 0)
1795     {
1796       set_apply_file_source_ID(TRUE);
1797       *argv[i]='\0';
1798     }
1799     else if (strcmp(argv[i],"-itranslate_intensity") == 0)
1800     {
1801       if ((i+1) >= argc)
1802       {
1803         fprintf(stderr,"ERROR: '%s' needs 1 argument: offset\n", argv[i]);
1804         return FALSE;
1805       }
1806       set_translate_intensity((F32)atof(argv[i+1]));
1807       *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
1808     }
1809     else if (strcmp(argv[i],"-iscale_intensity") == 0)
1810     {
1811       if ((i+1) >= argc)
1812       {
1813         fprintf(stderr,"ERROR: '%s' needs 1 argument: scale\n", argv[i]);
1814         return FALSE;
1815       }
1816       set_scale_intensity((F32)atof(argv[i+1]));
1817       *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
1818     }
1819     else if (strcmp(argv[i],"-itranslate_scan_angle") == 0)
1820     {
1821       if ((i+1) >= argc)
1822       {
1823         fprintf(stderr,"ERROR: '%s' needs 1 argument: offset\n", argv[i]);
1824         return FALSE;
1825       }
1826       set_translate_scan_angle((F32)atof(argv[i+1]));
1827       *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
1828     }
1829     else if (strcmp(argv[i],"-iscale_scan_angle") == 0)
1830     {
1831       if ((i+1) >= argc)
1832       {
1833         fprintf(stderr,"ERROR: '%s' needs 1 argument: scale\n", argv[i]);
1834         return FALSE;
1835       }
1836       set_scale_scan_angle((F32)atof(argv[i+1]));
1837       *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
1838     }
1839     else if (strcmp(argv[i],"-iadd_extra") == 0 || strcmp(argv[i],"-iadd_attribute") == 0)
1840     {
1841       if ((i+3) >= argc)
1842       {
1843         fprintf(stderr,"ERROR: '%s' needs 3 arguments: data_type name description\n", argv[i]);
1844         return FALSE;
1845       }
1846       if (((i+4) < argc) && (atof(argv[i+4]) != 0.0))
1847       {
1848         if (((i+5) < argc) && ((atof(argv[i+5]) != 0.0) || (strcmp(argv[i+5], "0") == 0) || (strcmp(argv[i+5], "0.0") == 0)))
1849         {
1850           if (((i+6) < argc) && (atof(argv[i+6]) != 0.0))
1851           {
1852             if (((i+7) < argc) && ((atof(argv[i+7]) != 0.0) || (strcmp(argv[i+7], "0") == 0) || (strcmp(argv[i+7], "0.0") == 0)))
1853             {
1854               if (((i+8) < argc) && ((atof(argv[i+8]) != 0.0) || (strcmp(argv[i+8], "0") == 0) || (strcmp(argv[i+8], "0.0") == 0)))
1855               {
1856                 add_attribute(atoi(argv[i+1]), argv[i+2], argv[i+3], atof(argv[i+4]), atof(argv[i+5]), atof(argv[i+6]), atof(argv[i+7]), atof(argv[i+8]));
1857                 *argv[i]='\0'; *argv[i+1]='\0'; *argv[i+2]='\0'; *argv[i+3]='\0'; *argv[i+4]='\0'; *argv[i+5]='\0'; *argv[i+6]='\0'; *argv[i+7]='\0'; *argv[i+8]='\0'; i+=8;
1858               }
1859               else
1860               {
1861                 add_attribute(atoi(argv[i+1]), argv[i+2], argv[i+3], atof(argv[i+4]), atof(argv[i+5]), atof(argv[i+6]), atof(argv[i+7]));
1862                 *argv[i]='\0'; *argv[i+1]='\0'; *argv[i+2]='\0'; *argv[i+3]='\0'; *argv[i+4]='\0'; *argv[i+5]='\0'; *argv[i+6]='\0'; *argv[i+7]='\0'; i+=7;
1863               }
1864             }
1865             else
1866             {
1867               add_attribute(atoi(argv[i+1]), argv[i+2], argv[i+3], atof(argv[i+4]), atof(argv[i+5]), atof(argv[i+6]));
1868               *argv[i]='\0'; *argv[i+1]='\0'; *argv[i+2]='\0'; *argv[i+3]='\0'; *argv[i+4]='\0'; *argv[i+5]='\0'; *argv[i+6]='\0'; i+=6;
1869             }
1870           }
1871           else
1872           {
1873             add_attribute(atoi(argv[i+1]), argv[i+2], argv[i+3], atof(argv[i+4]), atof(argv[i+5]));
1874             *argv[i]='\0'; *argv[i+1]='\0'; *argv[i+2]='\0'; *argv[i+3]='\0'; *argv[i+4]='\0'; *argv[i+5]='\0'; i+=5;
1875           }
1876         }
1877         else
1878         {
1879           add_attribute(atoi(argv[i+1]), argv[i+2], argv[i+3], atof(argv[i+4]));
1880           *argv[i]='\0'; *argv[i+1]='\0'; *argv[i+2]='\0'; *argv[i+3]='\0'; *argv[i+4]='\0'; i+=4;
1881         }
1882       }
1883       else
1884       {
1885         add_attribute(atoi(argv[i+1]), argv[i+2], argv[i+3]);
1886         *argv[i]='\0'; *argv[i+1]='\0'; *argv[i+2]='\0'; *argv[i+3]='\0'; i+=3;
1887       }
1888     }
1889     else if (strcmp(argv[i],"-iparse") == 0)
1890     {
1891       if ((i+1) >= argc)
1892       {
1893         fprintf(stderr,"ERROR: '%s' needs 1 argument: string\n", argv[i]);
1894         return FALSE;
1895       }
1896       set_parse_string(argv[i+1]);
1897       *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
1898     }
1899     else if (strcmp(argv[i],"-iskip") == 0)
1900     {
1901       if ((i+1) >= argc)
1902       {
1903         fprintf(stderr,"ERROR: '%s' needs 1 argument: number_of_lines\n", argv[i]);
1904         return FALSE;
1905       }
1906       set_skip_lines(atoi(argv[i+1]));
1907       *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
1908     }
1909     else if (strcmp(argv[i],"-merged") == 0)
1910     {
1911       set_merged(TRUE);
1912       *argv[i]='\0';
1913     }
1914     else if (strcmp(argv[i],"-stored") == 0)
1915     {
1916       set_stored(TRUE);
1917       *argv[i]='\0';
1918     }
1919     else if (strcmp(argv[i],"-buffered") == 0)
1920     {
1921       if ((i+1) >= argc)
1922       {
1923         fprintf(stderr,"ERROR: '%s' needs 1 argument: size\n", argv[i]);
1924         return FALSE;
1925       }
1926       set_buffer_size((F32)atof(argv[i+1]));
1927       *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
1928     }
1929     else if (strcmp(argv[i],"-temp_files") == 0)
1930     {
1931       if ((i+1) >= argc)
1932       {
1933         fprintf(stderr,"ERROR: '%s' needs 1 argument: base name\n", argv[i]);
1934         return FALSE;
1935       }
1936       temp_file_base = LASCopyString(argv[i+1]);
1937       *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
1938     }
1939     else if (strcmp(argv[i],"-neighbors") == 0)
1940     {
1941       if ((i+1) >= argc)
1942       {
1943         fprintf(stderr,"ERROR: '%s' needs at least 1 argument: file_name or wild_card\n", argv[i]);
1944         return FALSE;
1945       }
1946       *argv[i]='\0';
1947       i+=1;
1948       do
1949       {
1950         add_neighbor_file_name(argv[i]);
1951         *argv[i]='\0';
1952         i+=1;
1953       } while ((i < argc) && (*argv[i] != '-') && (*argv[i] != '\0'));
1954       i-=1;
1955     }
1956     else if (strcmp(argv[i],"-neighbors_lof") == 0)
1957     {
1958       if ((i+1) >= argc)
1959       {
1960         fprintf(stderr,"ERROR: '%s' needs at least 1 argument: file_name\n", argv[i]);
1961         return FALSE;
1962       }
1963       FILE* file = fopen(argv[i+1], "r");
1964       if (file == 0)
1965       {
1966         fprintf(stderr, "ERROR: cannot open '%s'\n", argv[i+1]);
1967         return FALSE;
1968       }
1969       CHAR line[1024];
1970       while (fgets(line, 1024, file))
1971       {
1972         // find end of line
1973         I32 len = (I32)strlen(line) - 1;
1974         // remove extra white spaces and line return at the end
1975         while (len > 0 && ((line[len] == '\n') || (line[len] == ' ') || (line[len] == '\t') || (line[len] == '\012')))
1976         {
1977           line[len] = '\0';
1978           len--;
1979         }
1980 #ifdef _WIN32
1981         add_neighbor_file_name_single(line);
1982 #else
1983         add_neighbor_file_name(line);
1984 #endif
1985       }
1986       fclose(file);
1987       *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
1988     }
1989     else if (strcmp(argv[i],"-pipe_on") == 0)
1990     {
1991       set_pipe_on(TRUE);
1992       *argv[i]='\0';
1993     }
1994     else if (strcmp(argv[i],"-populate") == 0)
1995     {
1996       set_populate_header(TRUE);
1997       *argv[i]='\0';
1998     }
1999     else if (strcmp(argv[i],"-io_ibuffer") == 0)
2000     {
2001       if ((i+1) >= argc)
2002       {
2003         fprintf(stderr,"ERROR: '%s' needs 1 argument: size\n", argv[i]);
2004         return FALSE;
2005       }
2006       set_io_ibuffer_size((I32)atoi(argv[i+1]));
2007       *argv[i]='\0'; *argv[i+1]='\0'; i+=1;
2008     }
2009     else if (strcmp(argv[i],"-do_not_populate") == 0)
2010     {
2011       set_populate_header(FALSE);
2012       *argv[i]='\0';
2013     }
2014     else if (strcmp(argv[i],"-ipts") == 0)
2015     {
2016       itxt = TRUE;
2017       ipts = TRUE;
2018       *argv[i]='\0';
2019     }
2020     else if (strcmp(argv[i],"-iptx") == 0)
2021     {
2022       itxt = TRUE;
2023       iptx = TRUE;
2024       *argv[i]='\0';
2025     }
2026     else if (strcmp(argv[i],"-itxt") == 0)
2027     {
2028       itxt = TRUE;
2029       *argv[i]='\0';
2030     }
2031   }
2032 
2033   // check that there are only buffered neighbors for single files
2034 
2035   if (neighbor_file_name_number)
2036   {
2037     if (file_name_number > 1)
2038     {
2039       fprintf(stderr, "ERROR: neighbors only supported for one buffered input file, not for %d\n", file_name_number);
2040       return FALSE;
2041     }
2042     if (buffer_size == 0.0f)
2043     {
2044       fprintf(stderr, "ERROR: neighbors only make sense when used with '-buffered 50' or similar\n");
2045       return FALSE;
2046     }
2047   }
2048 
2049   if (filter) filter->clean();
2050   else filter = new LASfilter();
2051   if (!filter->parse(argc, argv))
2052   {
2053     delete filter;
2054     return FALSE;
2055   }
2056   if (!filter->active())
2057   {
2058     delete filter;
2059     filter = 0;
2060   }
2061 
2062   if (transform) transform->clean();
2063   else transform = new LAStransform();
2064   if (!transform->parse(argc, argv))
2065   {
2066     delete transform;
2067     return FALSE;
2068   }
2069   if (!transform->active())
2070   {
2071     delete transform;
2072     transform = 0;
2073   }
2074   else if (transform->filtered())
2075   {
2076     transform->setFilter(filter);
2077     filter = 0;
2078   }
2079 
2080   if (files_are_flightlines || apply_file_source_ID)
2081   {
2082     if (transform == 0) transform = new LAStransform();
2083     transform->setPointSource(0);
2084   }
2085 
2086   return TRUE;
2087 }
2088 
get_file_name_number() const2089 U32 LASreadOpener::get_file_name_number() const
2090 {
2091   return file_name_number;
2092 }
2093 
get_file_name_current() const2094 U32 LASreadOpener::get_file_name_current() const
2095 {
2096   return file_name_current;
2097 }
2098 
get_file_name() const2099 const CHAR* LASreadOpener::get_file_name() const
2100 {
2101   if (file_name)
2102     return file_name;
2103   if (file_name_number)
2104     return file_names[0];
2105   return 0;
2106 }
2107 
get_file_name_only() const2108 const CHAR* LASreadOpener::get_file_name_only() const
2109 {
2110   const CHAR* file_name_only = 0;
2111   const CHAR* file_name_curr = get_file_name();
2112 
2113   if (file_name_curr)
2114   {
2115     I32 len = (I32)strlen(file_name_curr);
2116     while ((len > 0) && (file_name_curr[len] != '\\') && (file_name_curr[len] != '/') && (file_name_curr[len] != ':')) len--;
2117     if (len)
2118     {
2119       file_name_only = file_name_curr + len + 1;
2120     }
2121     else
2122     {
2123       file_name_only = file_name_curr;
2124     }
2125   }
2126 
2127   return file_name_only;
2128 }
2129 
get_file_name(U32 number) const2130 const CHAR* LASreadOpener::get_file_name(U32 number) const
2131 {
2132   return file_names[number];
2133 }
2134 
get_file_format(U32 number) const2135 I32 LASreadOpener::get_file_format(U32 number) const
2136 {
2137   if (strstr(file_names[number], ".las") || strstr(file_names[number], ".LAS"))
2138   {
2139     return LAS_TOOLS_FORMAT_LAS;
2140   }
2141   else if (strstr(file_names[number], ".laz") || strstr(file_names[number], ".LAZ"))
2142   {
2143     return LAS_TOOLS_FORMAT_LAZ;
2144   }
2145   else if (strstr(file_names[number], ".bin") || strstr(file_names[number], ".BIN"))
2146   {
2147     return LAS_TOOLS_FORMAT_BIN;
2148   }
2149   else if (strstr(file_names[number], ".shp") || strstr(file_names[number], ".SHP"))
2150   {
2151     return LAS_TOOLS_FORMAT_SHP;
2152   }
2153   else if (strstr(file_names[number], ".qi") || strstr(file_names[number], ".QI"))
2154   {
2155     return LAS_TOOLS_FORMAT_QFIT;
2156   }
2157   else if (strstr(file_names[number], ".asc") || strstr(file_names[number], ".ASC"))
2158   {
2159     return LAS_TOOLS_FORMAT_ASC;
2160   }
2161   else if (strstr(file_names[number], ".bil") || strstr(file_names[number], ".BIL"))
2162   {
2163     return LAS_TOOLS_FORMAT_BIL;
2164   }
2165   else if (strstr(file_names[number], ".dtm") || strstr(file_names[number], ".DTM"))
2166   {
2167     return LAS_TOOLS_FORMAT_DTM;
2168   }
2169   else
2170   {
2171     return LAS_TOOLS_FORMAT_TXT;
2172   }
2173 }
2174 
set_merged(const BOOL merged)2175 void LASreadOpener::set_merged(const BOOL merged)
2176 {
2177   this->merged = merged;
2178 }
2179 
set_stored(const BOOL stored)2180 void LASreadOpener::set_stored(const BOOL stored)
2181 {
2182   this->stored = stored;
2183 }
2184 
set_buffer_size(const F32 buffer_size)2185 void LASreadOpener::set_buffer_size(const F32 buffer_size)
2186 {
2187   this->buffer_size = buffer_size;
2188 }
2189 
get_buffer_size() const2190 F32 LASreadOpener::get_buffer_size() const
2191 {
2192   return buffer_size;
2193 }
2194 
set_filter(LASfilter * filter)2195 void LASreadOpener::set_filter(LASfilter* filter)
2196 {
2197   this->filter = filter;
2198 }
2199 
set_transform(LAStransform * transform)2200 void LASreadOpener::set_transform(LAStransform* transform)
2201 {
2202   this->transform = transform;
2203 }
2204 
set_auto_reoffset(const BOOL auto_reoffset)2205 void LASreadOpener::set_auto_reoffset(const BOOL auto_reoffset)
2206 {
2207   this->auto_reoffset = auto_reoffset;
2208 }
2209 
set_files_are_flightlines(const I32 files_are_flightlines)2210 void LASreadOpener::set_files_are_flightlines(const I32 files_are_flightlines)
2211 {
2212   this->files_are_flightlines = files_are_flightlines;
2213   if (files_are_flightlines > (I32)(U16_MAX))
2214   {
2215     fprintf(stderr, "WARNING: files_are_flightlines start value %d is too large\n", files_are_flightlines);
2216   }
2217   else if ((files_are_flightlines + files_are_flightlines_index) > (I32)(U16_MAX))
2218   {
2219     fprintf(stderr, "WARNING: files_are_flightlines start value %d plus index %d is too large\n", files_are_flightlines, files_are_flightlines_index);
2220   }
2221 }
2222 
set_files_are_flightlines_index(const I32 files_are_flightlines_index)2223 void LASreadOpener::set_files_are_flightlines_index(const I32 files_are_flightlines_index)
2224 {
2225   this->files_are_flightlines_index = files_are_flightlines_index-1;
2226   if (files_are_flightlines_index > (I32)(U16_MAX))
2227   {
2228     fprintf(stderr, "WARNING: files_are_flightlines_index index value %d is too large\n", files_are_flightlines_index);
2229   }
2230   else if ((files_are_flightlines + files_are_flightlines_index) > (I32)(U16_MAX))
2231   {
2232     fprintf(stderr, "WARNING: files_are_flightlines start value %d plus index %d is too large\n", files_are_flightlines, files_are_flightlines_index);
2233   }
2234 }
2235 
set_apply_file_source_ID(const BOOL apply_file_source_ID)2236 void LASreadOpener::set_apply_file_source_ID(const BOOL apply_file_source_ID)
2237 {
2238   this->apply_file_source_ID = apply_file_source_ID;
2239 }
2240 
set_io_ibuffer_size(I32 io_ibuffer_size)2241 void LASreadOpener::set_io_ibuffer_size(I32 io_ibuffer_size)
2242 {
2243   this->io_ibuffer_size = io_ibuffer_size;
2244 }
2245 
set_file_name(const CHAR * file_name,BOOL unique)2246 void LASreadOpener::set_file_name(const CHAR* file_name, BOOL unique)
2247 {
2248   add_file_name(file_name, unique);
2249 }
2250 
2251 #ifdef _WIN32
2252 #include <windows.h>
add_file_name(const CHAR * file_name,BOOL unique)2253 BOOL LASreadOpener::add_file_name(const CHAR* file_name, BOOL unique)
2254 {
2255   BOOL r = FALSE;
2256   HANDLE h;
2257   WIN32_FIND_DATA info;
2258   h = FindFirstFile(file_name, &info);
2259   if (h != INVALID_HANDLE_VALUE)
2260   {
2261     // find the path
2262     I32 len = (I32)strlen(file_name);
2263     while (len && (file_name[len] != '\\') && (file_name[len] != '/') && (file_name[len] != ':')) len--;
2264     if (len)
2265     {
2266       len++;
2267       CHAR full_file_name[512];
2268       strncpy(full_file_name, file_name, len);
2269 	    do
2270 	    {
2271         sprintf(&full_file_name[len], "%s", info.cFileName);
2272         if (add_file_name_single(full_file_name, unique)) r = TRUE;
2273   	  } while (FindNextFile(h, &info));
2274     }
2275     else
2276     {
2277       do
2278       {
2279         if (add_file_name_single(info.cFileName, unique)) r = TRUE;
2280   	  } while (FindNextFile(h, &info));
2281     }
2282 	  FindClose(h);
2283   }
2284   return r;
2285 }
2286 #endif
2287 
2288 #ifdef _WIN32
add_file_name_single(const CHAR * file_name,BOOL unique)2289 BOOL LASreadOpener::add_file_name_single(const CHAR* file_name, BOOL unique)
2290 #else
2291 BOOL LASreadOpener::add_file_name(const CHAR* file_name, BOOL unique)
2292 #endif
2293 {
2294   if (unique)
2295   {
2296     U32 i;
2297     for (i = 0; i < file_name_number; i++)
2298     {
2299       if (strcmp(file_names[i], file_name) == 0)
2300       {
2301         return FALSE;
2302       }
2303     }
2304   }
2305   if (file_name_number == file_name_allocated)
2306   {
2307     if (file_names)
2308     {
2309       file_name_allocated *= 2;
2310       file_names = (CHAR**)realloc(file_names, sizeof(CHAR*)*file_name_allocated);
2311     }
2312     else
2313     {
2314       file_name_allocated = 16;
2315       file_names = (CHAR**)malloc(sizeof(CHAR*)*file_name_allocated);
2316     }
2317     if (file_names == 0)
2318     {
2319       fprintf(stderr, "ERROR: alloc for file_names pointer array failed at %d\n", file_name_allocated);
2320     }
2321   }
2322   file_names[file_name_number] = LASCopyString(file_name);
2323   file_name_number++;
2324   return TRUE;
2325 }
2326 
add_list_of_files(const CHAR * list_of_files,BOOL unique)2327 BOOL LASreadOpener::add_list_of_files(const CHAR* list_of_files, BOOL unique)
2328 {
2329   FILE* file = fopen(list_of_files, "r");
2330   if (file == 0)
2331   {
2332     fprintf(stderr, "ERROR: cannot open '%s'\n", list_of_files);
2333     return FALSE;
2334   }
2335   CHAR line[1024];
2336   while (fgets(line, 1024, file))
2337   {
2338     // find end of line
2339     I32 len = (I32)strlen(line) - 1;
2340     // remove extra white spaces and line return at the end
2341     while (len > 0 && ((line[len] == '\n') || (line[len] == ' ') || (line[len] == '\t') || (line[len] == '\012')))
2342     {
2343       line[len] = '\0';
2344       len--;
2345     }
2346     add_file_name(line, unique);
2347   }
2348   fclose(file);
2349   return TRUE;
2350 }
2351 
delete_file_name(U32 file_name_id)2352 void LASreadOpener::delete_file_name(U32 file_name_id)
2353 {
2354   if (file_name_id < file_name_number)
2355   {
2356     U32 i;
2357     free(file_names[file_name_id]);
2358     for (i = file_name_id+1; i < file_name_number; i++)
2359     {
2360       file_names[i-1] = file_names[i];
2361     }
2362   }
2363   file_name_number--;
2364 }
2365 
set_file_name_current(U32 file_name_id)2366 BOOL LASreadOpener::set_file_name_current(U32 file_name_id)
2367 {
2368   if (file_name_id < file_name_number)
2369   {
2370     file_name_current = file_name_id;
2371     file_name = file_names[file_name_current];
2372     return TRUE;
2373   }
2374   return FALSE;
2375 }
2376 
2377 #ifdef _WIN32
2378 #include <windows.h>
add_neighbor_file_name(const CHAR * neighbor_file_name,BOOL unique)2379 BOOL LASreadOpener::add_neighbor_file_name(const CHAR* neighbor_file_name, BOOL unique)
2380 {
2381   BOOL r = FALSE;
2382   HANDLE h;
2383   WIN32_FIND_DATA info;
2384   h = FindFirstFile(neighbor_file_name, &info);
2385   if (h != INVALID_HANDLE_VALUE)
2386   {
2387     // find the path
2388     I32 len = (I32)strlen(neighbor_file_name);
2389     while (len && (neighbor_file_name[len] != '\\') && (neighbor_file_name[len] != '/') && (neighbor_file_name[len] != ':')) len--;
2390     if (len)
2391     {
2392       len++;
2393       CHAR full_neighbor_file_name[512];
2394       strncpy(full_neighbor_file_name, neighbor_file_name, len);
2395 	    do
2396 	    {
2397         sprintf(&full_neighbor_file_name[len], "%s", info.cFileName);
2398         if (add_neighbor_file_name_single(full_neighbor_file_name, unique)) r = TRUE;
2399   	  } while (FindNextFile(h, &info));
2400     }
2401     else
2402     {
2403       do
2404       {
2405         if (add_neighbor_file_name_single(info.cFileName, unique)) r = TRUE;
2406   	  } while (FindNextFile(h, &info));
2407     }
2408 	  FindClose(h);
2409   }
2410   return r;
2411 }
2412 #endif
2413 
2414 #ifdef _WIN32
add_neighbor_file_name_single(const CHAR * neighbor_file_name,BOOL unique)2415 BOOL LASreadOpener::add_neighbor_file_name_single(const CHAR* neighbor_file_name, BOOL unique)
2416 #else
2417 BOOL LASreadOpener::add_neighbor_file_name(const CHAR* neighbor_file_name, BOOL unique)
2418 #endif
2419 {
2420   if (unique)
2421   {
2422     U32 i;
2423     for (i = 0; i < neighbor_file_name_number; i++)
2424     {
2425       if (strcmp(neighbor_file_names[i], neighbor_file_name) == 0)
2426       {
2427         return FALSE;
2428       }
2429     }
2430   }
2431   if (neighbor_file_name_number == neighbor_file_name_allocated)
2432   {
2433     if (neighbor_file_names)
2434     {
2435       neighbor_file_name_allocated *= 2;
2436       neighbor_file_names = (CHAR**)realloc(neighbor_file_names, sizeof(CHAR*)*neighbor_file_name_allocated);
2437     }
2438     else
2439     {
2440       neighbor_file_name_allocated = 16;
2441       neighbor_file_names = (CHAR**)malloc(sizeof(CHAR*)*neighbor_file_name_allocated);
2442     }
2443     if (neighbor_file_names == 0)
2444     {
2445       fprintf(stderr, "ERROR: alloc for neighbor_file_names pointer array failed at %d\n", neighbor_file_name_allocated);
2446     }
2447   }
2448   neighbor_file_names[neighbor_file_name_number] = LASCopyString(neighbor_file_name);
2449   neighbor_file_name_number++;
2450   return TRUE;
2451 }
2452 
set_point_type(U8 point_type)2453 BOOL LASreadOpener::set_point_type(U8 point_type)
2454 {
2455   if (point_type > 10)
2456   {
2457     return FALSE;
2458   }
2459   this->point_type = point_type;
2460   return TRUE;
2461 }
2462 
set_parse_string(const CHAR * parse_string)2463 void LASreadOpener::set_parse_string(const CHAR* parse_string)
2464 {
2465   if (this->parse_string) free(this->parse_string);
2466   if (parse_string)
2467   {
2468     this->parse_string = LASCopyString(parse_string);
2469   }
2470   else
2471   {
2472     this->parse_string = 0;
2473   }
2474 }
2475 
get_parse_string() const2476 const CHAR* LASreadOpener::get_parse_string() const
2477 {
2478   return parse_string;
2479 }
2480 
set_scale_factor(const F64 * scale_factor)2481 void LASreadOpener::set_scale_factor(const F64* scale_factor)
2482 {
2483   if (scale_factor)
2484   {
2485     if (this->scale_factor == 0) this->scale_factor = new F64[3];
2486     this->scale_factor[0] = scale_factor[0];
2487     this->scale_factor[1] = scale_factor[1];
2488     this->scale_factor[2] = scale_factor[2];
2489   }
2490   else if (this->scale_factor)
2491   {
2492     delete [] this->scale_factor;
2493     this->scale_factor = 0;
2494   }
2495 }
2496 
set_offset(const F64 * offset)2497 void LASreadOpener::set_offset(const F64* offset)
2498 {
2499   if (offset)
2500   {
2501     if (this->offset == 0) this->offset = new F64[3];
2502     this->offset[0] = offset[0];
2503     this->offset[1] = offset[1];
2504     this->offset[2] = offset[2];
2505   }
2506   else if (this->offset)
2507   {
2508     delete [] this->offset;
2509     this->offset = 0;
2510   }
2511 }
2512 
set_translate_intensity(F32 translate_intensity)2513 void LASreadOpener::set_translate_intensity(F32 translate_intensity)
2514 {
2515   this->translate_intensity = translate_intensity;
2516 }
2517 
set_scale_intensity(F32 scale_intensity)2518 void LASreadOpener::set_scale_intensity(F32 scale_intensity)
2519 {
2520   this->scale_intensity = scale_intensity;
2521 }
2522 
set_translate_scan_angle(F32 translate_scan_angle)2523 void LASreadOpener::set_translate_scan_angle(F32 translate_scan_angle)
2524 {
2525   this->translate_scan_angle = translate_scan_angle;
2526 }
2527 
set_scale_scan_angle(F32 scale_scan_angle)2528 void LASreadOpener::set_scale_scan_angle(F32 scale_scan_angle)
2529 {
2530   this->scale_scan_angle = scale_scan_angle;
2531 }
2532 
add_attribute(I32 data_type,const CHAR * name,const CHAR * description,F64 scale,F64 offset,F64 pre_scale,F64 pre_offset,F64 no_data)2533 void LASreadOpener::add_attribute(I32 data_type, const CHAR* name, const CHAR* description, F64 scale, F64 offset, F64 pre_scale, F64 pre_offset, F64 no_data)
2534 {
2535   attribute_data_types[number_attributes] = data_type;
2536   attribute_names[number_attributes] = (name ? LASCopyString(name) : 0);
2537   attribute_descriptions[number_attributes] = (description ? LASCopyString(description) : 0);
2538   attribute_scales[number_attributes] = scale;
2539   attribute_offsets[number_attributes] = offset;
2540   attribute_pre_scales[number_attributes] = pre_scale;
2541   attribute_pre_offsets[number_attributes] = pre_offset;
2542   attribute_no_datas[number_attributes] = no_data;
2543   number_attributes++;
2544 }
2545 
set_skip_lines(I32 skip_lines)2546 void LASreadOpener::set_skip_lines(I32 skip_lines)
2547 {
2548   this->skip_lines = skip_lines;
2549 }
2550 
set_populate_header(BOOL populate_header)2551 void LASreadOpener::set_populate_header(BOOL populate_header)
2552 {
2553   this->populate_header = populate_header;
2554 }
2555 
set_keep_lastiling(BOOL keep_lastiling)2556 void LASreadOpener::set_keep_lastiling(BOOL keep_lastiling)
2557 {
2558   this->keep_lastiling = keep_lastiling;
2559 }
2560 
set_pipe_on(BOOL pipe_on)2561 void LASreadOpener::set_pipe_on(BOOL pipe_on)
2562 {
2563   this->pipe_on = pipe_on;
2564 }
2565 
set_decompress_selective(U32 decompress_selective)2566 void LASreadOpener::set_decompress_selective(U32 decompress_selective)
2567 {
2568   this->decompress_selective = decompress_selective;
2569   if (filter)
2570   {
2571     this->decompress_selective |= filter->get_decompress_selective();
2572   }
2573   if (transform)
2574   {
2575     this->decompress_selective |= transform->get_decompress_selective();
2576   }
2577 }
2578 
set_inside_tile(const F32 ll_x,const F32 ll_y,const F32 size)2579 void LASreadOpener::set_inside_tile(const F32 ll_x, const F32 ll_y, const F32 size)
2580 {
2581   if (inside_tile == 0) inside_tile = new F32[3];
2582   inside_tile[0] = ll_x;
2583   inside_tile[1] = ll_y;
2584   inside_tile[2] = size;
2585 }
2586 
set_inside_circle(const F64 center_x,const F64 center_y,const F64 radius)2587 void LASreadOpener::set_inside_circle(const F64 center_x, const F64 center_y, const F64 radius)
2588 {
2589   if (inside_circle == 0) inside_circle = new F64[3];
2590   inside_circle[0] = center_x;
2591   inside_circle[1] = center_y;
2592   inside_circle[2] = radius;
2593 }
2594 
set_inside_rectangle(const F64 min_x,const F64 min_y,const F64 max_x,const F64 max_y)2595 void LASreadOpener::set_inside_rectangle(const F64 min_x, const F64 min_y, const F64 max_x, const F64 max_y)
2596 {
2597   if (inside_rectangle == 0) inside_rectangle = new F64[4];
2598   inside_rectangle[0] = min_x;
2599   inside_rectangle[1] = min_y;
2600   inside_rectangle[2] = max_x;
2601   inside_rectangle[3] = max_y;
2602 }
2603 
active() const2604 BOOL LASreadOpener::active() const
2605 {
2606   return ((file_name_current < file_name_number) || use_stdin);
2607 }
2608 
LASreadOpener()2609 LASreadOpener::LASreadOpener()
2610 {
2611   io_ibuffer_size = LAS_TOOLS_IO_IBUFFER_SIZE;
2612   file_names = 0;
2613   file_name = 0;
2614   neighbor_file_names = 0;
2615   merged = FALSE;
2616   stored = FALSE;
2617   use_stdin = FALSE;
2618   comma_not_point = FALSE;
2619   scale_factor = 0;
2620   offset = 0;
2621   buffer_size = 0.0f;
2622   auto_reoffset = FALSE;
2623   files_are_flightlines = 0;
2624   files_are_flightlines_index = -1;
2625   apply_file_source_ID = FALSE;
2626   itxt = FALSE;
2627   ipts = FALSE;
2628   iptx = FALSE;
2629   translate_intensity = 0.0f;
2630   scale_intensity = 1.0f;
2631   translate_scan_angle = 0.0f;
2632   scale_scan_angle = 1.0f;
2633   number_attributes = 0;
2634   for (I32 i = 0; i < 32; i++)
2635   {
2636     attribute_data_types[i] = 0;
2637     attribute_names[i] = 0;
2638     attribute_descriptions[i] = 0;
2639     attribute_scales[i] = 1.0;
2640     attribute_offsets[i] = 0.0;
2641     attribute_pre_scales[i] = 1.0;
2642     attribute_pre_offsets[i] = 0.0;
2643     attribute_no_datas[i] = F64_MAX;
2644   }
2645   point_type = 0;
2646   parse_string = 0;
2647   skip_lines = 0;
2648   populate_header = FALSE;
2649   keep_lastiling = FALSE;
2650   pipe_on = FALSE;
2651   unique = FALSE;
2652   file_name_number = 0;
2653   file_name_allocated = 0;
2654   file_name_current = 0;
2655   neighbor_file_name_number = 0;
2656   neighbor_file_name_allocated = 0;
2657   decompress_selective = LASZIP_DECOMPRESS_SELECTIVE_ALL;
2658   inside_tile = 0;
2659   inside_circle = 0;
2660   inside_rectangle = 0;
2661   filter = 0;
2662   transform = 0;
2663   temp_file_base = 0;
2664 }
2665 
~LASreadOpener()2666 LASreadOpener::~LASreadOpener()
2667 {
2668   if (file_names)
2669   {
2670     U32 i;
2671     for (i = 0; i < file_name_number; i++) free(file_names[i]);
2672     free(file_names);
2673   }
2674   if (neighbor_file_names)
2675   {
2676     U32 i;
2677     for (i = 0; i < neighbor_file_name_number; i++) free(neighbor_file_names[i]);
2678     free(neighbor_file_names);
2679   }
2680   if (parse_string) free(parse_string);
2681   if (scale_factor) delete [] scale_factor;
2682   if (offset) delete [] offset;
2683   if (inside_tile) delete [] inside_tile;
2684   if (inside_circle) delete [] inside_circle;
2685   if (inside_rectangle) delete [] inside_rectangle;
2686   if (filter) delete filter;
2687   if (transform) delete transform;
2688   if (temp_file_base) free(temp_file_base);
2689 }
2690