glTF: update Draco library to new version

To support decoding and enhanced encoding of Draco compressed glTF files.

Differential Revision: https://developer.blender.org/D9642
This commit is contained in:
Jim Eckerlein 2020-12-07 15:23:55 +01:00 committed by Brecht Van Lommel
parent fb82cfb539
commit 3012446f02
353 changed files with 2766 additions and 11208 deletions

View File

@ -19,20 +19,24 @@
# ***** END GPL LICENSE BLOCK *****
# Build Draco library.
add_subdirectory(dracoenc)
add_subdirectory(draco)
# Build blender-draco-exporter module.
# Build Draco-Blender bridging module.
set(SRC
src/draco-compressor.cpp
src/draco-compressor.h
src/common.cpp
src/common.h
src/decoder.cpp
src/decoder.h
src/encoder.cpp
src/encoder.h
)
set(INC
dracoenc/src
draco/src
)
set(LIB
dracoenc
draco
)
add_library(extern_draco SHARED "${SRC}")

View File

@ -2,103 +2,165 @@ remove_strict_flags()
set(SRC
src/draco/animation/keyframe_animation.cc
src/draco/animation/keyframe_animation.h
src/draco/animation/keyframe_animation_decoder.cc
src/draco/animation/keyframe_animation_decoder.h
src/draco/animation/keyframe_animation_encoder.cc
src/draco/animation/keyframe_animation_encoder.h
src/draco/animation/keyframe_animation.h
src/draco/attributes/attribute_octahedron_transform.cc
src/draco/attributes/attribute_octahedron_transform.h
src/draco/attributes/attribute_quantization_transform.cc
src/draco/attributes/attribute_quantization_transform.h
src/draco/attributes/attribute_transform.cc
src/draco/attributes/attribute_transform_data.h
src/draco/attributes/attribute_transform.h
src/draco/attributes/attribute_transform_data.h
src/draco/attributes/attribute_transform_type.h
src/draco/attributes/geometry_attribute.cc
src/draco/attributes/geometry_attribute.h
src/draco/attributes/geometry_indices.h
src/draco/attributes/point_attribute.cc
src/draco/attributes/point_attribute.h
src/draco/compression/attributes/attributes_decoder.cc
src/draco/compression/attributes/attributes_decoder.h
src/draco/compression/attributes/attributes_decoder_interface.h
src/draco/compression/attributes/attributes_encoder.cc
src/draco/compression/attributes/attributes_encoder.h
src/draco/compression/attributes/kd_tree_attributes_decoder.cc
src/draco/compression/attributes/kd_tree_attributes_decoder.h
src/draco/compression/attributes/kd_tree_attributes_encoder.cc
src/draco/compression/attributes/kd_tree_attributes_encoder.h
src/draco/compression/attributes/kd_tree_attributes_shared.h
src/draco/compression/attributes/linear_sequencer.h
src/draco/compression/attributes/mesh_attribute_indices_encoding_data.h
src/draco/compression/attributes/normal_compression_utils.h
src/draco/compression/attributes/point_d_vector.h
src/draco/compression/attributes/points_sequencer.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h
src/draco/compression/attributes/sequential_attribute_decoder.cc
src/draco/compression/attributes/sequential_attribute_decoder.h
src/draco/compression/attributes/sequential_attribute_decoders_controller.cc
src/draco/compression/attributes/sequential_attribute_decoders_controller.h
src/draco/compression/attributes/sequential_attribute_encoder.cc
src/draco/compression/attributes/sequential_attribute_encoder.h
src/draco/compression/attributes/sequential_attribute_encoders_controller.cc
src/draco/compression/attributes/sequential_attribute_encoders_controller.h
src/draco/compression/attributes/sequential_integer_attribute_decoder.cc
src/draco/compression/attributes/sequential_integer_attribute_decoder.h
src/draco/compression/attributes/sequential_integer_attribute_encoder.cc
src/draco/compression/attributes/sequential_integer_attribute_encoder.h
src/draco/compression/attributes/sequential_normal_attribute_decoder.cc
src/draco/compression/attributes/sequential_normal_attribute_decoder.h
src/draco/compression/attributes/sequential_normal_attribute_encoder.cc
src/draco/compression/attributes/sequential_normal_attribute_encoder.h
src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc
src/draco/compression/attributes/sequential_quantization_attribute_decoder.h
src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc
src/draco/compression/attributes/sequential_quantization_attribute_encoder.h
src/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h
src/draco/compression/bit_coders/adaptive_rans_bit_decoder.cc
src/draco/compression/bit_coders/adaptive_rans_bit_decoder.h
src/draco/compression/bit_coders/adaptive_rans_bit_encoder.cc
src/draco/compression/bit_coders/adaptive_rans_bit_encoder.h
src/draco/compression/bit_coders/direct_bit_decoder.cc
src/draco/compression/bit_coders/direct_bit_decoder.h
src/draco/compression/bit_coders/direct_bit_encoder.cc
src/draco/compression/bit_coders/direct_bit_encoder.h
src/draco/compression/bit_coders/folded_integer_bit_decoder.h
src/draco/compression/bit_coders/folded_integer_bit_encoder.h
src/draco/compression/bit_coders/rans_bit_decoder.cc
src/draco/compression/bit_coders/rans_bit_decoder.h
src/draco/compression/bit_coders/rans_bit_encoder.cc
src/draco/compression/bit_coders/rans_bit_encoder.h
src/draco/compression/bit_coders/symbol_bit_decoder.cc
src/draco/compression/bit_coders/symbol_bit_decoder.h
src/draco/compression/bit_coders/symbol_bit_encoder.cc
src/draco/compression/bit_coders/symbol_bit_encoder.h
src/draco/compression/config/compression_shared.h
src/draco/compression/config/decoder_options.h
src/draco/compression/config/draco_options.h
src/draco/compression/config/encoder_options.h
src/draco/compression/config/encoding_features.h
src/draco/compression/encode_base.h
src/draco/compression/decode.cc
src/draco/compression/decode.h
src/draco/compression/encode.cc
src/draco/compression/encode.h
src/draco/compression/encode_base.h
src/draco/compression/entropy/ans.h
src/draco/compression/entropy/rans_symbol_coding.h
src/draco/compression/entropy/rans_symbol_decoder.h
src/draco/compression/entropy/rans_symbol_encoder.h
src/draco/compression/entropy/shannon_entropy.cc
src/draco/compression/entropy/shannon_entropy.h
src/draco/compression/entropy/symbol_decoding.cc
src/draco/compression/entropy/symbol_decoding.h
src/draco/compression/entropy/symbol_encoding.cc
src/draco/compression/entropy/symbol_encoding.h
src/draco/compression/expert_encode.cc
src/draco/compression/expert_encode.h
src/draco/compression/mesh/mesh_decoder.cc
src/draco/compression/mesh/mesh_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_decoder.cc
src/draco/compression/mesh/mesh_edgebreaker_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc
src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h
src/draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h
src/draco/compression/mesh/mesh_edgebreaker_encoder.cc
src/draco/compression/mesh/mesh_edgebreaker_encoder.h
src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc
src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h
src/draco/compression/mesh/mesh_edgebreaker_encoder_impl_interface.h
src/draco/compression/mesh/mesh_edgebreaker_shared.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_encoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_encoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_encoder.h
src/draco/compression/mesh/mesh_encoder.cc
src/draco/compression/mesh/mesh_encoder.h
src/draco/compression/mesh/mesh_encoder_helpers.h
src/draco/compression/mesh/mesh_sequential_decoder.cc
src/draco/compression/mesh/mesh_sequential_decoder.h
src/draco/compression/mesh/mesh_sequential_encoder.cc
src/draco/compression/mesh/mesh_sequential_encoder.h
src/draco/compression/mesh/traverser/depth_first_traverser.h
@ -106,18 +168,32 @@ set(SRC
src/draco/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h
src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h
src/draco/compression/mesh/traverser/traverser_base.h
src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.cc
src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h
src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.cc
src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h
src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.cc
src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.h
src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.cc
src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.h
src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.cc
src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h
src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.cc
src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.h
src/draco/compression/point_cloud/algorithms/point_cloud_compression_method.h
src/draco/compression/point_cloud/algorithms/point_cloud_types.h
src/draco/compression/point_cloud/algorithms/quantize_points_3.h
src/draco/compression/point_cloud/algorithms/queuing_policy.h
src/draco/compression/point_cloud/point_cloud_decoder.cc
src/draco/compression/point_cloud/point_cloud_decoder.h
src/draco/compression/point_cloud/point_cloud_encoder.cc
src/draco/compression/point_cloud/point_cloud_encoder.h
src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.cc
src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.h
src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.cc
src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.h
src/draco/compression/point_cloud/point_cloud_sequential_decoder.cc
src/draco/compression/point_cloud/point_cloud_sequential_decoder.h
src/draco/compression/point_cloud/point_cloud_sequential_encoder.cc
src/draco/compression/point_cloud/point_cloud_sequential_encoder.h
src/draco/core/bit_utils.cc
@ -128,12 +204,15 @@ set(SRC
src/draco/core/cycle_timer.h
src/draco/core/data_buffer.cc
src/draco/core/data_buffer.h
src/draco/core/decoder_buffer.cc
src/draco/core/decoder_buffer.h
src/draco/core/divide.cc
src/draco/core/divide.h
src/draco/core/draco_index_type.h
src/draco/core/draco_index_type_vector.h
src/draco/core/draco_types.cc
src/draco/core/draco_types.h
src/draco/core/draco_version.h
src/draco/core/encoder_buffer.cc
src/draco/core/encoder_buffer.h
src/draco/core/hash_utils.cc
@ -145,20 +224,21 @@ set(SRC
src/draco/core/quantization_utils.cc
src/draco/core/quantization_utils.h
src/draco/core/status.h
src/draco/core/statusor.h
src/draco/core/status_or.h
src/draco/core/varint_decoding.h
src/draco/core/varint_encoding.h
src/draco/core/vector_d.h
src/draco/mesh/corner_table.cc
src/draco/mesh/corner_table.h
src/draco/mesh/corner_table_iterators.h
src/draco/mesh/mesh.cc
src/draco/mesh/mesh.h
src/draco/mesh/mesh_are_equivalent.cc
src/draco/mesh/mesh_are_equivalent.h
src/draco/mesh/mesh_attribute_corner_table.cc
src/draco/mesh/mesh_attribute_corner_table.h
src/draco/mesh/mesh.cc
src/draco/mesh/mesh_cleanup.cc
src/draco/mesh/mesh_cleanup.h
src/draco/mesh/mesh.h
src/draco/mesh/mesh_misc_functions.cc
src/draco/mesh/mesh_misc_functions.h
src/draco/mesh/mesh_stripifier.cc
@ -169,13 +249,15 @@ set(SRC
src/draco/metadata/geometry_metadata.cc
src/draco/metadata/geometry_metadata.h
src/draco/metadata/metadata.cc
src/draco/metadata/metadata.h
src/draco/metadata/metadata_decoder.cc
src/draco/metadata/metadata_decoder.h
src/draco/metadata/metadata_encoder.cc
src/draco/metadata/metadata_encoder.h
src/draco/metadata/metadata.h
src/draco/point_cloud/point_cloud_builder.cc
src/draco/point_cloud/point_cloud_builder.h
src/draco/point_cloud/point_cloud.cc
src/draco/point_cloud/point_cloud.h
src/draco/point_cloud/point_cloud_builder.cc
src/draco/point_cloud/point_cloud_builder.h
)
set(LIB
@ -185,4 +267,5 @@ set(INC
src
)
blender_add_lib(dracoenc "${SRC}" "${INC}" "" "${LIB}")
blender_add_lib(draco "${SRC}" "${INC}" "" "${LIB}")

View File

@ -29,8 +29,9 @@ bool KeyframeAnimation::SetTimestamps(
} else {
// Check if the number of frames is consistent with
// the existing keyframes.
if (num_frames != num_points())
if (num_frames != num_points()) {
return false;
}
}
} else {
// This is the first attribute.
@ -40,10 +41,8 @@ bool KeyframeAnimation::SetTimestamps(
// Add attribute for time stamp data.
std::unique_ptr<PointAttribute> timestamp_att =
std::unique_ptr<PointAttribute>(new PointAttribute());
timestamp_att->Init(GeometryAttribute::GENERIC, nullptr, 1, DT_FLOAT32, false,
sizeof(float), 0);
timestamp_att->SetIdentityMapping();
timestamp_att->Reset(num_frames);
timestamp_att->Init(GeometryAttribute::GENERIC, 1, DT_FLOAT32, false,
num_frames);
for (PointIndex i(0); i < num_frames; ++i) {
timestamp_att->SetAttributeValue(timestamp_att->mapped_index(i),
&timestamp[i.value()]);

View File

@ -71,30 +71,29 @@ int32_t KeyframeAnimation::AddKeyframes(DataType data_type,
uint32_t num_components,
const std::vector<T> &data) {
// TODO(draco-eng): Verify T is consistent with |data_type|.
if (num_components == 0)
if (num_components == 0) {
return -1;
}
// If timestamps is not added yet, then reserve attribute 0 for timestamps.
if (!num_attributes()) {
// Add a temporary attribute with 0 points to fill attribute id 0.
std::unique_ptr<PointAttribute> temp_att =
std::unique_ptr<PointAttribute>(new PointAttribute());
temp_att->Init(GeometryAttribute::GENERIC, nullptr, num_components,
data_type, false, DataTypeLength(data_type), 0);
temp_att->Reset(0);
temp_att->Init(GeometryAttribute::GENERIC, num_components, data_type, false,
0);
this->AddAttribute(std::move(temp_att));
set_num_frames(data.size() / num_components);
}
if (data.size() != num_components * num_frames())
if (data.size() != num_components * num_frames()) {
return -1;
}
std::unique_ptr<PointAttribute> keyframe_att =
std::unique_ptr<PointAttribute>(new PointAttribute());
keyframe_att->Init(GeometryAttribute::GENERIC, nullptr, num_components,
data_type, false, DataTypeLength(data_type), 0);
keyframe_att->SetIdentityMapping();
keyframe_att->Reset(num_frames());
keyframe_att->Init(GeometryAttribute::GENERIC, num_components, data_type,
false, num_frames());
const size_t stride = num_components;
for (PointIndex i(0); i < num_frames(); ++i) {
keyframe_att->SetAttributeValue(keyframe_att->mapped_index(i),

View File

@ -21,8 +21,9 @@ Status KeyframeAnimationDecoder::Decode(const DecoderOptions &options,
KeyframeAnimation *animation) {
const auto status = PointCloudSequentialDecoder::Decode(
options, in_buffer, static_cast<PointCloud *>(animation));
if (!status.ok())
if (!status.ok()) {
return status;
}
return OkStatus();
}

View File

@ -25,8 +25,9 @@ bool AttributeOctahedronTransform::InitFromAttribute(
const AttributeTransformData *const transform_data =
attribute.GetAttributeTransformData();
if (!transform_data ||
transform_data->transform_type() != ATTRIBUTE_OCTAHEDRON_TRANSFORM)
transform_data->transform_type() != ATTRIBUTE_OCTAHEDRON_TRANSFORM) {
return false; // Wrong transform type.
}
quantization_bits_ = transform_data->GetParameterValue<int32_t>(0);
return true;
}
@ -68,8 +69,9 @@ AttributeOctahedronTransform::GeneratePortableAttribute(
float att_val[3];
int32_t dst_index = 0;
OctahedronToolBox converter;
if (!converter.SetQuantizationBits(quantization_bits_))
if (!converter.SetQuantizationBits(quantization_bits_)) {
return nullptr;
}
for (uint32_t i = 0; i < point_ids.size(); ++i) {
const AttributeValueIndex att_val_id = attribute.mapped_index(point_ids[i]);
attribute.GetValue(att_val_id, att_val);

View File

@ -25,8 +25,9 @@ bool AttributeQuantizationTransform::InitFromAttribute(
const AttributeTransformData *const transform_data =
attribute.GetAttributeTransformData();
if (!transform_data ||
transform_data->transform_type() != ATTRIBUTE_QUANTIZATION_TRANSFORM)
transform_data->transform_type() != ATTRIBUTE_QUANTIZATION_TRANSFORM) {
return false; // Wrong transform type.
}
int32_t byte_offset = 0;
quantization_bits_ = transform_data->GetParameterValue<int32_t>(byte_offset);
byte_offset += 4;
@ -80,22 +81,30 @@ bool AttributeQuantizationTransform::ComputeParameters(
++i) {
attribute.GetValue(i, att_val.get());
for (int c = 0; c < num_components; ++c) {
if (min_values_[c] > att_val[c])
if (min_values_[c] > att_val[c]) {
min_values_[c] = att_val[c];
if (max_values[c] < att_val[c])
}
if (max_values[c] < att_val[c]) {
max_values[c] = att_val[c];
}
}
}
for (int c = 0; c < num_components; ++c) {
if (std::isnan(min_values_[c]) || std::isinf(min_values_[c]) ||
std::isnan(max_values[c]) || std::isinf(max_values[c])) {
return false;
}
const float dif = max_values[c] - min_values_[c];
if (dif > range_)
if (dif > range_) {
range_ = dif;
}
}
// In case all values are the same, initialize the range to unit length. This
// will ensure that all values are quantized properly to the same value.
if (range_ == 0.f)
if (range_ == 0.f) {
range_ = 1.f;
}
return true;
}

View File

@ -14,8 +14,6 @@
//
#include "draco/attributes/geometry_attribute.h"
using std::array;
namespace draco {
GeometryAttribute::GeometryAttribute()
@ -45,8 +43,9 @@ void GeometryAttribute::Init(GeometryAttribute::Type attribute_type,
}
bool GeometryAttribute::CopyFrom(const GeometryAttribute &src_att) {
if (buffer_ == nullptr || src_att.buffer_ == nullptr)
if (buffer_ == nullptr || src_att.buffer_ == nullptr) {
return false;
}
buffer_->Update(src_att.buffer_->data(), src_att.buffer_->data_size());
num_components_ = src_att.num_components_;
data_type_ = src_att.data_type_;
@ -55,27 +54,35 @@ bool GeometryAttribute::CopyFrom(const GeometryAttribute &src_att) {
byte_offset_ = src_att.byte_offset_;
attribute_type_ = src_att.attribute_type_;
buffer_descriptor_ = src_att.buffer_descriptor_;
unique_id_ = src_att.unique_id_;
return true;
}
bool GeometryAttribute::operator==(const GeometryAttribute &va) const {
if (attribute_type_ != va.attribute_type_)
if (attribute_type_ != va.attribute_type_) {
return false;
}
// It's OK to compare just the buffer descriptors here. We don't need to
// compare the buffers themselves.
if (buffer_descriptor_.buffer_id != va.buffer_descriptor_.buffer_id)
if (buffer_descriptor_.buffer_id != va.buffer_descriptor_.buffer_id) {
return false;
}
if (buffer_descriptor_.buffer_update_count !=
va.buffer_descriptor_.buffer_update_count)
va.buffer_descriptor_.buffer_update_count) {
return false;
if (num_components_ != va.num_components_)
}
if (num_components_ != va.num_components_) {
return false;
if (data_type_ != va.data_type_)
}
if (data_type_ != va.data_type_) {
return false;
if (byte_stride_ != va.byte_stride_)
}
if (byte_stride_ != va.byte_stride_) {
return false;
if (byte_offset_ != va.byte_offset_)
}
if (byte_offset_ != va.byte_offset_) {
return false;
}
return true;
}

View File

@ -91,8 +91,9 @@ class GeometryAttribute {
// Byte address of the attribute index.
const int64_t byte_pos = byte_offset_ + byte_stride_ * att_index.value();
// Check we are not reading past end of data.
if (byte_pos + sizeof(*out) > buffer_->data_size())
if (byte_pos + sizeof(*out) > buffer_->data_size()) {
return false;
}
buffer_->Read(byte_pos, &((*out)[0]), sizeof(*out));
return true;
}
@ -118,6 +119,13 @@ class GeometryAttribute {
buffer_->Read(byte_pos, out_data, byte_stride_);
}
// Sets a value of an attribute entry. The input value must be allocated to
// cover all components of a single attribute entry.
void SetAttributeValue(AttributeValueIndex entry_index, const void *value) {
const int64_t byte_pos = entry_index.value() * byte_stride();
buffer_->Write(byte_pos, value, byte_stride());
}
// DEPRECATED: Use
// ConvertValue(AttributeValueIndex att_id,
// int out_num_components,
@ -139,8 +147,9 @@ class GeometryAttribute {
template <typename OutT>
bool ConvertValue(AttributeValueIndex att_id, int8_t out_num_components,
OutT *out_val) const {
if (out_val == nullptr)
if (out_val == nullptr) {
return false;
}
switch (data_type_) {
case DT_INT8:
return ConvertTypedValue<int8_t, OutT>(att_id, out_num_components,
@ -191,6 +200,26 @@ class GeometryAttribute {
return ConvertValue<OutT>(att_index, num_components_, out_value);
}
// Utility function. Returns |attribute_type| as std::string.
static std::string TypeToString(Type attribute_type) {
switch (attribute_type) {
case INVALID:
return "INVALID";
case POSITION:
return "POSITION";
case NORMAL:
return "NORMAL";
case COLOR:
return "COLOR";
case TEX_COORD:
return "TEX_COORD";
case GENERIC:
return "GENERIC";
default:
return "UNKNOWN";
}
}
bool operator==(const GeometryAttribute &va) const;
// Returns the type of the attribute indicating the nature of the attribute.
@ -285,8 +314,8 @@ struct GeometryAttributeHasher {
size_t hash = HashCombine(va.buffer_descriptor_.buffer_id,
va.buffer_descriptor_.buffer_update_count);
hash = HashCombine(va.num_components_, hash);
hash = HashCombine((int8_t)va.data_type_, hash);
hash = HashCombine((int8_t)va.attribute_type_, hash);
hash = HashCombine(static_cast<int8_t>(va.data_type_), hash);
hash = HashCombine(static_cast<int8_t>(va.attribute_type_), hash);
hash = HashCombine(va.byte_stride_, hash);
return HashCombine(va.byte_offset_, hash);
}

View File

@ -32,20 +32,32 @@ PointAttribute::PointAttribute(const GeometryAttribute &att)
num_unique_entries_(0),
identity_mapping_(false) {}
void PointAttribute::Init(Type attribute_type, int8_t num_components,
DataType data_type, bool normalized,
size_t num_attribute_values) {
attribute_buffer_ = std::unique_ptr<DataBuffer>(new DataBuffer());
GeometryAttribute::Init(attribute_type, attribute_buffer_.get(),
num_components, data_type, normalized,
DataTypeLength(data_type) * num_components, 0);
Reset(num_attribute_values);
SetIdentityMapping();
}
void PointAttribute::CopyFrom(const PointAttribute &src_att) {
if (buffer() == nullptr) {
// If the destination attribute doesn't have a valid buffer, create it.
attribute_buffer_ = std::unique_ptr<DataBuffer>(new DataBuffer());
ResetBuffer(attribute_buffer_.get(), 0, 0);
}
if (!GeometryAttribute::CopyFrom(src_att))
if (!GeometryAttribute::CopyFrom(src_att)) {
return;
}
identity_mapping_ = src_att.identity_mapping_;
num_unique_entries_ = src_att.num_unique_entries_;
indices_map_ = src_att.indices_map_;
if (src_att.attribute_transform_data_) {
attribute_transform_data_ = std::unique_ptr<AttributeTransformData>(
new AttributeTransformData(*src_att.attribute_transform_data_.get()));
new AttributeTransformData(*src_att.attribute_transform_data_));
} else {
attribute_transform_data_ = nullptr;
}
@ -56,14 +68,20 @@ bool PointAttribute::Reset(size_t num_attribute_values) {
attribute_buffer_ = std::unique_ptr<DataBuffer>(new DataBuffer());
}
const int64_t entry_size = DataTypeLength(data_type()) * num_components();
if (!attribute_buffer_->Update(nullptr, num_attribute_values * entry_size))
if (!attribute_buffer_->Update(nullptr, num_attribute_values * entry_size)) {
return false;
}
// Assign the new buffer to the parent attribute.
ResetBuffer(attribute_buffer_.get(), entry_size, 0);
num_unique_entries_ = static_cast<uint32_t>(num_attribute_values);
return true;
}
void PointAttribute::Resize(size_t new_num_unique_entries) {
num_unique_entries_ = static_cast<uint32_t>(new_num_unique_entries);
attribute_buffer_->Resize(new_num_unique_entries * byte_stride());
}
#ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
AttributeValueIndex::ValueType PointAttribute::DeduplicateValues(
const GeometryAttribute &in_att) {
@ -100,8 +118,9 @@ AttributeValueIndex::ValueType PointAttribute::DeduplicateValues(
default:
return -1; // Unsupported data type.
}
if (unique_vals == 0)
if (unique_vals == 0) {
return -1; // Unexpected error.
}
return unique_vals;
}
@ -181,8 +200,9 @@ AttributeValueIndex::ValueType PointAttribute::DeduplicateFormattedValues(
++unique_vals;
}
}
if (unique_vals == num_unique_entries_)
if (unique_vals == num_unique_entries_) {
return unique_vals.value(); // Nothing has changed.
}
if (is_mapping_identity()) {
// Change identity mapping to the explicit one.
// The number of points is equal to the number of old unique values.

View File

@ -17,13 +17,12 @@
#include <memory>
#include "draco/draco_features.h"
#include "draco/attributes/attribute_transform_data.h"
#include "draco/attributes/geometry_attribute.h"
#include "draco/core/draco_index_type_vector.h"
#include "draco/core/hash_utils.h"
#include "draco/core/macros.h"
#include "draco/draco_features.h"
namespace draco {
@ -41,6 +40,12 @@ class PointAttribute : public GeometryAttribute {
PointAttribute(PointAttribute &&attribute) = default;
PointAttribute &operator=(PointAttribute &&attribute) = default;
// Initializes a point attribute. By default the attribute will be set to
// identity mapping between point indices and attribute values. To set custom
// mapping use SetExplicitMapping() function.
void Init(Type attribute_type, int8_t num_components, DataType data_type,
bool normalized, size_t num_attribute_values);
// Copies attribute data from the provided |src_att| attribute.
void CopyFrom(const PointAttribute &src_att);
@ -49,15 +54,17 @@ class PointAttribute : public GeometryAttribute {
size_t size() const { return num_unique_entries_; }
AttributeValueIndex mapped_index(PointIndex point_index) const {
if (identity_mapping_)
if (identity_mapping_) {
return AttributeValueIndex(point_index.value());
}
return indices_map_[point_index];
}
DataBuffer *buffer() const { return attribute_buffer_.get(); }
bool is_mapping_identity() const { return identity_mapping_; }
size_t indices_map_size() const {
if (is_mapping_identity())
if (is_mapping_identity()) {
return 0;
}
return indices_map_.size();
}
@ -65,10 +72,14 @@ class PointAttribute : public GeometryAttribute {
return GetAddress(mapped_index(point_index));
}
// Sets the new number of unique attribute entries for the attribute.
void Resize(size_t new_num_unique_entries) {
num_unique_entries_ = static_cast<uint32_t>(new_num_unique_entries);
}
// Sets the new number of unique attribute entries for the attribute. The
// function resizes the attribute storage to hold |num_attribute_values|
// entries.
// All previous entries with AttributeValueIndex < |num_attribute_values|
// are preserved. Caller needs to ensure that the PointAttribute is still
// valid after the resizing operation (that is, each point is mapped to a
// valid attribute value).
void Resize(size_t new_num_unique_entries);
// Functions for setting the type of mapping between point indices and
// attribute entry ids.
@ -92,13 +103,6 @@ class PointAttribute : public GeometryAttribute {
indices_map_[point_index] = entry_index;
}
// Sets a value of an attribute entry. The input value must be allocated to
// cover all components of a single attribute entry.
void SetAttributeValue(AttributeValueIndex entry_index, const void *value) {
const int64_t byte_pos = entry_index.value() * byte_stride();
buffer()->Write(byte_pos, value, byte_stride());
}
// Same as GeometryAttribute::GetValue(), but using point id as the input.
// Mapping to attribute value index is performed automatically.
void GetMappedValue(PointIndex point_index, void *out_data) const {
@ -165,7 +169,7 @@ struct PointAttributeHasher {
hash = HashCombine(attribute.identity_mapping_, hash);
hash = HashCombine(attribute.num_unique_entries_, hash);
hash = HashCombine(attribute.indices_map_.size(), hash);
if (attribute.indices_map_.size() > 0) {
if (!attribute.indices_map_.empty()) {
const uint64_t indices_hash = FingerprintString(
reinterpret_cast<const char *>(attribute.indices_map_.data()),
attribute.indices_map_.size());

View File

@ -33,31 +33,42 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (point_cloud_decoder_->bitstream_version() <
DRACO_BITSTREAM_VERSION(2, 0)) {
if (!in_buffer->Decode(&num_attributes))
if (!in_buffer->Decode(&num_attributes)) {
return false;
}
} else
#endif
{
if (!DecodeVarint(&num_attributes, in_buffer))
if (!DecodeVarint(&num_attributes, in_buffer)) {
return false;
}
}
if (num_attributes == 0)
if (num_attributes == 0) {
return false;
}
point_attribute_ids_.resize(num_attributes);
PointCloud *pc = point_cloud_;
for (uint32_t i = 0; i < num_attributes; ++i) {
// Decode attribute descriptor data.
uint8_t att_type, data_type, num_components, normalized;
if (!in_buffer->Decode(&att_type))
if (!in_buffer->Decode(&att_type)) {
return false;
if (!in_buffer->Decode(&data_type))
}
if (!in_buffer->Decode(&data_type)) {
return false;
if (!in_buffer->Decode(&num_components))
}
if (!in_buffer->Decode(&num_components)) {
return false;
if (!in_buffer->Decode(&normalized))
}
if (!in_buffer->Decode(&normalized)) {
return false;
if (data_type <= DT_INVALID || data_type >= DT_TYPES_COUNT)
}
if (att_type >= GeometryAttribute::NAMED_ATTRIBUTES_COUNT) {
return false;
}
if (data_type == DT_INVALID || data_type >= DT_TYPES_COUNT) {
return false;
}
const DataType draco_dt = static_cast<DataType>(data_type);
// Add the attribute to the point cloud
@ -70,8 +81,9 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
if (point_cloud_decoder_->bitstream_version() <
DRACO_BITSTREAM_VERSION(1, 3)) {
uint16_t custom_id;
if (!in_buffer->Decode(&custom_id))
if (!in_buffer->Decode(&custom_id)) {
return false;
}
// TODO(draco-eng): Add "custom_id" to attribute metadata.
unique_id = static_cast<uint32_t>(custom_id);
ga.set_unique_id(unique_id);
@ -87,8 +99,10 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
point_attribute_ids_[i] = att_id;
// Update the inverse map.
if (att_id >= static_cast<int32_t>(point_attribute_to_local_id_map_.size()))
if (att_id >=
static_cast<int32_t>(point_attribute_to_local_id_map_.size())) {
point_attribute_to_local_id_map_.resize(att_id + 1, -1);
}
point_attribute_to_local_id_map_[att_id] = i;
}
return true;

View File

@ -17,11 +17,10 @@
#include <vector>
#include "draco/draco_features.h"
#include "draco/compression/attributes/attributes_decoder_interface.h"
#include "draco/compression/point_cloud/point_cloud_decoder.h"
#include "draco/core/decoder_buffer.h"
#include "draco/draco_features.h"
#include "draco/point_cloud/point_cloud.h"
namespace draco {
@ -54,12 +53,15 @@ class AttributesDecoder : public AttributesDecoderInterface {
// Decodes attribute data from the source buffer.
bool DecodeAttributes(DecoderBuffer *in_buffer) override {
if (!DecodePortableAttributes(in_buffer))
if (!DecodePortableAttributes(in_buffer)) {
return false;
if (!DecodeDataNeededByPortableTransforms(in_buffer))
}
if (!DecodeDataNeededByPortableTransforms(in_buffer)) {
return false;
if (!TransformAttributesToOriginalFormat())
}
if (!TransformAttributesToOriginalFormat()) {
return false;
}
return true;
}
@ -67,8 +69,9 @@ class AttributesDecoder : public AttributesDecoderInterface {
int32_t GetLocalIdForPointAttribute(int32_t point_attribute_id) const {
const int id_map_size =
static_cast<int>(point_attribute_to_local_id_map_.size());
if (point_attribute_id >= id_map_size)
if (point_attribute_id >= id_map_size) {
return -1;
}
return point_attribute_to_local_id_map_[point_attribute_id];
}
virtual bool DecodePortableAttributes(DecoderBuffer *in_buffer) = 0;

View File

@ -48,15 +48,18 @@ class AttributesEncoder {
// Encode attribute data to the target buffer.
virtual bool EncodeAttributes(EncoderBuffer *out_buffer) {
if (!TransformAttributesToPortableFormat())
if (!TransformAttributesToPortableFormat()) {
return false;
if (!EncodePortableAttributes(out_buffer))
}
if (!EncodePortableAttributes(out_buffer)) {
return false;
}
// Encode data needed by portable transforms after the attribute is encoded.
// This corresponds to the order in which the data is going to be decoded by
// the decoder.
if (!EncodeDataNeededByPortableTransforms(out_buffer))
if (!EncodeDataNeededByPortableTransforms(out_buffer)) {
return false;
}
return true;
}
@ -87,8 +90,9 @@ class AttributesEncoder {
void AddAttributeId(int32_t id) {
point_attribute_ids_.push_back(id);
if (id >= static_cast<int32_t>(point_attribute_to_local_id_map_.size()))
if (id >= static_cast<int32_t>(point_attribute_to_local_id_map_.size())) {
point_attribute_to_local_id_map_.resize(id + 1, -1);
}
point_attribute_to_local_id_map_[id] =
static_cast<int32_t>(point_attribute_ids_.size()) - 1;
}
@ -127,8 +131,9 @@ class AttributesEncoder {
int32_t GetLocalIdForPointAttribute(int32_t point_attribute_id) const {
const int id_map_size =
static_cast<int>(point_attribute_to_local_id_map_.size());
if (point_attribute_id >= id_map_size)
if (point_attribute_id >= id_map_size) {
return -1;
}
return point_attribute_to_local_id_map_[point_attribute_id];
}

View File

@ -13,6 +13,7 @@
// limitations under the License.
//
#include "draco/compression/attributes/kd_tree_attributes_decoder.h"
#include "draco/compression/attributes/kd_tree_attributes_shared.h"
#include "draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h"
#include "draco/compression/point_cloud/algorithms/float_points_tree_decoder.h"
@ -92,7 +93,7 @@ class PointAttributeVectorOutputIterator {
const uint32_t &data_size = std::get<3>(att);
const uint32_t &num_components = std::get<4>(att);
const uint32_t *data_source = val.data() + offset;
if (data_size != 4) { // handle uint16_t, uint8_t
if (data_size < 4) { // handle uint16_t, uint8_t
// selectively copy data bytes
uint8_t *data_counter = data_;
for (uint32_t index = 0; index < num_components;
@ -103,8 +104,9 @@ class PointAttributeVectorOutputIterator {
data_source = reinterpret_cast<uint32_t *>(data_);
}
const AttributeValueIndex avi = attribute->mapped_index(point_id_);
if (avi >= static_cast<uint32_t>(attribute->size()))
if (avi >= static_cast<uint32_t>(attribute->size())) {
return *this;
}
attribute->SetAttributeValue(avi, data_source);
}
return *this;
@ -134,8 +136,9 @@ bool KdTreeAttributesDecoder::DecodePortableAttributes(
return true;
}
uint8_t compression_level = 0;
if (!in_buffer->Decode(&compression_level))
if (!in_buffer->Decode(&compression_level)) {
return false;
}
const int32_t num_points = GetDecoder()->point_cloud()->num_points();
// Decode data using the kd tree decoding into integer (portable) attributes.
@ -197,44 +200,51 @@ bool KdTreeAttributesDecoder::DecodePortableAttributes(
switch (compression_level) {
case 0: {
DynamicIntegerPointsKdTreeDecoder<0> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it))
if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
}
break;
}
case 1: {
DynamicIntegerPointsKdTreeDecoder<1> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it))
if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
}
break;
}
case 2: {
DynamicIntegerPointsKdTreeDecoder<2> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it))
if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
}
break;
}
case 3: {
DynamicIntegerPointsKdTreeDecoder<3> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it))
if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
}
break;
}
case 4: {
DynamicIntegerPointsKdTreeDecoder<4> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it))
if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
}
break;
}
case 5: {
DynamicIntegerPointsKdTreeDecoder<5> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it))
if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
}
break;
}
case 6: {
DynamicIntegerPointsKdTreeDecoder<6> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it))
if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
}
break;
}
default:
@ -256,22 +266,26 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
if (att->data_type() == DT_FLOAT32) {
const int num_components = att->num_components();
min_value.resize(num_components);
if (!in_buffer->Decode(&min_value[0], sizeof(float) * num_components))
if (!in_buffer->Decode(&min_value[0], sizeof(float) * num_components)) {
return false;
}
float max_value_dif;
if (!in_buffer->Decode(&max_value_dif))
if (!in_buffer->Decode(&max_value_dif)) {
return false;
}
uint8_t quantization_bits;
if (!in_buffer->Decode(&quantization_bits) || quantization_bits > 31)
if (!in_buffer->Decode(&quantization_bits) || quantization_bits > 31) {
return false;
}
AttributeQuantizationTransform transform;
transform.SetParameters(quantization_bits, min_value.data(),
num_components, max_value_dif);
const int num_transforms =
static_cast<int>(attribute_quantization_transforms_.size());
if (!transform.TransferToAttribute(
quantized_portable_attributes_[num_transforms].get()))
quantized_portable_attributes_[num_transforms].get())) {
return false;
}
attribute_quantization_transforms_.push_back(transform);
}
}
@ -299,6 +313,10 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
const DataType data_type = att->data_type();
const uint32_t data_size = (std::max)(0, DataTypeLength(data_type));
const uint32_t num_components = att->num_components();
if (data_size > 4) {
return false;
}
atts[attribute_index] = std::make_tuple(
att, total_dimensionality, data_type, data_size, num_components);
// everything is treated as 32bit in the encoder.
@ -310,24 +328,30 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
att->SetIdentityMapping();
// Decode method
uint8_t method;
if (!in_buffer->Decode(&method))
if (!in_buffer->Decode(&method)) {
return false;
}
if (method == KdTreeAttributesEncodingMethod::kKdTreeQuantizationEncoding) {
uint8_t compression_level = 0;
if (!in_buffer->Decode(&compression_level))
if (!in_buffer->Decode(&compression_level)) {
return false;
}
uint32_t num_points = 0;
if (!in_buffer->Decode(&num_points))
if (!in_buffer->Decode(&num_points)) {
return false;
}
att->Reset(num_points);
FloatPointsTreeDecoder decoder;
decoder.set_num_points_from_header(num_points);
PointAttributeVectorOutputIterator<float> out_it(atts);
if (!decoder.DecodePointCloud(in_buffer, out_it))
if (!decoder.DecodePointCloud(in_buffer, out_it)) {
return false;
}
} else if (method == KdTreeAttributesEncodingMethod::kKdTreeIntegerEncoding) {
uint8_t compression_level = 0;
if (!in_buffer->Decode(&compression_level))
if (!in_buffer->Decode(&compression_level)) {
return false;
}
if (6 < compression_level) {
LOGE("KdTreeAttributesDecoder: compression level %i not supported.\n",
compression_level);
@ -335,8 +359,9 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
}
uint32_t num_points;
if (!in_buffer->Decode(&num_points))
if (!in_buffer->Decode(&num_points)) {
return false;
}
for (auto attribute_index = 0;
static_cast<uint32_t>(attribute_index) < attribute_count;
@ -353,44 +378,51 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
switch (compression_level) {
case 0: {
DynamicIntegerPointsKdTreeDecoder<0> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it))
if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
}
break;
}
case 1: {
DynamicIntegerPointsKdTreeDecoder<1> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it))
if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
}
break;
}
case 2: {
DynamicIntegerPointsKdTreeDecoder<2> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it))
if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
}
break;
}
case 3: {
DynamicIntegerPointsKdTreeDecoder<3> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it))
if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
}
break;
}
case 4: {
DynamicIntegerPointsKdTreeDecoder<4> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it))
if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
}
break;
}
case 5: {
DynamicIntegerPointsKdTreeDecoder<5> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it))
if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
}
break;
}
case 6: {
DynamicIntegerPointsKdTreeDecoder<6> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it))
if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
}
break;
}
default:
@ -445,16 +477,19 @@ bool KdTreeAttributesDecoder::TransformAttributesToOriginalFormat() {
// Values are stored as unsigned in the attribute, make them signed again.
if (att->data_type() == DT_INT32) {
if (!TransformAttributeBackToSignedType<int32_t>(
att, num_processed_signed_components))
att, num_processed_signed_components)) {
return false;
}
} else if (att->data_type() == DT_INT16) {
if (!TransformAttributeBackToSignedType<int16_t>(
att, num_processed_signed_components))
att, num_processed_signed_components)) {
return false;
}
} else if (att->data_type() == DT_INT8) {
if (!TransformAttributeBackToSignedType<int8_t>(
att, num_processed_signed_components))
att, num_processed_signed_components)) {
return false;
}
}
num_processed_signed_components += att->num_components();
} else if (att->data_type() == DT_FLOAT32) {
@ -491,8 +526,9 @@ bool KdTreeAttributesDecoder::TransformAttributesToOriginalFormat() {
int quant_val_id = 0;
int out_byte_pos = 0;
Dequantizer dequantizer;
if (!dequantizer.Init(transform.range(), max_quantized_value))
if (!dequantizer.Init(transform.range(), max_quantized_value)) {
return false;
}
const uint32_t *const portable_attribute_data =
reinterpret_cast<const uint32_t *>(
src_att->GetAddress(AttributeValueIndex(0)));

View File

@ -13,6 +13,7 @@
// limitations under the License.
//
#include "draco/compression/attributes/kd_tree_attributes_encoder.h"
#include "draco/compression/attributes/kd_tree_attributes_shared.h"
#include "draco/compression/attributes/point_d_vector.h"
#include "draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h"
@ -50,8 +51,9 @@ bool KdTreeAttributesEncoder::TransformAttributesToPortableFormat() {
AttributeQuantizationTransform attribute_quantization_transform;
const int quantization_bits = encoder()->options()->GetAttributeInt(
att_id, "quantization_bits", -1);
if (quantization_bits < 1)
if (quantization_bits < 1) {
return false;
}
if (encoder()->options()->IsAttributeOptionSet(att_id,
"quantization_origin") &&
encoder()->options()->IsAttributeOptionSet(att_id,
@ -91,8 +93,9 @@ bool KdTreeAttributesEncoder::TransformAttributesToPortableFormat() {
++avi) {
att->ConvertValue<int32_t>(avi, &act_value[0]);
for (int c = 0; c < att->num_components(); ++c) {
if (min_value[c] > act_value[c])
if (min_value[c] > act_value[c]) {
min_value[c] = act_value[c];
}
}
}
for (int c = 0; c < att->num_components(); ++c) {
@ -167,8 +170,9 @@ bool KdTreeAttributesEncoder::EncodePortableAttributes(
return false;
}
if (source_att == nullptr)
if (source_att == nullptr) {
return false;
}
// Copy source_att to the vector.
if (source_att->data_type() == DT_UINT32) {
@ -233,50 +237,57 @@ bool KdTreeAttributesEncoder::EncodePortableAttributes(
case 6: {
DynamicIntegerPointsKdTreeEncoder<6> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
num_bits, out_buffer))
num_bits, out_buffer)) {
return false;
}
break;
}
case 5: {
DynamicIntegerPointsKdTreeEncoder<5> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
num_bits, out_buffer))
num_bits, out_buffer)) {
return false;
}
break;
}
case 4: {
DynamicIntegerPointsKdTreeEncoder<4> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
num_bits, out_buffer))
num_bits, out_buffer)) {
return false;
}
break;
}
case 3: {
DynamicIntegerPointsKdTreeEncoder<3> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
num_bits, out_buffer))
num_bits, out_buffer)) {
return false;
}
break;
}
case 2: {
DynamicIntegerPointsKdTreeEncoder<2> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
num_bits, out_buffer))
num_bits, out_buffer)) {
return false;
}
break;
}
case 1: {
DynamicIntegerPointsKdTreeEncoder<1> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
num_bits, out_buffer))
num_bits, out_buffer)) {
return false;
}
break;
}
case 0: {
DynamicIntegerPointsKdTreeEncoder<0> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
num_bits, out_buffer))
num_bits, out_buffer)) {
return false;
}
break;
}
// Compression level and/or encoding speed seem wrong.

