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:
parent
fb82cfb539
commit
3012446f02
|
@ -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}")
|
||||
|
|
|
@ -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}")
|
||||
|
|
@ -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),
|
||||
×tamp[i.value()]);
|
|
@ -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),
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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);
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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.
|
|
@ -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());
|
|
@ -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;
|
|
@ -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;
|
|
@ -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];
|
||||
}
|
||||
|
|
@ -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)));
|
|
@ -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.
|
|
@ -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);
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 {
|
|
@ -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();
|
||||
}
|
|
@ -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];
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
@ -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);
|
|
@ -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();
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
|
@ -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;
|
||||
}
|
|
@ -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]);
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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.
|
|
@ -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;
|
|
@ -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(¢er_value))
|
||||
}
|
||||
if (!buffer->Decode(¢er_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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
};
|
|
@ -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(¢er_value))
|
||||
if (!buffer->Decode(¢er_value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
(void)center_value;
|
||||
return this->set_max_quantized_value(max_quantized_value);
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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 {
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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;
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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(
|
|
@ -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)));
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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) {
|
|
@ -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 {
|
||||
|
|
@ -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
Loading…
Reference in New Issue