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