View File

@ -32,8 +32,9 @@ class LinearSequencer : public PointsSequencer {
protected:
bool GenerateSequenceInternal() override {
if (num_points_ < 0)
if (num_points_ < 0) {
return false;
}
out_point_ids()->resize(num_points_);
for (int i = 0; i < num_points_; ++i) {
out_point_ids()->at(i) = PointIndex(i);

View File

@ -39,6 +39,7 @@
#define DRACO_COMPRESSION_ATTRIBUTES_NORMAL_COMPRESSION_UTILS_H_
#include <inttypes.h>
#include <algorithm>
#include <cmath>
@ -55,8 +56,9 @@ class OctahedronToolBox {
center_value_(-1) {}
bool SetQuantizationBits(int32_t q) {
if (q < 2 || q > 30)
if (q < 2 || q > 30) {
return false;
}
quantization_bits_ = q;
max_quantized_value_ = (1 << quantization_bits_) - 1;
max_value_ = max_quantized_value_ - 1;
@ -157,8 +159,9 @@ class OctahedronToolBox {
int_vec[2] = 0;
}
// Take care of the sign.
if (scaled_vector[2] < 0)
if (scaled_vector[2] < 0) {
int_vec[2] *= -1;
}
IntegerVectorToQuantizedOctahedralCoords(int_vec, out_s, out_t);
}
@ -189,6 +192,8 @@ class OctahedronToolBox {
}
}
// TODO(b/149328891): Change function to not use templates as |T| is only
// float.
template <typename T>
void OctaherdalCoordsToUnitVector(T in_s, T in_t, T *out_vector) const {
DRACO_DCHECK_GE(in_s, 0);
@ -304,18 +309,21 @@ class OctahedronToolBox {
// For correction values.
int32_t ModMax(int32_t x) const {
if (x > this->center_value())
if (x > this->center_value()) {
return x - this->max_quantized_value();
if (x < -this->center_value())
}
if (x < -this->center_value()) {
return x + this->max_quantized_value();
}
return x;
}
// For correction values.
int32_t MakePositive(int32_t x) const {
DRACO_DCHECK_LE(x, this->center_value() * 2);
if (x < 0)
if (x < 0) {
return x + this->max_quantized_value();
}
return x;
}

View File

@ -19,6 +19,7 @@
#include <cstring>
#include <memory>
#include <vector>
#include "draco/core/macros.h"
namespace draco {
@ -42,8 +43,9 @@ class PseudoPointD {
// Specifically copies referenced memory
void swap(PseudoPointD &other) noexcept {
for (internal_t dim = 0; dim < dimension_; dim += 1)
for (internal_t dim = 0; dim < dimension_; dim += 1) {
std::swap(mem_[dim], other.mem_[dim]);
}
}
PseudoPointD(const PseudoPointD &other)
@ -59,9 +61,11 @@ class PseudoPointD {
}
bool operator==(const PseudoPointD &other) const {
for (auto dim = 0; dim < dimension_; dim += 1)
if (mem_[dim] != other.mem_[dim])
for (auto dim = 0; dim < dimension_; dim += 1) {
if (mem_[dim] != other.mem_[dim]) {
return false;
}
}
return true;
}
bool operator!=(const PseudoPointD &other) const {

View File

@ -18,13 +18,12 @@
#include <algorithm>
#include <cmath>
#include "draco/draco_features.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h"
#include "draco/compression/bit_coders/rans_bit_decoder.h"
#include "draco/core/varint_decoding.h"
#include "draco/draco_features.h"
namespace draco {
@ -123,8 +122,9 @@ bool MeshPredictionSchemeConstrainedMultiParallelogramDecoder<
++num_parallelograms;
// Stop processing when we reach the maximum number of allowed
// parallelograms.
if (num_parallelograms == kMaxNumParallelograms)
if (num_parallelograms == kMaxNumParallelograms) {
break;
}
}
// Proceed to the next corner attached to the vertex. First swing left
@ -154,8 +154,9 @@ bool MeshPredictionSchemeConstrainedMultiParallelogramDecoder<
for (int i = 0; i < num_parallelograms; ++i) {
const int context = num_parallelograms - 1;
const int pos = is_crease_edge_pos[context]++;
if (is_crease_edge_[context].size() <= pos)
if (is_crease_edge_[context].size() <= pos) {
return false;
}
const bool is_crease = is_crease_edge_[context][pos];
if (!is_crease) {
++num_used_parallelograms;
@ -206,12 +207,15 @@ bool MeshPredictionSchemeConstrainedMultiParallelogramDecoder<
// Encode selected edges using separate rans bit coder for each context.
for (int i = 0; i < kMaxNumParallelograms; ++i) {
uint32_t num_flags;
DecodeVarint<uint32_t>(&num_flags, buffer);
if (!DecodeVarint<uint32_t>(&num_flags, buffer)) {
return false;
}
if (num_flags > 0) {
is_crease_edge_[i].resize(num_flags);
RAnsBitDecoder decoder;
if (!decoder.StartDecoding(buffer))
if (!decoder.StartDecoding(buffer)) {
return false;
}
for (uint32_t j = 0; j < num_flags; ++j) {
is_crease_edge_[i][j] = decoder.DecodeNextBit();
}

View File

@ -108,10 +108,12 @@ class MeshPredictionSchemeConstrainedMultiParallelogramEncoder
int residual_error;
bool operator<(const Error &e) const {
if (num_bits < e.num_bits)
if (num_bits < e.num_bits) {
return true;
if (num_bits > e.num_bits)
}
if (num_bits > e.num_bits) {
return false;
}
return residual_error < e.residual_error;
}
};
@ -231,8 +233,9 @@ bool MeshPredictionSchemeConstrainedMultiParallelogramEncoder<
++num_parallelograms;
// Stop processing when we reach the maximum number of allowed
// parallelograms.
if (num_parallelograms == kMaxNumParallelograms)
if (num_parallelograms == kMaxNumParallelograms) {
break;
}
}
// Proceed to the next corner attached to the vertex. First swing left
@ -304,8 +307,9 @@ bool MeshPredictionSchemeConstrainedMultiParallelogramEncoder<
}
uint8_t configuration = 0;
for (int j = 0; j < num_parallelograms; ++j) {
if (exluded_parallelograms[j])
if (exluded_parallelograms[j]) {
continue;
}
for (int c = 0; c < num_components; ++c) {
multi_pred_vals[c] += pred_vals[j][c];
}

View File

@ -15,11 +15,10 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_DECODER_H_
#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_DECODER_H_
#include "draco/draco_features.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h"
#include "draco/compression/bit_coders/rans_bit_decoder.h"
#include "draco/draco_features.h"
namespace draco {
@ -52,12 +51,15 @@ class MeshPredictionSchemeGeometricNormalDecoder
}
bool IsInitialized() const override {
if (!predictor_.IsInitialized())
if (!predictor_.IsInitialized()) {
return false;
if (!this->mesh_data().IsInitialized())
}
if (!this->mesh_data().IsInitialized()) {
return false;
if (!octahedron_tool_box_.IsInitialized())
}
if (!octahedron_tool_box_.IsInitialized()) {
return false;
}
return true;
}
@ -70,10 +72,12 @@ class MeshPredictionSchemeGeometricNormalDecoder
}
bool SetParentAttribute(const PointAttribute *att) override {
if (att->attribute_type() != GeometryAttribute::POSITION)
if (att->attribute_type() != GeometryAttribute::POSITION) {
return false; // Invalid attribute type.
if (att->num_components() != 3)
}
if (att->num_components() != 3) {
return false; // Currently works only for 3 component positions.
}
predictor_.SetPositionAttribute(*att);
return true;
}
@ -137,23 +141,28 @@ bool MeshPredictionSchemeGeometricNormalDecoder<
DataTypeT, TransformT, MeshDataT>::DecodePredictionData(DecoderBuffer
*buffer) {
// Get data needed for transform
if (!this->transform().DecodeTransformData(buffer))
if (!this->transform().DecodeTransformData(buffer)) {
return false;
}
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
uint8_t prediction_mode;
buffer->Decode(&prediction_mode);
if (!buffer->Decode(&prediction_mode)) {
return false;
}
if (!predictor_.SetNormalPredictionMode(
NormalPredictionMode(prediction_mode)))
NormalPredictionMode(prediction_mode))) {
return false;
}
}
#endif
// Init normal flips.
if (!flip_normal_bit_decoder_.StartDecoding(buffer))
if (!flip_normal_bit_decoder_.StartDecoding(buffer)) {
return false;
}
return true;
}

View File

@ -50,10 +50,12 @@ class MeshPredictionSchemeGeometricNormalEncoder
}
bool IsInitialized() const override {
if (!predictor_.IsInitialized())
if (!predictor_.IsInitialized()) {
return false;
if (!this->mesh_data().IsInitialized())
}
if (!this->mesh_data().IsInitialized()) {
return false;
}
return true;
}
@ -66,10 +68,12 @@ class MeshPredictionSchemeGeometricNormalEncoder
}
bool SetParentAttribute(const PointAttribute *att) override {
if (att->attribute_type() != GeometryAttribute::POSITION)
if (att->attribute_type() != GeometryAttribute::POSITION) {
return false; // Invalid attribute type.
if (att->num_components() != 3)
}
if (att->num_components() != 3) {
return false; // Currently works only for 3 component positions.
}
predictor_.SetPositionAttribute(*att);
return true;
}
@ -162,8 +166,9 @@ template <typename DataTypeT, class TransformT, class MeshDataT>
bool MeshPredictionSchemeGeometricNormalEncoder<
DataTypeT, TransformT, MeshDataT>::EncodePredictionData(EncoderBuffer
*buffer) {
if (!this->transform().EncodeTransformData(buffer))
if (!this->transform().EncodeTransformData(buffer)) {
return false;
}
// Encode normal flips.
flip_normal_bit_encoder_.EndEncoding(buffer);

View File

@ -45,10 +45,12 @@ class MeshPredictionSchemeGeometricNormalPredictorBase {
entry_to_point_id_map_ = map;
}
bool IsInitialized() const {
if (pos_attribute_ == nullptr)
if (pos_attribute_ == nullptr) {
return false;
if (entry_to_point_id_map_ == nullptr)
}
if (entry_to_point_id_map_ == nullptr) {
return false;
}
return true;
}

View File

@ -16,10 +16,9 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_MULTI_PARALLELOGRAM_DECODER_H_
#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_MULTI_PARALLELOGRAM_DECODER_H_
#include "draco/draco_features.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h"
#include "draco/draco_features.h"
namespace draco {

View File

@ -47,8 +47,9 @@ inline bool ComputeParallelogramPrediction(
const std::vector<int32_t> &vertex_to_data_map, const DataTypeT *in_data,
int num_components, DataTypeT *out_prediction) {
const CornerIndex oci = table->Opposite(ci);
if (oci == kInvalidCornerIndex)
if (oci == kInvalidCornerIndex) {
return false;
}
int vert_opp, vert_next, vert_prev;
GetParallelogramEntries<CornerTableT>(oci, table, vertex_to_data_map,
&vert_opp, &vert_next, &vert_prev);

View File

@ -18,12 +18,11 @@
#include <math.h>
#include "draco/draco_features.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h"
#include "draco/compression/bit_coders/rans_bit_decoder.h"
#include "draco/core/varint_decoding.h"
#include "draco/core/vector_d.h"
#include "draco/draco_features.h"
#include "draco/mesh/corner_table.h"
namespace draco {
@ -60,10 +59,12 @@ class MeshPredictionSchemeTexCoordsDecoder
}
bool IsInitialized() const override {
if (pos_attribute_ == nullptr)
if (pos_attribute_ == nullptr) {
return false;
if (!this->mesh_data().IsInitialized())
}
if (!this->mesh_data().IsInitialized()) {
return false;
}
return true;
}
@ -76,12 +77,15 @@ class MeshPredictionSchemeTexCoordsDecoder
}
bool SetParentAttribute(const PointAttribute *att) override {
if (att == nullptr)
if (att == nullptr) {
return false;
if (att->attribute_type() != GeometryAttribute::POSITION)
}
if (att->attribute_type() != GeometryAttribute::POSITION) {
return false; // Invalid attribute type.
if (att->num_components() != 3)
}
if (att->num_components() != 3) {
return false; // Currently works only for 3 component positions.
}
pos_attribute_ = att;
return true;
}
@ -144,22 +148,27 @@ bool MeshPredictionSchemeTexCoordsDecoder<DataTypeT, TransformT, MeshDataT>::
// Decode the delta coded orientations.
uint32_t num_orientations = 0;
if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
if (!buffer->Decode(&num_orientations))
if (!buffer->Decode(&num_orientations)) {
return false;
}
} else {
if (!DecodeVarint(&num_orientations, buffer))
if (!DecodeVarint(&num_orientations, buffer)) {
return false;
}
}
if (num_orientations == 0)
if (num_orientations == 0) {
return false;
}
orientations_.resize(num_orientations);
bool last_orientation = true;
RAnsBitDecoder decoder;
if (!decoder.StartDecoding(buffer))
if (!decoder.StartDecoding(buffer)) {
return false;
}
for (uint32_t i = 0; i < num_orientations; ++i) {
if (!decoder.DecodeNextBit())
if (!decoder.DecodeNextBit()) {
last_orientation = !last_orientation;
}
orientations_[i] = last_orientation;
}
decoder.EndDecoding();

View File

@ -16,6 +16,7 @@
#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_ENCODER_H_
#include <math.h>
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h"
#include "draco/compression/bit_coders/rans_bit_encoder.h"
#include "draco/core/varint_encoding.h"
@ -55,10 +56,12 @@ class MeshPredictionSchemeTexCoordsEncoder
}
bool IsInitialized() const override {
if (pos_attribute_ == nullptr)
if (pos_attribute_ == nullptr) {
return false;
if (!this->mesh_data().IsInitialized())
}
if (!this->mesh_data().IsInitialized()) {
return false;
}
return true;
}
@ -71,10 +74,12 @@ class MeshPredictionSchemeTexCoordsEncoder
}
bool SetParentAttribute(const PointAttribute *att) override {
if (att->attribute_type() != GeometryAttribute::POSITION)
if (att->attribute_type() != GeometryAttribute::POSITION) {
return false; // Invalid attribute type.
if (att->num_components() != 3)
}
if (att->num_components() != 3) {
return false; // Currently works only for 3 component positions.
}
pos_attribute_ = att;
return true;
}

View File

@ -48,10 +48,12 @@ class MeshPredictionSchemeTexCoordsPortableDecoder
}
bool IsInitialized() const override {
if (!predictor_.IsInitialized())
if (!predictor_.IsInitialized()) {
return false;
if (!this->mesh_data().IsInitialized())
}
if (!this->mesh_data().IsInitialized()) {
return false;
}
return true;
}
@ -64,10 +66,12 @@ class MeshPredictionSchemeTexCoordsPortableDecoder
}
bool SetParentAttribute(const PointAttribute *att) override {
if (!att || att->attribute_type() != GeometryAttribute::POSITION)
if (!att || att->attribute_type() != GeometryAttribute::POSITION) {
return false; // Invalid attribute type.
if (att->num_components() != 3)
}
if (att->num_components() != 3) {
return false; // Currently works only for 3 component positions.
}
predictor_.SetPositionAttribute(*att);
return true;
}
@ -84,6 +88,10 @@ bool MeshPredictionSchemeTexCoordsPortableDecoder<
DataTypeT *out_data, int /* size */,
int num_components,
const PointIndex *entry_to_point_id_map) {
if (num_components != MeshPredictionSchemeTexCoordsPortablePredictor<
DataTypeT, MeshDataT>::kNumComponents) {
return false;
}
predictor_.SetEntryToPointIdMap(entry_to_point_id_map);
this->transform().Init(num_components);
@ -92,8 +100,9 @@ bool MeshPredictionSchemeTexCoordsPortableDecoder<
for (int p = 0; p < corner_map_size; ++p) {
const CornerIndex corner_id = this->mesh_data().data_to_corner_map()->at(p);
if (!predictor_.template ComputePredictedValue<false>(corner_id, out_data,
p))
p)) {
return false;
}
const int dst_offset = p * num_components;
this->transform().ComputeOriginalValue(predictor_.predicted_value(),
@ -109,16 +118,19 @@ bool MeshPredictionSchemeTexCoordsPortableDecoder<
*buffer) {
// Decode the delta coded orientations.
int32_t num_orientations = 0;
if (!buffer->Decode(&num_orientations) || num_orientations < 0)
if (!buffer->Decode(&num_orientations) || num_orientations < 0) {
return false;
}
predictor_.ResizeOrientations(num_orientations);
bool last_orientation = true;
RAnsBitDecoder decoder;
if (!decoder.StartDecoding(buffer))
if (!decoder.StartDecoding(buffer)) {
return false;
}
for (int i = 0; i < num_orientations; ++i) {
if (!decoder.DecodeNextBit())
if (!decoder.DecodeNextBit()) {
last_orientation = !last_orientation;
}
predictor_.set_orientation(i, last_orientation);
}
decoder.EndDecoding();

View File

@ -51,10 +51,12 @@ class MeshPredictionSchemeTexCoordsPortableEncoder
}
bool IsInitialized() const override {
if (!predictor_.IsInitialized())
if (!predictor_.IsInitialized()) {
return false;
if (!this->mesh_data().IsInitialized())
}
if (!this->mesh_data().IsInitialized()) {
return false;
}
return true;
}
@ -67,10 +69,12 @@ class MeshPredictionSchemeTexCoordsPortableEncoder
}
bool SetParentAttribute(const PointAttribute *att) override {
if (att->attribute_type() != GeometryAttribute::POSITION)
if (att->attribute_type() != GeometryAttribute::POSITION) {
return false; // Invalid attribute type.
if (att->num_components() != 3)
}
if (att->num_components() != 3) {
return false; // Currently works only for 3 component positions.
}
predictor_.SetPositionAttribute(*att);
return true;
}

