diff options
Diffstat (limited to 'extern/draco/draco/src/draco/compression/attributes/prediction_schemes')
9 files changed, 74 insertions, 18 deletions
diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h index f712952556a..2960a5e71b4 100644 --- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h +++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. // -#ifndef DRACO_COMPRESSION_ATTRIBUTES_MESH_PREDICTION_SCHEMES_PREDICTION_SCHEME_DATA_H_ -#define DRACO_COMPRESSION_ATTRIBUTES_MESH_PREDICTION_SCHEMES_PREDICTION_SCHEME_DATA_H_ +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_DATA_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_DATA_H_ #include "draco/mesh/corner_table.h" #include "draco/mesh/mesh.h" diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h index bf1a6146111..775eded6b55 100644 --- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h +++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h @@ -69,7 +69,14 @@ class MeshPredictionSchemeGeometricNormalPredictorArea // Computing cross product. const VectorD<int64_t, 3> cross = CrossProduct(delta_next, delta_prev); - normal = normal + cross; + + // Prevent signed integer overflows by doing math as unsigned. + auto normal_data = reinterpret_cast<uint64_t *>(normal.data()); + auto cross_data = reinterpret_cast<const uint64_t *>(cross.data()); + normal_data[0] = normal_data[0] + cross_data[0]; + normal_data[1] = normal_data[1] + cross_data[1]; + normal_data[2] = normal_data[2] + cross_data[2]; + cit.Next(); } diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h index 485d457ccf6..fd10fb524b3 100644 --- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h +++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h @@ -60,8 +60,13 @@ inline bool ComputeParallelogramPrediction( const int v_next_off = vert_next * num_components; const int v_prev_off = vert_prev * num_components; for (int c = 0; c < num_components; ++c) { - out_prediction[c] = (in_data[v_next_off + c] + in_data[v_prev_off + c]) - - in_data[v_opp_off + c]; + const int64_t in_data_next_off = in_data[v_next_off + c]; + const int64_t in_data_prev_off = in_data[v_prev_off + c]; + const int64_t in_data_opp_off = in_data[v_opp_off + c]; + const int64_t result = + (in_data_next_off + in_data_prev_off) - in_data_opp_off; + + out_prediction[c] = static_cast<DataTypeT>(result); } return true; } diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h index 5d8a5060133..f05e5ddd713 100644 --- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h +++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h @@ -156,6 +156,13 @@ bool MeshPredictionSchemeTexCoordsPortablePredictor< const VectorD<int64_t, 2> x_uv = n_uv * pn_norm2_squared + (cn_dot_pn * pn_uv); + const int64_t pn_absmax_element = + std::max(std::max(std::abs(pn[0]), std::abs(pn[1])), std::abs(pn[2])); + if (cn_dot_pn > std::numeric_limits<int64_t>::max() / pn_absmax_element) { + // return false if squared length calculation would overflow. + return false; + } + // Compute squared length of vector CX in position coordinate system: const VectorD<int64_t, 3> x_pos = next_pos + (cn_dot_pn * pn) / pn_norm2_squared; diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc index 428340da013..60429d5c779 100644 --- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc +++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc @@ -18,34 +18,51 @@ namespace draco { PredictionSchemeMethod SelectPredictionMethod( int att_id, const PointCloudEncoder *encoder) { - if (encoder->options()->GetSpeed() >= 10) { + return SelectPredictionMethod(att_id, *encoder->options(), encoder); +} + +PredictionSchemeMethod SelectPredictionMethod( + int att_id, const EncoderOptions &options, + const PointCloudEncoder *encoder) { + if (options.GetSpeed() >= 10) { // Selected fastest, though still doing some compression. return PREDICTION_DIFFERENCE; } if (encoder->GetGeometryType() == TRIANGULAR_MESH) { // Use speed setting to select the best encoding method. const PointAttribute *const att = encoder->point_cloud()->attribute(att_id); - if (att->attribute_type() == GeometryAttribute::TEX_COORD) { - if (encoder->options()->GetSpeed() < 4) { + if (att->attribute_type() == GeometryAttribute::TEX_COORD && + att->num_components() == 2) { + if (options.GetSpeed() < 4) { // Use texture coordinate prediction for speeds 0, 1, 2, 3. return MESH_PREDICTION_TEX_COORDS_PORTABLE; } } if (att->attribute_type() == GeometryAttribute::NORMAL) { #ifdef DRACO_NORMAL_ENCODING_SUPPORTED - if (encoder->options()->GetSpeed() < 4) { + if (options.GetSpeed() < 4) { // Use geometric normal prediction for speeds 0, 1, 2, 3. - return MESH_PREDICTION_GEOMETRIC_NORMAL; + // For this prediction, the position attribute needs to be either + // integer or quantized as well. + const int pos_att_id = encoder->point_cloud()->GetNamedAttributeId( + GeometryAttribute::POSITION); + const PointAttribute *const pos_att = + encoder->point_cloud()->GetNamedAttribute( + GeometryAttribute::POSITION); + if (pos_att && (IsDataTypeIntegral(pos_att->data_type()) || + options.GetAttributeInt(pos_att_id, "quantization_bits", + -1) > 0)) { + return MESH_PREDICTION_GEOMETRIC_NORMAL; + } } #endif return PREDICTION_DIFFERENCE; // default } // Handle other attribute types. - if (encoder->options()->GetSpeed() >= 8) { + if (options.GetSpeed() >= 8) { return PREDICTION_DIFFERENCE; } - if (encoder->options()->GetSpeed() >= 2 || - encoder->point_cloud()->num_points() < 40) { + if (options.GetSpeed() >= 2 || encoder->point_cloud()->num_points() < 40) { // Parallelogram prediction is used for speeds 2 - 7 or when the overhead // of using constrained multi-parallelogram would be too high. return MESH_PREDICTION_PARALLELOGRAM; diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h index 40a7683aa0d..b7e21224fad 100644 --- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h +++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h @@ -38,6 +38,10 @@ namespace draco { PredictionSchemeMethod SelectPredictionMethod(int att_id, const PointCloudEncoder *encoder); +PredictionSchemeMethod SelectPredictionMethod(int att_id, + const EncoderOptions &options, + const PointCloudEncoder *encoder); + // Factory class for creating mesh prediction schemes. template <typename DataTypeT> struct MeshPredictionSchemeEncoderFactory { diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h index ab64bce7114..37aa9f76a9c 100644 --- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h +++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. // -#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODING_INTERFACE_H_ -#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODING_INTERFACE_H_ +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_INTERFACE_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_INTERFACE_H_ #include "draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h" #include "draco/core/encoder_buffer.h" @@ -52,4 +52,4 @@ class PredictionSchemeTypedEncoderInterface } // namespace draco -#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODING_INTERFACE_H_ +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_INTERFACE_H_ diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h index 0a14d0d9ba4..e100c738a6c 100644 --- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h +++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h @@ -36,9 +36,25 @@ class PredictionSchemeWrapDecodingTransform inline void ComputeOriginalValue(const DataTypeT *predicted_vals, const CorrTypeT *corr_vals, DataTypeT *out_original_vals) const { + // For now we assume both |DataTypeT| and |CorrTypeT| are equal. + static_assert(std::is_same<DataTypeT, CorrTypeT>::value, + "Predictions and corrections must have the same type."); + + // The only valid implementation right now is for int32_t. + static_assert(std::is_same<DataTypeT, int32_t>::value, + "Only int32_t is supported for predicted values."); + predicted_vals = this->ClampPredictedValue(predicted_vals); + + // Perform the wrapping using unsigned coordinates to avoid potential signed + // integer overflows caused by malformed input. + const uint32_t *const uint_predicted_vals = + reinterpret_cast<const uint32_t *>(predicted_vals); + const uint32_t *const uint_corr_vals = + reinterpret_cast<const uint32_t *>(corr_vals); for (int i = 0; i < this->num_components(); ++i) { - out_original_vals[i] = predicted_vals[i] + corr_vals[i]; + out_original_vals[i] = + static_cast<DataTypeT>(uint_predicted_vals[i] + uint_corr_vals[i]); if (out_original_vals[i] > this->max_value()) { out_original_vals[i] -= this->max_dif(); } else if (out_original_vals[i] < this->min_value()) { diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h index 26f61fbaf6a..979c63c3d11 100644 --- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h +++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h @@ -73,7 +73,7 @@ class PredictionSchemeWrapTransformBase { return &clamped_value_[0]; } - // TODO(hemmer): Consider refactoring to avoid this dummy. + // TODO(b/199760123): Consider refactoring to avoid this dummy. int quantization_bits() const { DRACO_DCHECK(false); return -1; |