Branch data Line data Source code
1 : : /*
2 : : ===============================================================================
3 : :
4 : : FILE: util.hpp
5 : :
6 : : CONTENTS:
7 : : Utility classes
8 : :
9 : : PROGRAMMERS:
10 : :
11 : : martin.isenburg@rapidlasso.com - http://rapidlasso.com
12 : : uday.karan@gmail.com - Hobu, Inc.
13 : :
14 : : COPYRIGHT:
15 : :
16 : : (c) 2007-2014, martin isenburg, rapidlasso - tools to catch reality
17 : : (c) 2014, Uday Verma, Hobu, Inc.
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 : : ===============================================================================
29 : : */
30 : :
31 : : #ifndef __util_hpp__
32 : : #define __util_hpp__
33 : :
34 : : #include <array>
35 : : #include <cstdint>
36 : : #include <cstdlib>
37 : :
38 : : namespace laszip {
39 : : namespace utils {
40 : : #define ALIGN 64
41 : :
42 : 0 : static inline void *aligned_malloc(int size) {
43 : 0 : void *mem = malloc(size+ALIGN+sizeof(void*));
44 : 0 : void **ptr = (void**)(( ((uintptr_t)mem)+ALIGN+sizeof(void*) ) & ~(uintptr_t)(ALIGN-1) );
45 : 0 : ptr[-1] = mem;
46 : 0 : return ptr;
47 : : }
48 : :
49 : 0 : static inline void aligned_free(void *ptr) {
50 : 0 : free(((void**)ptr)[-1]);
51 : 0 : }
52 : :
53 : : template<
54 : : typename T
55 : : >
56 : : class streaming_median {
57 : : public:
58 : : std::array<T, 5> values;
59 : : BOOL high;
60 : :
61 : 0 : void init() {
62 : 0 : values.fill(T(0));
63 : 0 : high = true;
64 : 0 : }
65 : :
66 : 0 : inline void add(const T& v) {
67 : 0 : if (high) {
68 : 0 : if (v < values[2]) {
69 : 0 : values[4] = values[3];
70 : 0 : values[3] = values[2];
71 : 0 : if (v < values[0]) {
72 : 0 : values[2] = values[1];
73 : 0 : values[1] = values[0];
74 : 0 : values[0] = v;
75 : 0 : }
76 : 0 : else if (v < values[1]) {
77 : 0 : values[2] = values[1];
78 : 0 : values[1] = v;
79 : 0 : }
80 : : else {
81 : 0 : values[2] = v;
82 : : }
83 : 0 : }
84 : : else {
85 : 0 : if (v < values[3]) {
86 : 0 : values[4] = values[3];
87 : 0 : values[3] = v;
88 : 0 : }
89 : : else {
90 : 0 : values[4] = v;
91 : : }
92 : 0 : high = false;
93 : : }
94 : 0 : }
95 : : else {
96 : 0 : if (values[2] < v) {
97 : 0 : values[0] = values[1];
98 : 0 : values[1] = values[2];
99 : 0 : if (values[4] < v) {
100 : 0 : values[2] = values[3];
101 : 0 : values[3] = values[4];
102 : 0 : values[4] = v;
103 : 0 : }
104 : 0 : else if (values[3] < v) {
105 : 0 : values[2] = values[3];
106 : 0 : values[3] = v;
107 : 0 : }
108 : : else {
109 : 0 : values[2] = v;
110 : : }
111 : 0 : }
112 : : else {
113 : 0 : if (values[1] < v) {
114 : 0 : values[0] = values[1];
115 : 0 : values[1] = v;
116 : 0 : }
117 : : else {
118 : 0 : values[0] = v;
119 : : }
120 : 0 : high = true;
121 : : }
122 : : }
123 : 0 : }
124 : :
125 : 0 : inline T get() const {
126 : 0 : return values[2];
127 : : }
128 : :
129 : 0 : streaming_median() {
130 : 0 : init();
131 : 0 : }
132 : : };
133 : :
134 : : // for LAS files with the return (r) and the number (n) of
135 : : // returns field correctly populated the mapping should really
136 : : // be only the following.
137 : : // { 15, 15, 15, 15, 15, 15, 15, 15 },
138 : : // { 15, 0, 15, 15, 15, 15, 15, 15 },
139 : : // { 15, 1, 2, 15, 15, 15, 15, 15 },
140 : : // { 15, 3, 4, 5, 15, 15, 15, 15 },
141 : : // { 15, 6, 7, 8, 9, 15, 15, 15 },
142 : : // { 15, 10, 11, 12, 13, 14, 15, 15 },
143 : : // { 15, 15, 15, 15, 15, 15, 15, 15 },
144 : : // { 15, 15, 15, 15, 15, 15, 15, 15 }
145 : : // however, some files start the numbering of r and n with 0,
146 : : // only have return counts r, or only have number of return
147 : : // counts n, or mix up the position of r and n. we therefore
148 : : // "complete" the table to also map those "undesired" r & n
149 : : // combinations to different contexts
150 : : const unsigned char number_return_map[8][8] =
151 : : {
152 : : { 15, 14, 13, 12, 11, 10, 9, 8 },
153 : : { 14, 0, 1, 3, 6, 10, 10, 9 },
154 : : { 13, 1, 2, 4, 7, 11, 11, 10 },
155 : : { 12, 3, 4, 5, 8, 12, 12, 11 },
156 : : { 11, 6, 7, 8, 9, 13, 13, 12 },
157 : : { 10, 10, 11, 12, 13, 14, 14, 13 },
158 : : { 9, 10, 11, 12, 13, 14, 15, 14 },
159 : : { 8, 9, 10, 11, 12, 13, 14, 15 }
160 : : };
161 : :
162 : : // for LAS files with the return (r) and the number (n) of
163 : : // returns field correctly populated the mapping should really
164 : : // be only the following.
165 : : // { 0, 7, 7, 7, 7, 7, 7, 7 },
166 : : // { 7, 0, 7, 7, 7, 7, 7, 7 },
167 : : // { 7, 1, 0, 7, 7, 7, 7, 7 },
168 : : // { 7, 2, 1, 0, 7, 7, 7, 7 },
169 : : // { 7, 3, 2, 1, 0, 7, 7, 7 },
170 : : // { 7, 4, 3, 2, 1, 0, 7, 7 },
171 : : // { 7, 5, 4, 3, 2, 1, 0, 7 },
172 : : // { 7, 6, 5, 4, 3, 2, 1, 0 }
173 : : // however, some files start the numbering of r and n with 0,
174 : : // only have return counts r, or only have number of return
175 : : // counts n, or mix up the position of r and n. we therefore
176 : : // "complete" the table to also map those "undesired" r & n
177 : : // combinations to different contexts
178 : : const unsigned char number_return_level[8][8] =
179 : : {
180 : : { 0, 1, 2, 3, 4, 5, 6, 7 },
181 : : { 1, 0, 1, 2, 3, 4, 5, 6 },
182 : : { 2, 1, 0, 1, 2, 3, 4, 5 },
183 : : { 3, 2, 1, 0, 1, 2, 3, 4 },
184 : : { 4, 3, 2, 1, 0, 1, 2, 3 },
185 : : { 5, 4, 3, 2, 1, 0, 1, 2 },
186 : : { 6, 5, 4, 3, 2, 1, 0, 1 },
187 : : { 7, 6, 5, 4, 3, 2, 1, 0 }
188 : : };
189 : : }
190 : : }
191 : :
192 : : #endif // __util_hpp__
|