View File

@ -16,6 +16,7 @@
#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_PORTABLE_PREDICTOR_H_
#include <math.h>
#include "draco/attributes/point_attribute.h"
#include "draco/core/math_utils.h"
#include "draco/core/vector_d.h"
@ -28,6 +29,8 @@ namespace draco {
template <typename DataTypeT, class MeshDataT>
class MeshPredictionSchemeTexCoordsPortablePredictor {
public:
static constexpr int kNumComponents = 2;
explicit MeshPredictionSchemeTexCoordsPortablePredictor(const MeshDataT &md)
: pos_attribute_(nullptr),
entry_to_point_id_map_(nullptr),
@ -71,7 +74,6 @@ class MeshPredictionSchemeTexCoordsPortablePredictor {
private:
const PointAttribute *pos_attribute_;
const PointIndex *entry_to_point_id_map_;
static constexpr int kNumComponents = 2;
DataTypeT predicted_value_[kNumComponents];
// Encoded / decoded array of UV flips.
// TODO(ostava): We should remove this and replace this with in-place encoding
@ -203,14 +205,16 @@ bool MeshPredictionSchemeTexCoordsPortablePredictor<
}
} else {
// When decoding the data, we already know which orientation to use.
if (orientations_.empty())
if (orientations_.empty()) {
return false;
}
const bool orientation = orientations_.back();
orientations_.pop_back();
if (orientation)
if (orientation) {
predicted_uv = (x_uv + cx_uv) / pn_norm2_squared;
else
} else {
predicted_uv = (x_uv - cx_uv) / pn_norm2_squared;
}
}
predicted_value_[0] = static_cast<int>(predicted_uv[0]);
predicted_value_[1] = static_cast<int>(predicted_uv[1]);

View File

@ -46,8 +46,9 @@ class PredictionSchemeDecoder : public PredictionSchemeTypedDecoderInterface<
: attribute_(attribute), transform_(transform) {}
bool DecodePredictionData(DecoderBuffer *buffer) override {
if (!transform_.DecodeTransformData(buffer))
if (!transform_.DecodeTransformData(buffer)) {
return false;
}
return true;
}

View File

@ -18,9 +18,8 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODER_FACTORY_H_
#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODER_FACTORY_H_
#include "draco/draco_features.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h"
#include "draco/draco_features.h"
#ifdef DRACO_NORMAL_ENCODING_SUPPORTED
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h"
#endif
@ -154,8 +153,9 @@ std::unique_ptr<PredictionSchemeDecoder<DataTypeT, TransformT>>
CreatePredictionSchemeForDecoder(PredictionSchemeMethod method, int att_id,
const PointCloudDecoder *decoder,
const TransformT &transform) {
if (method == PREDICTION_NONE)
if (method == PREDICTION_NONE) {
return nullptr;
}
const PointAttribute *const att = decoder->point_cloud()->attribute(att_id);
if (decoder->GetGeometryType() == TRIANGULAR_MESH) {
// Cast the decoder to mesh decoder. This is not necessarily safe if there
@ -170,8 +170,9 @@ CreatePredictionSchemeForDecoder(PredictionSchemeMethod method, int att_id,
MeshDecoder, PredictionSchemeDecoder<DataTypeT, TransformT>,
MeshPredictionSchemeDecoderFactory<DataTypeT>>(
mesh_decoder, method, att_id, transform, decoder->bitstream_version());
if (ret)
if (ret) {
return ret;
}
// Otherwise try to create another prediction scheme.
}
// Create delta decoder.

View File

@ -46,8 +46,9 @@ class PredictionSchemeEncoder : public PredictionSchemeTypedEncoderInterface<
: attribute_(attribute), transform_(transform) {}
bool EncodePredictionData(EncoderBuffer *buffer) override {
if (!transform_.EncodeTransformData(buffer))
if (!transform_.EncodeTransformData(buffer)) {
return false;
}
return true;
}

View File

@ -62,10 +62,12 @@ PredictionSchemeMethod GetPredictionMethodFromOptions(
int att_id, const EncoderOptions &options) {
const int pred_type =
options.GetAttributeInt(att_id, "prediction_scheme", -1);
if (pred_type == -1)
if (pred_type == -1) {
return PREDICTION_UNDEFINED;
if (pred_type < 0 || pred_type >= NUM_PREDICTION_SCHEMES)
}
if (pred_type < 0 || pred_type >= NUM_PREDICTION_SCHEMES) {
return PREDICTION_NONE;
}
return static_cast<PredictionSchemeMethod>(pred_type);
}

View File

@ -86,8 +86,9 @@ CreatePredictionSchemeForEncoder(PredictionSchemeMethod method, int att_id,
if (method == PREDICTION_UNDEFINED) {
method = SelectPredictionMethod(att_id, encoder);
}
if (method == PREDICTION_NONE)
if (method == PREDICTION_NONE) {
return nullptr; // No prediction is used.
}
if (encoder->GetGeometryType() == TRIANGULAR_MESH) {
// Cast the encoder to mesh encoder. This is not necessarily safe if there
// is some other encoder decides to use TRIANGULAR_MESH as the return type,
@ -100,8 +101,9 @@ CreatePredictionSchemeForEncoder(PredictionSchemeMethod method, int att_id,
MeshEncoder, PredictionSchemeEncoder<DataTypeT, TransformT>,
MeshPredictionSchemeEncoderFactory<DataTypeT>>(
mesh_encoder, method, att_id, transform, kDracoMeshBitstreamVersion);
if (ret)
if (ret) {
return ret;
}
// Otherwise try to create another prediction scheme.
}
// Create delta encoder.

View File

@ -61,8 +61,9 @@ std::unique_ptr<PredictionSchemeT> CreateMeshPredictionScheme(
&encoding_data->vertex_to_encoded_attribute_value_index_map);
MeshPredictionSchemeFactoryT factory;
auto ret = factory(method, att, transform, md, bitstream_version);
if (ret)
if (ret) {
return ret;
}
} else {
typedef MeshPredictionSchemeData<CornerTable> MeshData;
MeshData md;
@ -71,8 +72,9 @@ std::unique_ptr<PredictionSchemeT> CreateMeshPredictionScheme(
&encoding_data->vertex_to_encoded_attribute_value_index_map);
MeshPredictionSchemeFactoryT factory;
auto ret = factory(method, att, transform, md, bitstream_version);
if (ret)
if (ret) {
return ret;
}
}
}
return nullptr;

View File

@ -44,18 +44,23 @@ class PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform
bool DecodeTransformData(DecoderBuffer *buffer) {
DataTypeT max_quantized_value, center_value;
if (!buffer->Decode(&max_quantized_value))
if (!buffer->Decode(&max_quantized_value)) {
return false;
if (!buffer->Decode(&center_value))
}
if (!buffer->Decode(&center_value)) {
return false;
}
(void)center_value;
if (!this->set_max_quantized_value(max_quantized_value))
if (!this->set_max_quantized_value(max_quantized_value)) {
return false;
}
// Account for reading wrong values, e.g., due to fuzzing.
if (this->quantization_bits() < 2)
if (this->quantization_bits() < 2) {
return false;
if (this->quantization_bits() > 30)
}
if (this->quantization_bits() > 30) {
return false;
}
return true;
}

View File

@ -90,8 +90,9 @@ class PredictionSchemeNormalOctahedronCanonicalizedTransformBase
}
bool IsInBottomLeft(const Point2 &p) const {
if (p[0] == 0 && p[1] == 0)
if (p[0] == 0 && p[1] == 0) {
return true;
}
return (p[0] < 0 && p[1] <= 0);
}
};

View File

@ -18,13 +18,12 @@
#include <cmath>
#include "draco/draco_features.h"
#include "draco/compression/attributes/normal_compression_utils.h"
#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h"
#include "draco/core/decoder_buffer.h"
#include "draco/core/macros.h"
#include "draco/core/vector_d.h"
#include "draco/draco_features.h"
namespace draco {
@ -45,11 +44,13 @@ class PredictionSchemeNormalOctahedronDecodingTransform
void Init(int num_components) {}
bool DecodeTransformData(DecoderBuffer *buffer) {
DataTypeT max_quantized_value, center_value;
if (!buffer->Decode(&max_quantized_value))
if (!buffer->Decode(&max_quantized_value)) {
return false;
}
if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
if (!buffer->Decode(&center_value))
if (!buffer->Decode(&center_value)) {
return false;
}
}
(void)center_value;
return this->set_max_quantized_value(max_quantized_value);

View File

@ -60,8 +60,9 @@ class PredictionSchemeNormalOctahedronTransformBase {
protected:
inline bool set_max_quantized_value(DataTypeT max_quantized_value) {
if (max_quantized_value % 2 == 0)
if (max_quantized_value % 2 == 0) {
return false;
}
int q = MostSignificantBit(max_quantized_value) + 1;
return octahedron_tool_box_.SetQuantizationBits(q);
}

View File

@ -39,25 +39,30 @@ class PredictionSchemeWrapDecodingTransform
predicted_vals = this->ClampPredictedValue(predicted_vals);
for (int i = 0; i < this->num_components(); ++i) {
out_original_vals[i] = predicted_vals[i] + corr_vals[i];
if (out_original_vals[i] > this->max_value())
if (out_original_vals[i] > this->max_value()) {
out_original_vals[i] -= this->max_dif();
else if (out_original_vals[i] < this->min_value())
} else if (out_original_vals[i] < this->min_value()) {
out_original_vals[i] += this->max_dif();
}
}
}
bool DecodeTransformData(DecoderBuffer *buffer) {
DataTypeT min_value, max_value;
if (!buffer->Decode(&min_value))
if (!buffer->Decode(&min_value)) {
return false;
if (!buffer->Decode(&max_value))
}
if (!buffer->Decode(&max_value)) {
return false;
if (min_value > max_value)
}
if (min_value > max_value) {
return false;
}
this->set_min_value(min_value);
this->set_max_value(max_value);
if (!this->InitCorrectionBounds())
if (!this->InitCorrectionBounds()) {
return false;
}
return true;
}
};

View File

@ -32,15 +32,17 @@ class PredictionSchemeWrapEncodingTransform
void Init(const DataTypeT *orig_data, int size, int num_components) {
PredictionSchemeWrapTransformBase<DataTypeT>::Init(num_components);
// Go over the original values and compute the bounds.
if (size == 0)
if (size == 0) {
return;
}
DataTypeT min_value = orig_data[0];
DataTypeT max_value = min_value;
for (int i = 1; i < size; ++i) {
if (orig_data[i] < min_value)
if (orig_data[i] < min_value) {
min_value = orig_data[i];
else if (orig_data[i] > max_value)
} else if (orig_data[i] > max_value) {
max_value = orig_data[i];
}
}
this->set_min_value(min_value);
this->set_max_value(max_value);
@ -58,10 +60,11 @@ class PredictionSchemeWrapEncodingTransform
out_corr_vals[i] = original_vals[i] - predicted_vals[i];
// Wrap around if needed.
DataTypeT &corr_val = out_corr_vals[i];
if (corr_val < this->min_correction())
if (corr_val < this->min_correction()) {
corr_val += this->max_dif();
else if (corr_val > this->max_correction())
} else if (corr_val > this->max_correction()) {
corr_val -= this->max_dif();
}
}
}

