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/attributes/sequential_attribute_decoders_controller.h"
16 #ifdef DRACO_NORMAL_ENCODING_SUPPORTED
17 #include "draco/compression/attributes/sequential_normal_attribute_decoder.h"
18 #endif
19 #include "draco/compression/attributes/sequential_quantization_attribute_decoder.h"
20 #include "draco/compression/config/compression_shared.h"
21
22 namespace draco {
23
SequentialAttributeDecodersController(std::unique_ptr<PointsSequencer> sequencer)24 SequentialAttributeDecodersController::SequentialAttributeDecodersController(
25 std::unique_ptr<PointsSequencer> sequencer)
26 : sequencer_(std::move(sequencer)) {}
27
DecodeAttributesDecoderData(DecoderBuffer * buffer)28 bool SequentialAttributeDecodersController::DecodeAttributesDecoderData(
29 DecoderBuffer *buffer) {
30 if (!AttributesDecoder::DecodeAttributesDecoderData(buffer)) {
31 return false;
32 }
33 // Decode unique ids of all sequential encoders and create them.
34 const int32_t num_attributes = GetNumAttributes();
35 sequential_decoders_.resize(num_attributes);
36 for (int i = 0; i < num_attributes; ++i) {
37 uint8_t decoder_type;
38 if (!buffer->Decode(&decoder_type)) {
39 return false;
40 }
41 // Create the decoder from the id.
42 sequential_decoders_[i] = CreateSequentialDecoder(decoder_type);
43 if (!sequential_decoders_[i]) {
44 return false;
45 }
46 if (!sequential_decoders_[i]->Init(GetDecoder(), GetAttributeId(i))) {
47 return false;
48 }
49 }
50 return true;
51 }
52
DecodeAttributes(DecoderBuffer * buffer)53 bool SequentialAttributeDecodersController::DecodeAttributes(
54 DecoderBuffer *buffer) {
55 if (!sequencer_ || !sequencer_->GenerateSequence(&point_ids_)) {
56 return false;
57 }
58 // Initialize point to attribute value mapping for all decoded attributes.
59 const int32_t num_attributes = GetNumAttributes();
60 for (int i = 0; i < num_attributes; ++i) {
61 PointAttribute *const pa =
62 GetDecoder()->point_cloud()->attribute(GetAttributeId(i));
63 if (!sequencer_->UpdatePointToAttributeIndexMapping(pa)) {
64 return false;
65 }
66 }
67 return AttributesDecoder::DecodeAttributes(buffer);
68 }
69
DecodePortableAttributes(DecoderBuffer * in_buffer)70 bool SequentialAttributeDecodersController::DecodePortableAttributes(
71 DecoderBuffer *in_buffer) {
72 const int32_t num_attributes = GetNumAttributes();
73 for (int i = 0; i < num_attributes; ++i) {
74 if (!sequential_decoders_[i]->DecodePortableAttribute(point_ids_,
75 in_buffer)) {
76 return false;
77 }
78 }
79 return true;
80 }
81
82 bool SequentialAttributeDecodersController::
DecodeDataNeededByPortableTransforms(DecoderBuffer * in_buffer)83 DecodeDataNeededByPortableTransforms(DecoderBuffer *in_buffer) {
84 const int32_t num_attributes = GetNumAttributes();
85 for (int i = 0; i < num_attributes; ++i) {
86 if (!sequential_decoders_[i]->DecodeDataNeededByPortableTransform(
87 point_ids_, in_buffer)) {
88 return false;
89 }
90 }
91 return true;
92 }
93
94 bool SequentialAttributeDecodersController::
TransformAttributesToOriginalFormat()95 TransformAttributesToOriginalFormat() {
96 const int32_t num_attributes = GetNumAttributes();
97 for (int i = 0; i < num_attributes; ++i) {
98 // Check whether the attribute transform should be skipped.
99 if (GetDecoder()->options()) {
100 const PointAttribute *const attribute =
101 sequential_decoders_[i]->attribute();
102 const PointAttribute *const portable_attribute =
103 sequential_decoders_[i]->GetPortableAttribute();
104 if (portable_attribute &&
105 GetDecoder()->options()->GetAttributeBool(
106 attribute->attribute_type(), "skip_attribute_transform", false)) {
107 // Attribute transform should not be performed. In this case, we replace
108 // the output geometry attribute with the portable attribute.
109 // TODO(ostava): We can potentially avoid this copy by introducing a new
110 // mechanism that would allow to use the final attributes as portable
111 // attributes for predictors that may need them.
112 sequential_decoders_[i]->attribute()->CopyFrom(*portable_attribute);
113 continue;
114 }
115 }
116 if (!sequential_decoders_[i]->TransformAttributeToOriginalFormat(
117 point_ids_)) {
118 return false;
119 }
120 }
121 return true;
122 }
123
124 std::unique_ptr<SequentialAttributeDecoder>
CreateSequentialDecoder(uint8_t decoder_type)125 SequentialAttributeDecodersController::CreateSequentialDecoder(
126 uint8_t decoder_type) {
127 switch (decoder_type) {
128 case SEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC:
129 return std::unique_ptr<SequentialAttributeDecoder>(
130 new SequentialAttributeDecoder());
131 case SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER:
132 return std::unique_ptr<SequentialAttributeDecoder>(
133 new SequentialIntegerAttributeDecoder());
134 case SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION:
135 return std::unique_ptr<SequentialAttributeDecoder>(
136 new SequentialQuantizationAttributeDecoder());
137 #ifdef DRACO_NORMAL_ENCODING_SUPPORTED
138 case SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS:
139 return std::unique_ptr<SequentialNormalAttributeDecoder>(
140 new SequentialNormalAttributeDecoder());
141 #endif
142 default:
143 break;
144 }
145 // Unknown or unsupported decoder type.
146 return nullptr;
147 }
148
149 } // namespace draco
150