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_quantization_attribute_decoder.h"
16
17 #include "draco/attributes/attribute_quantization_transform.h"
18 #include "draco/core/quantization_utils.h"
19
20 namespace draco {
21
SequentialQuantizationAttributeDecoder()22 SequentialQuantizationAttributeDecoder::SequentialQuantizationAttributeDecoder()
23 : quantization_bits_(-1), max_value_dif_(0.f) {}
24
Init(PointCloudDecoder * decoder,int attribute_id)25 bool SequentialQuantizationAttributeDecoder::Init(PointCloudDecoder *decoder,
26 int attribute_id) {
27 if (!SequentialIntegerAttributeDecoder::Init(decoder, attribute_id))
28 return false;
29 const PointAttribute *const attribute =
30 decoder->point_cloud()->attribute(attribute_id);
31 // Currently we can quantize only floating point arguments.
32 if (attribute->data_type() != DT_FLOAT32)
33 return false;
34 return true;
35 }
36
DecodeIntegerValues(const std::vector<PointIndex> & point_ids,DecoderBuffer * in_buffer)37 bool SequentialQuantizationAttributeDecoder::DecodeIntegerValues(
38 const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
39 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
40 if (decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0) &&
41 !DecodeQuantizedDataInfo())
42 return false;
43 #endif
44 return SequentialIntegerAttributeDecoder::DecodeIntegerValues(point_ids,
45 in_buffer);
46 }
47
48 bool SequentialQuantizationAttributeDecoder::
DecodeDataNeededByPortableTransform(const std::vector<PointIndex> & point_ids,DecoderBuffer * in_buffer)49 DecodeDataNeededByPortableTransform(
50 const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
51 if (decoder()->bitstream_version() >= DRACO_BITSTREAM_VERSION(2, 0)) {
52 // Decode quantization data here only for files with bitstream version 2.0+
53 if (!DecodeQuantizedDataInfo())
54 return false;
55 }
56
57 // Store the decoded transform data in portable attribute;
58 AttributeQuantizationTransform transform;
59 transform.SetParameters(quantization_bits_, min_value_.get(),
60 attribute()->num_components(), max_value_dif_);
61 return transform.TransferToAttribute(portable_attribute());
62 }
63
StoreValues(uint32_t num_values)64 bool SequentialQuantizationAttributeDecoder::StoreValues(uint32_t num_values) {
65 return DequantizeValues(num_values);
66 }
67
DecodeQuantizedDataInfo()68 bool SequentialQuantizationAttributeDecoder::DecodeQuantizedDataInfo() {
69 const int num_components = attribute()->num_components();
70 min_value_ = std::unique_ptr<float[]>(new float[num_components]);
71 if (!decoder()->buffer()->Decode(min_value_.get(),
72 sizeof(float) * num_components))
73 return false;
74 if (!decoder()->buffer()->Decode(&max_value_dif_))
75 return false;
76 uint8_t quantization_bits;
77 if (!decoder()->buffer()->Decode(&quantization_bits) ||
78 quantization_bits > 31)
79 return false;
80 quantization_bits_ = quantization_bits;
81 return true;
82 }
83
DequantizeValues(uint32_t num_values)84 bool SequentialQuantizationAttributeDecoder::DequantizeValues(
85 uint32_t num_values) {
86 // Convert all quantized values back to floats.
87 const int32_t max_quantized_value =
88 (1u << static_cast<uint32_t>(quantization_bits_)) - 1;
89 const int num_components = attribute()->num_components();
90 const int entry_size = sizeof(float) * num_components;
91 const std::unique_ptr<float[]> att_val(new float[num_components]);
92 int quant_val_id = 0;
93 int out_byte_pos = 0;
94 Dequantizer dequantizer;
95 if (!dequantizer.Init(max_value_dif_, max_quantized_value))
96 return false;
97 const int32_t *const portable_attribute_data = GetPortableAttributeData();
98 for (uint32_t i = 0; i < num_values; ++i) {
99 for (int c = 0; c < num_components; ++c) {
100 float value =
101 dequantizer.DequantizeFloat(portable_attribute_data[quant_val_id++]);
102 value = value + min_value_[c];
103 att_val[c] = value;
104 }
105 // Store the floating point value into the attribute buffer.
106 attribute()->buffer()->Write(out_byte_pos, att_val.get(), entry_size);
107 out_byte_pos += entry_size;
108 }
109 return true;
110 }
111
112 } // namespace draco
113