View File

@ -15,6 +15,7 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_WRAP_TRANSFORM_BASE_H_
#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_WRAP_TRANSFORM_BASE_H_
#include <limits>
#include <vector>
#include "draco/compression/config/compression_shared.h"
@ -61,12 +62,13 @@ class PredictionSchemeWrapTransformBase {
inline const DataTypeT *ClampPredictedValue(
const DataTypeT *predicted_val) const {
for (int i = 0; i < this->num_components(); ++i) {
if (predicted_val[i] > max_value_)
if (predicted_val[i] > max_value_) {
clamped_value_[i] = max_value_;
else if (predicted_val[i] < min_value_)
} else if (predicted_val[i] < min_value_) {
clamped_value_[i] = min_value_;
else
} else {
clamped_value_[i] = predicted_val[i];
}
}
return &clamped_value_[0];
}
@ -81,13 +83,15 @@ class PredictionSchemeWrapTransformBase {
bool InitCorrectionBounds() {
const int64_t dif =
static_cast<int64_t>(max_value_) - static_cast<int64_t>(min_value_);
if (dif < 0 || dif >= std::numeric_limits<DataTypeT>::max())
if (dif < 0 || dif >= std::numeric_limits<DataTypeT>::max()) {
return false;
}
max_dif_ = 1 + static_cast<DataTypeT>(dif);
max_correction_ = max_dif_ / 2;
min_correction_ = -max_correction_;
if ((max_dif_ & 1) == 0)
if ((max_dif_ & 1) == 0) {
max_correction_ -= 1;
}
return true;
}

View File

@ -36,10 +36,13 @@ bool SequentialAttributeDecoder::InitializeStandalone(
bool SequentialAttributeDecoder::DecodePortableAttribute(
const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
if (attribute_->num_components() <= 0 || !attribute_->Reset(point_ids.size()))
if (attribute_->num_components() <= 0 ||
!attribute_->Reset(point_ids.size())) {
return false;
if (!DecodeValues(point_ids, in_buffer))
}
if (!DecodeValues(point_ids, in_buffer)) {
return false;
}
return true;
}
@ -74,8 +77,9 @@ bool SequentialAttributeDecoder::InitPredictionScheme(
for (int i = 0; i < ps->GetNumParentAttributes(); ++i) {
const int att_id = decoder_->point_cloud()->GetNamedAttributeId(
ps->GetParentAttributeType(i));
if (att_id == -1)
if (att_id == -1) {
return false; // Requested attribute does not exist.
}
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
if (!ps->SetParentAttribute(decoder_->point_cloud()->attribute(att_id))) {
@ -102,8 +106,9 @@ bool SequentialAttributeDecoder::DecodeValues(
int out_byte_pos = 0;
// Decode raw attribute values in their original format.
for (int i = 0; i < num_values; ++i) {
if (!in_buffer->Decode(value_data, entry_size))
if (!in_buffer->Decode(value_data, entry_size)) {
return false;
}
attribute_->buffer()->Write(out_byte_pos, value_data, entry_size);
out_byte_pos += entry_size;
}

View File

@ -15,10 +15,9 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_DECODER_H_
#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_DECODER_H_
#include "draco/draco_features.h"
#include "draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h"
#include "draco/compression/point_cloud/point_cloud_decoder.h"
#include "draco/draco_features.h"
namespace draco {

View File

@ -27,36 +27,42 @@ SequentialAttributeDecodersController::SequentialAttributeDecodersController(
bool SequentialAttributeDecodersController::DecodeAttributesDecoderData(
DecoderBuffer *buffer) {
if (!AttributesDecoder::DecodeAttributesDecoderData(buffer))
if (!AttributesDecoder::DecodeAttributesDecoderData(buffer)) {
return false;
}
// Decode unique ids of all sequential encoders and create them.
const int32_t num_attributes = GetNumAttributes();
sequential_decoders_.resize(num_attributes);
for (int i = 0; i < num_attributes; ++i) {
uint8_t decoder_type;
if (!buffer->Decode(&decoder_type))
if (!buffer->Decode(&decoder_type)) {
return false;
}
// Create the decoder from the id.
sequential_decoders_[i] = CreateSequentialDecoder(decoder_type);
if (!sequential_decoders_[i])
if (!sequential_decoders_[i]) {
return false;
if (!sequential_decoders_[i]->Init(GetDecoder(), GetAttributeId(i)))
}
if (!sequential_decoders_[i]->Init(GetDecoder(), GetAttributeId(i))) {
return false;
}
}
return true;
}
bool SequentialAttributeDecodersController::DecodeAttributes(
DecoderBuffer *buffer) {
if (!sequencer_ || !sequencer_->GenerateSequence(&point_ids_))
if (!sequencer_ || !sequencer_->GenerateSequence(&point_ids_)) {
return false;
}
// Initialize point to attribute value mapping for all decoded attributes.
const int32_t num_attributes = GetNumAttributes();
for (int i = 0; i < num_attributes; ++i) {
PointAttribute *const pa =
GetDecoder()->point_cloud()->attribute(GetAttributeId(i));
if (!sequencer_->UpdatePointToAttributeIndexMapping(pa))
if (!sequencer_->UpdatePointToAttributeIndexMapping(pa)) {
return false;
}
}
return AttributesDecoder::DecodeAttributes(buffer);
}
@ -66,8 +72,9 @@ bool SequentialAttributeDecodersController::DecodePortableAttributes(
const int32_t num_attributes = GetNumAttributes();
for (int i = 0; i < num_attributes; ++i) {
if (!sequential_decoders_[i]->DecodePortableAttribute(point_ids_,
in_buffer))
in_buffer)) {
return false;
}
}
return true;
}
@ -77,8 +84,9 @@ bool SequentialAttributeDecodersController::
const int32_t num_attributes = GetNumAttributes();
for (int i = 0; i < num_attributes; ++i) {
if (!sequential_decoders_[i]->DecodeDataNeededByPortableTransform(
point_ids_, in_buffer))
point_ids_, in_buffer)) {
return false;
}
}
return true;
}
@ -106,8 +114,9 @@ bool SequentialAttributeDecodersController::
}
}
if (!sequential_decoders_[i]->TransformAttributeToOriginalFormat(
point_ids_))
point_ids_)) {
return false;
}
}
return true;
}

