GameApi 28
Library used by GameApi Builder tool
Loading...
Searching...
No Matches
dynamic_integer_points_kd_tree_decoder.h
Go to the documentation of this file.
1// Copyright 2016 The Draco Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// See dynamic_integer_points_kd_tree_encoder.h for documentation.
16
17#ifndef DRACO_COMPRESSION_POINT_CLOUD_ALGORITHMS_DYNAMIC_INTEGER_POINTS_KD_TREE_DECODER_H_
18#define DRACO_COMPRESSION_POINT_CLOUD_ALGORITHMS_DYNAMIC_INTEGER_POINTS_KD_TREE_DECODER_H_
19
20#include <array>
21#include <limits>
22#include <memory>
23#include <stack>
24#include <vector>
25
34
35namespace draco {
36
37template <int compression_level_t>
41
42template <>
50
51template <>
56
57template <>
62
63template <>
68
69// Decodes a point cloud encoded by DynamicIntegerPointsKdTreeEncoder.
70template <int compression_level_t>
72 static_assert(compression_level_t >= 0, "Compression level must in [0..6].");
73 static_assert(compression_level_t <= 6, "Compression level must in [0..6].");
75 compression_level_t>
76 Policy;
77
78 typedef typename Policy::NumbersDecoder NumbersDecoder;
79 typedef typename Policy::AxisDecoder AxisDecoder;
80 typedef typename Policy::HalfDecoder HalfDecoder;
81 typedef typename Policy::RemainingBitsDecoder RemainingBitsDecoder;
82 typedef std::vector<uint32_t> VectorUint32;
83
84 public:
86 : bit_length_(0),
87 num_points_(0),
88 num_decoded_points_(0),
89 dimension_(dimension),
90 p_(dimension, 0),
91 axes_(dimension, 0),
92 // Init the stack with the maximum depth of the tree.
93 // +1 for a second leaf.
94 base_stack_(32 * dimension + 1, VectorUint32(dimension, 0)),
95 levels_stack_(32 * dimension + 1, VectorUint32(dimension, 0)) {}
96
97 // Decodes an integer point cloud from |buffer|. Optional |oit_max_points| can
98 // be used to tell the decoder the maximum number of points accepted by the
99 // iterator.
100 template <class OutputIteratorT>
101 bool DecodePoints(DecoderBuffer *buffer, OutputIteratorT &oit);
102
103 template <class OutputIteratorT>
104 bool DecodePoints(DecoderBuffer *buffer, OutputIteratorT &oit,
105 uint32_t oit_max_points);
106
107#ifndef DRACO_OLD_GCC
108 template <class OutputIteratorT>
109 bool DecodePoints(DecoderBuffer *buffer, OutputIteratorT &&oit);
110 template <class OutputIteratorT>
111 bool DecodePoints(DecoderBuffer *buffer, OutputIteratorT &&oit,
112 uint32_t oit_max_points);
113#endif // DRACO_OLD_GCC
114
115 const uint32_t dimension() const { return dimension_; }
116
117 // Returns the number of decoded points. Must be called after DecodePoints().
118 uint32_t num_decoded_points() const { return num_decoded_points_; }
119
120 private:
121 uint32_t GetAxis(uint32_t num_remaining_points, const VectorUint32 &levels,
122 uint32_t last_axis);
123
124 template <class OutputIteratorT>
125 bool DecodeInternal(uint32_t num_points, OutputIteratorT &oit);
126
127 void DecodeNumber(int nbits, uint32_t *value) {
128 numbers_decoder_.DecodeLeastSignificantBits32(nbits, value);
129 }
130
131 struct DecodingStatus {
132 DecodingStatus(uint32_t num_remaining_points_, uint32_t last_axis_,
133 uint32_t stack_pos_)
134 : num_remaining_points(num_remaining_points_),
135 last_axis(last_axis_),
136 stack_pos(stack_pos_) {}
137
138 uint32_t num_remaining_points;
139 uint32_t last_axis;
140 uint32_t stack_pos; // used to get base and levels
141 };
142
143 uint32_t bit_length_;
144 uint32_t num_points_;
145 uint32_t num_decoded_points_;
146 uint32_t dimension_;
147 NumbersDecoder numbers_decoder_;
148 RemainingBitsDecoder remaining_bits_decoder_;
149 AxisDecoder axis_decoder_;
150 HalfDecoder half_decoder_;
151 VectorUint32 p_;
152 VectorUint32 axes_;
153 std::vector<VectorUint32> base_stack_;
154 std::vector<VectorUint32> levels_stack_;
155};
156
157// Decodes a point cloud from |buffer|.
158#ifndef DRACO_OLD_GCC
159template <int compression_level_t>
160template <class OutputIteratorT>
162 DecoderBuffer *buffer, OutputIteratorT &&oit) {
163 return DecodePoints(buffer, oit, std::numeric_limits<uint32_t>::max());
164}
165
166template <int compression_level_t>
167template <class OutputIteratorT>
169 DecoderBuffer *buffer, OutputIteratorT &&oit, uint32_t oit_max_points) {
170 OutputIteratorT local = std::forward<OutputIteratorT>(oit);
171 return DecodePoints(buffer, local, oit_max_points);
172}
173#endif // DRACO_OLD_GCC
174
175template <int compression_level_t>
176template <class OutputIteratorT>
178 DecoderBuffer *buffer, OutputIteratorT &oit) {
179 return DecodePoints(buffer, oit, std::numeric_limits<uint32_t>::max());
180}
181
182template <int compression_level_t>
183template <class OutputIteratorT>
185 DecoderBuffer *buffer, OutputIteratorT &oit, uint32_t oit_max_points) {
186 if (!buffer->Decode(&bit_length_)) {
187 return false;
188 }
189 if (bit_length_ > 32) {
190 return false;
191 }
192 if (!buffer->Decode(&num_points_)) {
193 return false;
194 }
195 if (num_points_ == 0) {
196 return true;
197 }
198 if (num_points_ > oit_max_points) {
199 return false;
200 }
201 num_decoded_points_ = 0;
202
203 if (!numbers_decoder_.StartDecoding(buffer)) {
204 return false;
205 }
206 if (!remaining_bits_decoder_.StartDecoding(buffer)) {
207 return false;
208 }
209 if (!axis_decoder_.StartDecoding(buffer)) {
210 return false;
211 }
212 if (!half_decoder_.StartDecoding(buffer)) {
213 return false;
214 }
215
216 if (!DecodeInternal(num_points_, oit)) {
217 return false;
218 }
219
220 numbers_decoder_.EndDecoding();
221 remaining_bits_decoder_.EndDecoding();
222 axis_decoder_.EndDecoding();
223 half_decoder_.EndDecoding();
224
225 return true;
226}
227
228template <int compression_level_t>
229uint32_t DynamicIntegerPointsKdTreeDecoder<compression_level_t>::GetAxis(
230 uint32_t num_remaining_points, const VectorUint32 &levels,
231 uint32_t last_axis) {
232 if (!Policy::select_axis) {
233 return DRACO_INCREMENT_MOD(last_axis, dimension_);
234 }
235
236 uint32_t best_axis = 0;
237 if (num_remaining_points < 64) {
238 for (uint32_t axis = 1; axis < dimension_; ++axis) {
239 if (levels[best_axis] > levels[axis]) {
240 best_axis = axis;
241 }
242 }
243 } else {
244 axis_decoder_.DecodeLeastSignificantBits32(4, &best_axis);
245 }
246
247 return best_axis;
248}
249
250template <int compression_level_t>
251template <class OutputIteratorT>
252bool DynamicIntegerPointsKdTreeDecoder<compression_level_t>::DecodeInternal(
253 uint32_t num_points, OutputIteratorT &oit) {
254 typedef DecodingStatus Status;
255 base_stack_[0] = VectorUint32(dimension_, 0);
256 levels_stack_[0] = VectorUint32(dimension_, 0);
257 DecodingStatus init_status(num_points, 0, 0);
258 std::stack<Status> status_stack;
259 status_stack.push(init_status);
260
261 // TODO(b/199760123): Use preallocated vector instead of stack.
262 while (!status_stack.empty()) {
263 const DecodingStatus status = status_stack.top();
264 status_stack.pop();
265
266 const uint32_t num_remaining_points = status.num_remaining_points;
267 const uint32_t last_axis = status.last_axis;
268 const uint32_t stack_pos = status.stack_pos;
269 const VectorUint32 &old_base = base_stack_[stack_pos];
270 const VectorUint32 &levels = levels_stack_[stack_pos];
271
272 if (num_remaining_points > num_points) {
273 return false;
274 }
275
276 const uint32_t axis = GetAxis(num_remaining_points, levels, last_axis);
277 if (axis >= dimension_) {
278 return false;
279 }
280
281 const uint32_t level = levels[axis];
282
283 // All axes have been fully subdivided, just output points.
284 if ((bit_length_ - level) == 0) {
285 for (uint32_t i = 0; i < num_remaining_points; i++) {
286 *oit = old_base;
287 ++oit;
288 ++num_decoded_points_;
289 }
290 continue;
291 }
292
293 DRACO_DCHECK_EQ(true, num_remaining_points != 0);
294
295 // Fast decoding of remaining bits if number of points is 1 or 2.
296 if (num_remaining_points <= 2) {
297 // TODO(b/199760123): |axes_| not necessary, remove would change
298 // bitstream!
299 axes_[0] = axis;
300 for (uint32_t i = 1; i < dimension_; i++) {
301 axes_[i] = DRACO_INCREMENT_MOD(axes_[i - 1], dimension_);
302 }
303 for (uint32_t i = 0; i < num_remaining_points; ++i) {
304 for (uint32_t j = 0; j < dimension_; j++) {
305 p_[axes_[j]] = 0;
306 const uint32_t num_remaining_bits = bit_length_ - levels[axes_[j]];
307 if (num_remaining_bits) {
308 if (!remaining_bits_decoder_.DecodeLeastSignificantBits32(
309 num_remaining_bits, &p_[axes_[j]])) {
310 return false;
311 }
312 }
313 p_[axes_[j]] = old_base[axes_[j]] | p_[axes_[j]];
314 }
315 *oit = p_;
316 ++oit;
317 ++num_decoded_points_;
318 }
319 continue;
320 }
321
322 if (num_decoded_points_ > num_points_) {
323 return false;
324 }
325
326 const int num_remaining_bits = bit_length_ - level;
327 const uint32_t modifier = 1 << (num_remaining_bits - 1);
328 base_stack_[stack_pos + 1] = old_base; // copy
329 base_stack_[stack_pos + 1][axis] += modifier; // new base
330
331 const int incoming_bits = MostSignificantBit(num_remaining_points);
332
333 uint32_t number = 0;
334 DecodeNumber(incoming_bits, &number);
335
336 uint32_t first_half = num_remaining_points / 2;
337 if (first_half < number) {
338 // Invalid |number|.
339 return false;
340 }
341 first_half -= number;
342 uint32_t second_half = num_remaining_points - first_half;
343
344 if (first_half != second_half) {
345 if (!half_decoder_.DecodeNextBit()) {
346 std::swap(first_half, second_half);
347 }
348 }
349
350 levels_stack_[stack_pos][axis] += 1;
351 levels_stack_[stack_pos + 1] = levels_stack_[stack_pos]; // copy
352 if (first_half) {
353 status_stack.push(DecodingStatus(first_half, axis, stack_pos));
354 }
355 if (second_half) {
356 status_stack.push(DecodingStatus(second_half, axis, stack_pos + 1));
357 }
358 }
359 return true;
360}
361
362extern template class DynamicIntegerPointsKdTreeDecoder<0>;
363extern template class DynamicIntegerPointsKdTreeDecoder<2>;
364extern template class DynamicIntegerPointsKdTreeDecoder<4>;
365extern template class DynamicIntegerPointsKdTreeDecoder<6>;
366
367} // namespace draco
368
369#endif // DRACO_COMPRESSION_POINT_CLOUD_ALGORITHMS_DYNAMIC_INTEGER_POINTS_KD_TREE_DECODER_H_
Definition decoder_buffer.h:30
bool Decode(T *out_val)
Definition decoder_buffer.h:68
Definition direct_bit_decoder.h:25
Definition dynamic_integer_points_kd_tree_decoder.h:71
bool DecodePoints(DecoderBuffer *buffer, OutputIteratorT &oit)
Definition dynamic_integer_points_kd_tree_decoder.h:177
DynamicIntegerPointsKdTreeDecoder(uint32_t dimension)
Definition dynamic_integer_points_kd_tree_decoder.h:85
const uint32_t dimension() const
Definition dynamic_integer_points_kd_tree_decoder.h:115
uint32_t num_decoded_points() const
Definition dynamic_integer_points_kd_tree_decoder.h:118
Definition folded_integer_bit_decoder.h:27
Definition rans_bit_decoder.h:28
Definition status.h:25
#define DRACO_DCHECK_EQ(a, b)
Definition macros.h:81
#define DRACO_INCREMENT_MOD(I, M)
Definition math_utils.h:24
Definition attribute_octahedron_transform.cc:21
int MostSignificantBit(uint32_t n)
Definition bit_utils.h:58
static constexpr bool select_axis
Definition dynamic_integer_points_kd_tree_decoder.h:48
DirectBitDecoder HalfDecoder
Definition dynamic_integer_points_kd_tree_decoder.h:46
DirectBitDecoder RemainingBitsDecoder
Definition dynamic_integer_points_kd_tree_decoder.h:47
DirectBitDecoder NumbersDecoder
Definition dynamic_integer_points_kd_tree_decoder.h:44
DirectBitDecoder AxisDecoder
Definition dynamic_integer_points_kd_tree_decoder.h:45
RAnsBitDecoder NumbersDecoder
Definition dynamic_integer_points_kd_tree_decoder.h:54
FoldedBit32Decoder< RAnsBitDecoder > NumbersDecoder
Definition dynamic_integer_points_kd_tree_decoder.h:60
static constexpr bool select_axis
Definition dynamic_integer_points_kd_tree_decoder.h:66
Definition dynamic_integer_points_kd_tree_decoder.h:40