1 /*
2 ===============================================================================
3 
4   FILE:  laszip_common_v2.hpp
5 
6   CONTENTS:
7 
8     Common defines and functionalities for version 2 of LASitemReadCompressed
9     and LASitemwriteCompressed.
10 
11   PROGRAMMERS:
12 
13     martin.isenburg@rapidlasso.com  -  http://rapidlasso.com
14 
15   COPYRIGHT:
16 
17     (c) 2007-2012, martin isenburg, rapidlasso - fast tools to catch reality
18 
19     This is free software; you can redistribute and/or modify it under the
20     terms of the GNU Lesser General Licence as published by the Free Software
21     Foundation. See the COPYING file for more information.
22 
23     This software is distributed WITHOUT ANY WARRANTY and without even the
24     implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
25 
26   CHANGE HISTORY:
27 
28     16 March 2011 -- created after designing the "streaming median" algorithm
29 
30 ===============================================================================
31 */
32 #ifndef LASZIP_COMMON_V2_HPP
33 #define LASZIP_COMMON_V2_HPP
34 
35 class StreamingMedian5
36 {
37 public:
38   I32 values[5];
39   BOOL high;
init()40   void init()
41   {
42     values[0] = values[1] = values[2] = values[3] = values[4] = 0;
43     high = true;
44   }
add(I32 v)45   inline void add(I32 v)
46   {
47     if (high)
48     {
49       if (v < values[2])
50       {
51         values[4] = values[3];
52         values[3] = values[2];
53         if (v < values[0])
54         {
55           values[2] = values[1];
56           values[1] = values[0];
57           values[0] = v;
58         }
59         else if (v < values[1])
60         {
61           values[2] = values[1];
62           values[1] = v;
63         }
64         else
65         {
66           values[2] = v;
67         }
68       }
69       else
70       {
71         if (v < values[3])
72         {
73           values[4] = values[3];
74           values[3] = v;
75         }
76         else
77         {
78           values[4] = v;
79         }
80         high = false;
81       }
82     }
83     else
84     {
85       if (values[2] < v)
86       {
87         values[0] = values[1];
88         values[1] = values[2];
89         if (values[4] < v)
90         {
91           values[2] = values[3];
92           values[3] = values[4];
93           values[4] = v;
94         }
95         else if (values[3] < v)
96         {
97           values[2] = values[3];
98           values[3] = v;
99         }
100         else
101         {
102           values[2] = v;
103         }
104       }
105       else
106       {
107         if (values[1] < v)
108         {
109           values[0] = values[1];
110           values[1] = v;
111         }
112         else
113         {
114           values[0] = v;
115         }
116         high = true;
117       }
118     }
119   }
get() const120   I32 get() const
121   {
122     return values[2];
123   }
StreamingMedian5()124   StreamingMedian5()
125   {
126     init();
127   }
128 };
129 
130 // for LAS files with the return (r) and the number (n) of
131 // returns field correctly populated the mapping should really
132 // be only the following.
133 //  { 15, 15, 15, 15, 15, 15, 15, 15 },
134 //  { 15,  0, 15, 15, 15, 15, 15, 15 },
135 //  { 15,  1,  2, 15, 15, 15, 15, 15 },
136 //  { 15,  3,  4,  5, 15, 15, 15, 15 },
137 //  { 15,  6,  7,  8,  9, 15, 15, 15 },
138 //  { 15, 10, 11, 12, 13, 14, 15, 15 },
139 //  { 15, 15, 15, 15, 15, 15, 15, 15 },
140 //  { 15, 15, 15, 15, 15, 15, 15, 15 }
141 // however, some files start the numbering of r and n with 0,
142 // only have return counts r, or only have number of return
143 // counts n, or mix up the position of r and n. we therefore
144 // "complete" the table to also map those "undesired" r & n
145 // combinations to different contexts
146 const U8 number_return_map[8][8] =
147 {
148   { 15, 14, 13, 12, 11, 10,  9,  8 },
149   { 14,  0,  1,  3,  6, 10, 10,  9 },
150   { 13,  1,  2,  4,  7, 11, 11, 10 },
151   { 12,  3,  4,  5,  8, 12, 12, 11 },
152   { 11,  6,  7,  8,  9, 13, 13, 12 },
153   { 10, 10, 11, 12, 13, 14, 14, 13 },
154   {  9, 10, 11, 12, 13, 14, 15, 14 },
155   {  8,  9, 10, 11, 12, 13, 14, 15 }
156 };
157 
158 // for LAS files with the return (r) and the number (n) of
159 // returns field correctly populated the mapping should really
160 // be only the following.
161 //  {  0,  7,  7,  7,  7,  7,  7,  7 },
162 //  {  7,  0,  7,  7,  7,  7,  7,  7 },
163 //  {  7,  1,  0,  7,  7,  7,  7,  7 },
164 //  {  7,  2,  1,  0,  7,  7,  7,  7 },
165 //  {  7,  3,  2,  1,  0,  7,  7,  7 },
166 //  {  7,  4,  3,  2,  1,  0,  7,  7 },
167 //  {  7,  5,  4,  3,  2,  1,  0,  7 },
168 //  {  7,  6,  5,  4,  3,  2,  1,  0 }
169 // however, some files start the numbering of r and n with 0,
170 // only have return counts r, or only have number of return
171 // counts n, or mix up the position of r and n. we therefore
172 // "complete" the table to also map those "undesired" r & n
173 // combinations to different contexts
174 const U8 number_return_level[8][8] =
175 {
176   {  0,  1,  2,  3,  4,  5,  6,  7 },
177   {  1,  0,  1,  2,  3,  4,  5,  6 },
178   {  2,  1,  0,  1,  2,  3,  4,  5 },
179   {  3,  2,  1,  0,  1,  2,  3,  4 },
180   {  4,  3,  2,  1,  0,  1,  2,  3 },
181   {  5,  4,  3,  2,  1,  0,  1,  2 },
182   {  6,  5,  4,  3,  2,  1,  0,  1 },
183   {  7,  6,  5,  4,  3,  2,  1,  0 }
184 };
185 
186 #endif
187