View File

@ -37,8 +37,9 @@ class SequentialAttributeDecodersController : public AttributesDecoder {
const PointAttribute *GetPortableAttribute(
int32_t point_attribute_id) override {
const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id);
if (loc_id < 0)
if (loc_id < 0) {
return nullptr;
}
return sequential_decoders_[loc_id]->GetPortableAttribute();
}

View File

@ -46,8 +46,9 @@ bool SequentialAttributeEncoder::TransformAttributeToPortableFormat(
bool SequentialAttributeEncoder::EncodePortableAttribute(
const std::vector<PointIndex> &point_ids, EncoderBuffer *out_buffer) {
// Lossless encoding of the input values.
if (!EncodeValues(point_ids, out_buffer))
if (!EncodeValues(point_ids, out_buffer)) {
return false;
}
return true;
}
@ -80,8 +81,9 @@ bool SequentialAttributeEncoder::InitPredictionScheme(
for (int i = 0; i < ps->GetNumParentAttributes(); ++i) {
const int att_id = encoder_->point_cloud()->GetNamedAttributeId(
ps->GetParentAttributeType(i));
if (att_id == -1)
if (att_id == -1) {
return false; // Requested attribute does not exist.
}
parent_attributes_.push_back(att_id);
encoder_->MarkParentAttribute(att_id);
}
@ -93,10 +95,12 @@ bool SequentialAttributeEncoder::SetPredictionSchemeParentAttributes(
for (int i = 0; i < ps->GetNumParentAttributes(); ++i) {
const int att_id = encoder_->point_cloud()->GetNamedAttributeId(
ps->GetParentAttributeType(i));
if (att_id == -1)
if (att_id == -1) {
return false; // Requested attribute does not exist.
if (!ps->SetParentAttribute(encoder_->GetPortableAttribute(att_id)))
}
if (!ps->SetParentAttribute(encoder_->GetPortableAttribute(att_id))) {
return false;
}
}
return true;
}

View File

@ -64,8 +64,9 @@ class SequentialAttributeEncoder {
int GetParentAttributeId(int i) const { return parent_attributes_[i]; }
const PointAttribute *GetPortableAttribute() const {
if (portable_attribute_ != nullptr)
if (portable_attribute_ != nullptr) {
return portable_attribute_.get();
}
return attribute();
}

View File

@ -31,23 +31,27 @@ SequentialAttributeEncodersController::SequentialAttributeEncodersController(
bool SequentialAttributeEncodersController::Init(PointCloudEncoder *encoder,
const PointCloud *pc) {
if (!AttributesEncoder::Init(encoder, pc))
if (!AttributesEncoder::Init(encoder, pc)) {
return false;
if (!CreateSequentialEncoders())
}
if (!CreateSequentialEncoders()) {
return false;
}
// Initialize all value encoders.
for (uint32_t i = 0; i < num_attributes(); ++i) {
const int32_t att_id = GetAttributeId(i);
if (!sequential_encoders_[i]->Init(encoder, att_id))
if (!sequential_encoders_[i]->Init(encoder, att_id)) {
return false;
}
}
return true;
}
bool SequentialAttributeEncodersController::EncodeAttributesEncoderData(
EncoderBuffer *out_buffer) {
if (!AttributesEncoder::EncodeAttributesEncoderData(out_buffer))
if (!AttributesEncoder::EncodeAttributesEncoderData(out_buffer)) {
return false;
}
// Encode a unique id of every sequential encoder.
for (uint32_t i = 0; i < sequential_encoders_.size(); ++i) {
out_buffer->Encode(sequential_encoders_[i]->GetUniqueId());
@ -57,8 +61,9 @@ bool SequentialAttributeEncodersController::EncodeAttributesEncoderData(
bool SequentialAttributeEncodersController::EncodeAttributes(
EncoderBuffer *buffer) {
if (!sequencer_ || !sequencer_->GenerateSequence(&point_ids_))
if (!sequencer_ || !sequencer_->GenerateSequence(&point_ids_)) {
return false;
}
return AttributesEncoder::EncodeAttributes(buffer);
}
@ -66,8 +71,9 @@ bool SequentialAttributeEncodersController::
TransformAttributesToPortableFormat() {
for (uint32_t i = 0; i < sequential_encoders_.size(); ++i) {
if (!sequential_encoders_[i]->TransformAttributeToPortableFormat(
point_ids_))
point_ids_)) {
return false;
}
}
return true;
}
@ -76,8 +82,9 @@ bool SequentialAttributeEncodersController::EncodePortableAttributes(
EncoderBuffer *out_buffer) {
for (uint32_t i = 0; i < sequential_encoders_.size(); ++i) {
if (!sequential_encoders_[i]->EncodePortableAttribute(point_ids_,
out_buffer))
out_buffer)) {
return false;
}
}
return true;
}
@ -86,8 +93,9 @@ bool SequentialAttributeEncodersController::
EncodeDataNeededByPortableTransforms(EncoderBuffer *out_buffer) {
for (uint32_t i = 0; i < sequential_encoders_.size(); ++i) {
if (!sequential_encoders_[i]->EncodeDataNeededByPortableTransform(
out_buffer))
out_buffer)) {
return false;
}
}
return true;
}
@ -96,11 +104,13 @@ bool SequentialAttributeEncodersController::CreateSequentialEncoders() {
sequential_encoders_.resize(num_attributes());
for (uint32_t i = 0; i < num_attributes(); ++i) {
sequential_encoders_[i] = CreateSequentialEncoder(i);
if (sequential_encoders_[i] == nullptr)
if (sequential_encoders_[i] == nullptr) {
return false;
}
if (i < sequential_encoder_marked_as_parent_.size()) {
if (sequential_encoder_marked_as_parent_[i])
if (sequential_encoder_marked_as_parent_[i]) {
sequential_encoders_[i]->MarkParentAttribute();
}
}
}
return true;

View File

@ -42,23 +42,26 @@ class SequentialAttributeEncodersController : public AttributesEncoder {
int NumParentAttributes(int32_t point_attribute_id) const override {
const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id);
if (loc_id < 0)
if (loc_id < 0) {
return 0;
}
return sequential_encoders_[loc_id]->NumParentAttributes();
}
int GetParentAttributeId(int32_t point_attribute_id,
int32_t parent_i) const override {
const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id);
if (loc_id < 0)
if (loc_id < 0) {
return -1;
}
return sequential_encoders_[loc_id]->GetParentAttributeId(parent_i);
}
bool MarkParentAttribute(int32_t point_attribute_id) override {
const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id);
if (loc_id < 0)
if (loc_id < 0) {
return false;
}
// Mark the attribute encoder as parent (even when if it is not created
// yet).
if (sequential_encoder_marked_as_parent_.size() <= loc_id) {
@ -66,8 +69,9 @@ class SequentialAttributeEncodersController : public AttributesEncoder {
}
sequential_encoder_marked_as_parent_[loc_id] = true;
if (sequential_encoders_.size() <= loc_id)
if (sequential_encoders_.size() <= loc_id) {
return true; // Sequential encoders not generated yet.
}
sequential_encoders_[loc_id]->MarkParentAttribute();
return true;
}
@ -75,8 +79,9 @@ class SequentialAttributeEncodersController : public AttributesEncoder {
const PointAttribute *GetPortableAttribute(
int32_t point_attribute_id) override {
const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id);
if (loc_id < 0)
if (loc_id < 0) {
return nullptr;
}
return sequential_encoders_[loc_id]->GetPortableAttribute();
}

View File

@ -24,8 +24,9 @@ SequentialIntegerAttributeDecoder::SequentialIntegerAttributeDecoder() {}
bool SequentialIntegerAttributeDecoder::Init(PointCloudDecoder *decoder,
int attribute_id) {
if (!SequentialAttributeDecoder::Init(decoder, attribute_id))
if (!SequentialAttributeDecoder::Init(decoder, attribute_id)) {
return false;
}
return true;
}
@ -33,8 +34,9 @@ bool SequentialIntegerAttributeDecoder::TransformAttributeToOriginalFormat(
const std::vector<PointIndex> &point_ids) {
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder() &&
decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0))
decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
return true; // Don't revert the transform here for older files.
}
#endif
return StoreValues(static_cast<uint32_t>(point_ids.size()));
}
@ -43,30 +45,37 @@ bool SequentialIntegerAttributeDecoder::DecodeValues(
const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
// Decode prediction scheme.
int8_t prediction_scheme_method;
in_buffer->Decode(&prediction_scheme_method);
if (!in_buffer->Decode(&prediction_scheme_method)) {
return false;
}
if (prediction_scheme_method != PREDICTION_NONE) {
int8_t prediction_transform_type;
in_buffer->Decode(&prediction_transform_type);
if (!in_buffer->Decode(&prediction_transform_type)) {
return false;
}
prediction_scheme_ = CreateIntPredictionScheme(
static_cast<PredictionSchemeMethod>(prediction_scheme_method),
static_cast<PredictionSchemeTransformType>(prediction_transform_type));
}
if (prediction_scheme_) {
if (!InitPredictionScheme(prediction_scheme_.get()))
if (!InitPredictionScheme(prediction_scheme_.get())) {
return false;
}
}
if (!DecodeIntegerValues(point_ids, in_buffer))
if (!DecodeIntegerValues(point_ids, in_buffer)) {
return false;
}
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
const int32_t num_values = static_cast<uint32_t>(point_ids.size());
if (decoder() &&
decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
// For older files, revert the transform right after we decode the data.
if (!StoreValues(num_values))
if (!StoreValues(num_values)) {
return false;
}
}
#endif
return true;
@ -76,8 +85,9 @@ std::unique_ptr<PredictionSchemeTypedDecoderInterface<int32_t>>
SequentialIntegerAttributeDecoder::CreateIntPredictionScheme(
PredictionSchemeMethod method,
PredictionSchemeTransformType transform_type) {
if (transform_type != PREDICTION_TRANSFORM_WRAP)
if (transform_type != PREDICTION_TRANSFORM_WRAP) {
return nullptr; // For now we support only wrap transform.
}
return CreatePredictionSchemeForDecoder<
int32_t, PredictionSchemeWrapDecodingTransform<int32_t>>(
method, attribute_id(), decoder());
@ -86,44 +96,55 @@ SequentialIntegerAttributeDecoder::CreateIntPredictionScheme(
bool SequentialIntegerAttributeDecoder::DecodeIntegerValues(
const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
const int num_components = GetNumValueComponents();
if (num_components <= 0)
if (num_components <= 0) {
return false;
}
const size_t num_entries = point_ids.size();
const size_t num_values = num_entries * num_components;
PreparePortableAttribute(static_cast<int>(num_entries), num_components);
int32_t *const portable_attribute_data = GetPortableAttributeData();
if (portable_attribute_data == nullptr)
if (portable_attribute_data == nullptr) {
return false;
}
uint8_t compressed;
if (!in_buffer->Decode(&compressed))
if (!in_buffer->Decode(&compressed)) {
return false;
}
if (compressed > 0) {
// Decode compressed values.
if (!DecodeSymbols(static_cast<uint32_t>(num_values), num_components,
in_buffer,
reinterpret_cast<uint32_t *>(portable_attribute_data)))
reinterpret_cast<uint32_t *>(portable_attribute_data))) {
return false;
}
} else {
// Decode the integer data directly.
// Get the number of bytes for a given entry.
uint8_t num_bytes;
if (!in_buffer->Decode(&num_bytes))
if (!in_buffer->Decode(&num_bytes)) {
return false;
}
if (num_bytes == DataTypeLength(DT_INT32)) {
if (portable_attribute()->buffer()->data_size() <
sizeof(int32_t) * num_values)
sizeof(int32_t) * num_values) {
return false;
}
if (!in_buffer->Decode(portable_attribute_data,
sizeof(int32_t) * num_values))
sizeof(int32_t) * num_values)) {
return false;
}
} else {
if (portable_attribute()->buffer()->data_size() < num_bytes * num_values)
if (portable_attribute()->buffer()->data_size() <
num_bytes * num_values) {
return false;
}
if (in_buffer->remaining_size() <
static_cast<int64_t>(num_bytes) * static_cast<int64_t>(num_values))
static_cast<int64_t>(num_bytes) * static_cast<int64_t>(num_values)) {
return false;
}
for (size_t i = 0; i < num_values; ++i) {
in_buffer->Decode(portable_attribute_data + i, num_bytes);
if (!in_buffer->Decode(portable_attribute_data + i, num_bytes))
return false;
}
}
}
@ -138,8 +159,9 @@ bool SequentialIntegerAttributeDecoder::DecodeIntegerValues(
// If the data was encoded with a prediction scheme, we must revert it.
if (prediction_scheme_) {
if (!prediction_scheme_->DecodePredictionData(in_buffer))
if (!prediction_scheme_->DecodePredictionData(in_buffer)) {
return false;
}
if (num_values > 0) {
if (!prediction_scheme_->ComputeOriginalValues(

View File

@ -15,10 +15,9 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_INTEGER_ATTRIBUTE_DECODER_H_
#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_INTEGER_ATTRIBUTE_DECODER_H_
#include "draco/draco_features.h"
#include "draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h"
#include "draco/compression/attributes/sequential_attribute_decoder.h"
#include "draco/draco_features.h"
namespace draco {
@ -56,8 +55,9 @@ class SequentialIntegerAttributeDecoder : public SequentialAttributeDecoder {
void PreparePortableAttribute(int num_entries, int num_components);
int32_t *GetPortableAttributeData() {
if (portable_attribute()->size() == 0)
if (portable_attribute()->size() == 0) {
return nullptr;
}
return reinterpret_cast<int32_t *>(
portable_attribute()->GetAddress(AttributeValueIndex(0)));
}

View File

@ -25,8 +25,9 @@ SequentialIntegerAttributeEncoder::SequentialIntegerAttributeEncoder() {}
bool SequentialIntegerAttributeEncoder::Init(PointCloudEncoder *encoder,
int attribute_id) {
if (!SequentialAttributeEncoder::Init(encoder, attribute_id))
if (!SequentialAttributeEncoder::Init(encoder, attribute_id)) {
return false;
}
if (GetUniqueId() == SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER) {
// When encoding integers, this encoder currently works only for integer
// attributes up to 32 bits.
@ -58,11 +59,13 @@ bool SequentialIntegerAttributeEncoder::Init(PointCloudEncoder *encoder,
bool SequentialIntegerAttributeEncoder::TransformAttributeToPortableFormat(
const std::vector<PointIndex> &point_ids) {
if (encoder()) {
if (!PrepareValues(point_ids, encoder()->point_cloud()->num_points()))
if (!PrepareValues(point_ids, encoder()->point_cloud()->num_points())) {
return false;
}
} else {
if (!PrepareValues(point_ids, 0))
if (!PrepareValues(point_ids, 0)) {
return false;
}
}
// Update point to attribute mapping with the portable attribute if the
@ -100,8 +103,9 @@ bool SequentialIntegerAttributeEncoder::EncodeValues(
const std::vector<PointIndex> &point_ids, EncoderBuffer *out_buffer) {
// Initialize general quantization data.
const PointAttribute *const attrib = attribute();
if (attrib->size() == 0)
if (attrib->size() == 0) {
return true;
}
int8_t prediction_scheme_method = PREDICTION_NONE;
if (prediction_scheme_) {
@ -202,8 +206,9 @@ bool SequentialIntegerAttributeEncoder::PrepareValues(
for (PointIndex pi : point_ids) {
const AttributeValueIndex att_id = attrib->mapped_index(pi);
if (!attrib->ConvertValue<int32_t>(att_id,
portable_attribute_data + dst_index))
portable_attribute_data + dst_index)) {
return false;
}
dst_index += num_components;
}
return true;

View File

@ -13,6 +13,7 @@
// limitations under the License.
//
#include "draco/compression/attributes/sequential_normal_attribute_decoder.h"
#include "draco/attributes/attribute_octahedron_transform.h"
#include "draco/compression/attributes/normal_compression_utils.h"
@ -26,11 +27,13 @@ bool SequentialNormalAttributeDecoder::Init(PointCloudDecoder *decoder,
if (!SequentialIntegerAttributeDecoder::Init(decoder, attribute_id))
return false;
// Currently, this encoder works only for 3-component normal vectors.
if (attribute()->num_components() != 3)
if (attribute()->num_components() != 3) {
return false;
}
// Also the data type must be DT_FLOAT32.
if (attribute()->data_type() != DT_FLOAT32)
if (attribute()->data_type() != DT_FLOAT32) {
return false;
}
return true;
}
@ -39,8 +42,9 @@ bool SequentialNormalAttributeDecoder::DecodeIntegerValues(
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
uint8_t quantization_bits;
if (!in_buffer->Decode(&quantization_bits))
if (!in_buffer->Decode(&quantization_bits)) {
return false;
}
quantization_bits_ = quantization_bits;
}
#endif
@ -53,8 +57,9 @@ bool SequentialNormalAttributeDecoder::DecodeDataNeededByPortableTransform(
if (decoder()->bitstream_version() >= DRACO_BITSTREAM_VERSION(2, 0)) {
// For newer file version, decode attribute transform data here.
uint8_t quantization_bits;
if (!in_buffer->Decode(&quantization_bits))
if (!in_buffer->Decode(&quantization_bits)) {
return false;
}
quantization_bits_ = quantization_bits;
}

View File

@ -15,12 +15,11 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_NORMAL_ATTRIBUTE_DECODER_H_
#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_NORMAL_ATTRIBUTE_DECODER_H_
#include "draco/draco_features.h"
#include "draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h"
#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h"
#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h"
#include "draco/compression/attributes/sequential_integer_attribute_decoder.h"
#include "draco/draco_features.h"
namespace draco {

View File

@ -13,6 +13,7 @@
// limitations under the License.
//
#include "draco/compression/attributes/sequential_normal_attribute_encoder.h"
#include "draco/compression/attributes/normal_compression_utils.h"
namespace draco {
@ -22,14 +23,16 @@ bool SequentialNormalAttributeEncoder::Init(PointCloudEncoder *encoder,
if (!SequentialIntegerAttributeEncoder::Init(encoder, attribute_id))
return false;
// Currently this encoder works only for 3-component normal vectors.
if (attribute()->num_components() != 3)
if (attribute()->num_components() != 3) {
return false;
}
// Initialize AttributeOctahedronTransform.
const int quantization_bits = encoder->options()->GetAttributeInt(
attribute_id, "quantization_bits", -1);
if (quantization_bits < 1)
if (quantization_bits < 1) {
return false;
}
attribute_octahedron_transform_.SetParameters(quantization_bits);
return true;
}

View File

@ -24,13 +24,15 @@ SequentialQuantizationAttributeDecoder::SequentialQuantizationAttributeDecoder()
bool SequentialQuantizationAttributeDecoder::Init(PointCloudDecoder *decoder,
int attribute_id) {
if (!SequentialIntegerAttributeDecoder::Init(decoder, attribute_id))
if (!SequentialIntegerAttributeDecoder::Init(decoder, attribute_id)) {
return false;
}
const PointAttribute *const attribute =
decoder->point_cloud()->attribute(attribute_id);
// Currently we can quantize only floating point arguments.
if (attribute->data_type() != DT_FLOAT32)
if (attribute->data_type() != DT_FLOAT32) {
return false;
}
return true;
}
@ -38,8 +40,9 @@ bool SequentialQuantizationAttributeDecoder::DecodeIntegerValues(
const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0) &&
!DecodeQuantizedDataInfo())
!DecodeQuantizedDataInfo()) {
return false;
}
#endif
return SequentialIntegerAttributeDecoder::DecodeIntegerValues(point_ids,
in_buffer);
@ -50,8 +53,9 @@ bool SequentialQuantizationAttributeDecoder::
const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
if (decoder()->bitstream_version() >= DRACO_BITSTREAM_VERSION(2, 0)) {
// Decode quantization data here only for files with bitstream version 2.0+
if (!DecodeQuantizedDataInfo())
if (!DecodeQuantizedDataInfo()) {
return false;
}
}
// Store the decoded transform data in portable attribute;
@ -69,14 +73,17 @@ bool SequentialQuantizationAttributeDecoder::DecodeQuantizedDataInfo() {
const int num_components = attribute()->num_components();
min_value_ = std::unique_ptr<float[]>(new float[num_components]);
if (!decoder()->buffer()->Decode(min_value_.get(),
sizeof(float) * num_components))
sizeof(float) * num_components)) {
return false;
if (!decoder()->buffer()->Decode(&max_value_dif_))
}
if (!decoder()->buffer()->Decode(&max_value_dif_)) {
return false;
}
uint8_t quantization_bits;
if (!decoder()->buffer()->Decode(&quantization_bits) ||
quantization_bits > 31)
quantization_bits > 31) {
return false;
}
quantization_bits_ = quantization_bits;
return true;
}
@ -92,8 +99,9 @@ bool SequentialQuantizationAttributeDecoder::DequantizeValues(
int quant_val_id = 0;
int out_byte_pos = 0;
Dequantizer dequantizer;
if (!dequantizer.Init(max_value_dif_, max_quantized_value))
if (!dequantizer.Init(max_value_dif_, max_quantized_value)) {
return false;
}
const int32_t *const portable_attribute_data = GetPortableAttributeData();
for (uint32_t i = 0; i < num_values; ++i) {
for (int c = 0; c < num_components; ++c) {

View File

@ -15,9 +15,8 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_QUANTIZATION_ATTRIBUTE_DECODER_H_
#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_QUANTIZATION_ATTRIBUTE_DECODER_H_
#include "draco/draco_features.h"
#include "draco/compression/attributes/sequential_integer_attribute_decoder.h"
#include "draco/draco_features.h"
namespace draco {

View File

@ -23,19 +23,22 @@ SequentialQuantizationAttributeEncoder::
bool SequentialQuantizationAttributeEncoder::Init(PointCloudEncoder *encoder,
int attribute_id) {
if (!SequentialIntegerAttributeEncoder::Init(encoder, attribute_id))
if (!SequentialIntegerAttributeEncoder::Init(encoder, attribute_id)) {
return false;
}
// This encoder currently works only for floating point attributes.
const PointAttribute *const attribute =
encoder->point_cloud()->attribute(attribute_id);
if (attribute->data_type() != DT_FLOAT32)
if (attribute->data_type() != DT_FLOAT32) {
return false;
}
// Initialize AttributeQuantizationTransform.
const int quantization_bits = encoder->options()->GetAttributeInt(
attribute_id, "quantization_bits", -1);
if (quantization_bits < 1)
if (quantization_bits < 1) {
return false;
}
if (encoder->options()->IsAttributeOptionSet(attribute_id,
"quantization_origin") &&
encoder->options()->IsAttributeOptionSet(attribute_id,
@ -52,8 +55,10 @@ bool SequentialQuantizationAttributeEncoder::Init(PointCloudEncoder *encoder,
attribute->num_components(), range);
} else {
// Compute quantization settings from the attribute values.
attribute_quantization_transform_.ComputeParameters(*attribute,
quantization_bits);
if (!attribute_quantization_transform_.ComputeParameters(
*attribute, quantization_bits)) {
return false;
}
}
return true;
}

Some files were not shown because too many files have changed in this diff Show More