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