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/core/quantization_utils.h"
18 
19 namespace draco {
20 
21 SequentialQuantizationAttributeDecoder::
SequentialQuantizationAttributeDecoder()22     SequentialQuantizationAttributeDecoder() {}
23 
Init(PointCloudDecoder * decoder,int attribute_id)24 bool SequentialQuantizationAttributeDecoder::Init(PointCloudDecoder *decoder,
25                                                   int attribute_id) {
26   if (!SequentialIntegerAttributeDecoder::Init(decoder, attribute_id)) {
27     return false;
28   }
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   }
35   return true;
36 }
37 
DecodeIntegerValues(const std::vector<PointIndex> & point_ids,DecoderBuffer * in_buffer)38 bool SequentialQuantizationAttributeDecoder::DecodeIntegerValues(
39     const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
40 #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
41   if (decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0) &&
42       !DecodeQuantizedDataInfo()) {
43     return false;
44   }
45 #endif
46   return SequentialIntegerAttributeDecoder::DecodeIntegerValues(point_ids,
47                                                                 in_buffer);
48 }
49 
50 bool SequentialQuantizationAttributeDecoder::
DecodeDataNeededByPortableTransform(const std::vector<PointIndex> & point_ids,DecoderBuffer * in_buffer)51     DecodeDataNeededByPortableTransform(
52         const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
53   if (decoder()->bitstream_version() >= DRACO_BITSTREAM_VERSION(2, 0)) {
54     // Decode quantization data here only for files with bitstream version 2.0+
55     if (!DecodeQuantizedDataInfo()) {
56       return false;
57     }
58   }
59 
60   // Store the decoded transform data in portable attribute;
61   return quantization_transform_.TransferToAttribute(portable_attribute());
62 }
63 
StoreValues(uint32_t num_points)64 bool SequentialQuantizationAttributeDecoder::StoreValues(uint32_t num_points) {
65   return DequantizeValues(num_points);
66 }
67 
DecodeQuantizedDataInfo()68 bool SequentialQuantizationAttributeDecoder::DecodeQuantizedDataInfo() {
69   // Get attribute used as source for decoding.
70   auto att = GetPortableAttribute();
71   if (att == nullptr) {
72     // This should happen only in the backward compatibility mode. It will still
73     // work fine for this case because the only thing the quantization transform
74     // cares about is the number of components that is the same for both source
75     // and target attributes.
76     att = attribute();
77   }
78   return quantization_transform_.DecodeParameters(*att, decoder()->buffer());
79 }
80 
DequantizeValues(uint32_t num_values)81 bool SequentialQuantizationAttributeDecoder::DequantizeValues(
82     uint32_t num_values) {
83   // Convert all quantized values back to floats.
84   return quantization_transform_.InverseTransformAttribute(
85       *GetPortableAttribute(), attribute());
86 }
87 
88 }  // namespace draco
89