Coverage Report

Created: 2024-09-08 06:47

/src/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.cc
Line
Count
Source (jump to first uncovered line)
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
#include "draco/compression/point_cloud/algorithms/float_points_tree_decoder.h"
16
17
#include <algorithm>
18
19
#include "draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h"
20
#include "draco/compression/point_cloud/algorithms/quantize_points_3.h"
21
#include "draco/core/math_utils.h"
22
#include "draco/core/quantization_utils.h"
23
24
namespace draco {
25
26
struct Converter {
27
  typedef std::vector<uint32_t> SourceType;
28
  typedef Point3ui TargetType;
29
164k
  Point3ui operator()(const std::vector<uint32_t> &v) {
30
164k
    return Point3ui(v[0], v[1], v[2]);
31
164k
  }
32
};
33
34
// Output iterator that is used to decode values directly into the data buffer
35
// of the modified PointAttribute.
36
template <class OutputIterator, class Converter>
37
class ConversionOutputIterator {
38
  typedef ConversionOutputIterator<OutputIterator, Converter> Self;
39
  typedef typename Converter::SourceType SourceType;
40
  typedef typename Converter::TargetType TargetType;
41
42
 public:
43
30
  explicit ConversionOutputIterator(OutputIterator oit) : oit_(oit) {}
44
45
164k
  const Self &operator++() {
46
164k
    ++oit_;
47
164k
    return *this;
48
164k
  }
49
  Self operator++(int) {
50
    Self copy = *this;
51
    ++oit_;
52
    return copy;
53
  }
54
164k
  Self &operator*() { return *this; }
55
164k
  const Self &operator=(const SourceType &source) {
56
164k
    *oit_ = Converter()(source);
57
164k
    return *this;
58
164k
  }
59
60
 private:
61
  OutputIterator oit_;
62
};
63
64
FloatPointsTreeDecoder::FloatPointsTreeDecoder()
65
34
    : num_points_(0), compression_level_(0), num_points_from_header_(0) {
66
34
  qinfo_.quantization_bits = 0;
67
34
  qinfo_.range = 0;
68
34
}
69
70
bool FloatPointsTreeDecoder::DecodePointCloudKdTreeInternal(
71
33
    DecoderBuffer *buffer, std::vector<Point3ui> *qpoints) {
72
33
  if (!buffer->Decode(&qinfo_.quantization_bits)) {
73
0
    return false;
74
0
  }
75
33
  if (qinfo_.quantization_bits > 31) {
76
0
    return false;
77
0
  }
78
33
  if (!buffer->Decode(&qinfo_.range)) {
79
0
    return false;
80
0
  }
81
33
  if (!buffer->Decode(&num_points_)) {
82
0
    return false;
83
0
  }
84
33
  if (num_points_from_header_ > 0 && num_points_ != num_points_from_header_) {
85
0
    return false;
86
0
  }
87
33
  if (!buffer->Decode(&compression_level_)) {
88
0
    return false;
89
0
  }
90
91
  // Only allow compression level in [0..6].
92
33
  if (6 < compression_level_) {
93
3
    DRACO_LOGE("FloatPointsTreeDecoder: compression level %i not supported.\n",
94
3
               compression_level_);
95
3
    return false;
96
3
  }
97
98
30
  std::back_insert_iterator<std::vector<Point3ui>> oit_qpoints =
99
30
      std::back_inserter(*qpoints);
100
30
  ConversionOutputIterator<std::back_insert_iterator<std::vector<Point3ui>>,
101
30
                           Converter>
102
30
      oit(oit_qpoints);
103
30
  if (num_points_ > 0) {
104
30
    qpoints->reserve(num_points_);
105
30
    switch (compression_level_) {
106
7
      case 0: {
107
7
        DynamicIntegerPointsKdTreeDecoder<0> qpoints_decoder(3);
108
7
        qpoints_decoder.DecodePoints(buffer, oit);
109
7
        break;
110
0
      }
111
3
      case 1: {
112
3
        DynamicIntegerPointsKdTreeDecoder<1> qpoints_decoder(3);
113
3
        qpoints_decoder.DecodePoints(buffer, oit);
114
3
        break;
115
0
      }
116
1
      case 2: {
117
1
        DynamicIntegerPointsKdTreeDecoder<2> qpoints_decoder(3);
118
1
        qpoints_decoder.DecodePoints(buffer, oit);
119
1
        break;
120
0
      }
121
15
      case 3: {
122
15
        DynamicIntegerPointsKdTreeDecoder<3> qpoints_decoder(3);
123
15
        qpoints_decoder.DecodePoints(buffer, oit);
124
15
        break;
125
0
      }
126
3
      case 4: {
127
3
        DynamicIntegerPointsKdTreeDecoder<4> qpoints_decoder(3);
128
3
        qpoints_decoder.DecodePoints(buffer, oit);
129
3
        break;
130
0
      }
131
0
      case 5: {
132
0
        DynamicIntegerPointsKdTreeDecoder<5> qpoints_decoder(3);
133
0
        qpoints_decoder.DecodePoints(buffer, oit);
134
0
        break;
135
0
      }
136
1
      case 6: {
137
1
        DynamicIntegerPointsKdTreeDecoder<6> qpoints_decoder(3);
138
1
        qpoints_decoder.DecodePoints(buffer, oit);
139
1
        break;
140
0
      }
141
0
      default:
142
0
        return false;
143
30
    }
144
30
  }
145
146
30
  if (qpoints->size() != num_points_) {
147
30
    return false;
148
30
  }
149
0
  return true;
150
30
}
151
152
}  // namespace draco