Differential D9642 Diff 31697 extern/draco/draco/src/draco/compression/mesh/mesh_sequential_decoder.cc
Changeset View
Changeset View
Standalone View
Standalone View
extern/draco/draco/src/draco/compression/mesh/mesh_sequential_decoder.cc
- This file was moved from extern/draco/dracoenc/src/draco/compression/mesh/mesh_sequential_decoder.cc.
| Show All 22 Lines | |||||
| MeshSequentialDecoder::MeshSequentialDecoder() {} | MeshSequentialDecoder::MeshSequentialDecoder() {} | ||||
| bool MeshSequentialDecoder::DecodeConnectivity() { | bool MeshSequentialDecoder::DecodeConnectivity() { | ||||
| uint32_t num_faces; | uint32_t num_faces; | ||||
| uint32_t num_points; | uint32_t num_points; | ||||
| #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED | #ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED | ||||
| if (bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) { | if (bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) { | ||||
| if (!buffer()->Decode(&num_faces)) | if (!buffer()->Decode(&num_faces)) { | ||||
| return false; | return false; | ||||
| if (!buffer()->Decode(&num_points)) | } | ||||
| if (!buffer()->Decode(&num_points)) { | |||||
| return false; | return false; | ||||
| } | |||||
| } else | } else | ||||
| #endif | #endif | ||||
| { | { | ||||
| if (!DecodeVarint(&num_faces, buffer())) | if (!DecodeVarint(&num_faces, buffer())) { | ||||
| return false; | return false; | ||||
| if (!DecodeVarint(&num_points, buffer())) | } | ||||
| if (!DecodeVarint(&num_points, buffer())) { | |||||
| return false; | return false; | ||||
| } | } | ||||
| } | |||||
| // Check that num_faces and num_points are valid values. | // Check that num_faces and num_points are valid values. | ||||
| const uint64_t faces_64 = static_cast<uint64_t>(num_faces); | const uint64_t faces_64 = static_cast<uint64_t>(num_faces); | ||||
| const uint64_t points_64 = static_cast<uint64_t>(num_points); | const uint64_t points_64 = static_cast<uint64_t>(num_points); | ||||
| // Compressed sequential encoding can only handle (2^32 - 1) / 3 indices. | // Compressed sequential encoding can only handle (2^32 - 1) / 3 indices. | ||||
| if (faces_64 > 0xffffffff / 3) | if (faces_64 > 0xffffffff / 3) { | ||||
| return false; | return false; | ||||
| if (points_64 > faces_64 * 3) | } | ||||
| if (points_64 > faces_64 * 3) { | |||||
| return false; | return false; | ||||
| } | |||||
| uint8_t connectivity_method; | uint8_t connectivity_method; | ||||
| if (!buffer()->Decode(&connectivity_method)) | if (!buffer()->Decode(&connectivity_method)) { | ||||
| return false; | return false; | ||||
| } | |||||
| if (connectivity_method == 0) { | if (connectivity_method == 0) { | ||||
| if (!DecodeAndDecompressIndices(num_faces)) | if (!DecodeAndDecompressIndices(num_faces)) { | ||||
| return false; | return false; | ||||
| } | |||||
| } else { | } else { | ||||
| if (num_points < 256) { | if (num_points < 256) { | ||||
| // Decode indices as uint8_t. | // Decode indices as uint8_t. | ||||
| for (uint32_t i = 0; i < num_faces; ++i) { | for (uint32_t i = 0; i < num_faces; ++i) { | ||||
| Mesh::Face face; | Mesh::Face face; | ||||
| for (int j = 0; j < 3; ++j) { | for (int j = 0; j < 3; ++j) { | ||||
| uint8_t val; | uint8_t val; | ||||
| if (!buffer()->Decode(&val)) | if (!buffer()->Decode(&val)) { | ||||
| return false; | return false; | ||||
| } | |||||
| face[j] = val; | face[j] = val; | ||||
| } | } | ||||
| mesh()->AddFace(face); | mesh()->AddFace(face); | ||||
| } | } | ||||
| } else if (num_points < (1 << 16)) { | } else if (num_points < (1 << 16)) { | ||||
| // Decode indices as uint16_t. | // Decode indices as uint16_t. | ||||
| for (uint32_t i = 0; i < num_faces; ++i) { | for (uint32_t i = 0; i < num_faces; ++i) { | ||||
| Mesh::Face face; | Mesh::Face face; | ||||
| for (int j = 0; j < 3; ++j) { | for (int j = 0; j < 3; ++j) { | ||||
| uint16_t val; | uint16_t val; | ||||
| if (!buffer()->Decode(&val)) | if (!buffer()->Decode(&val)) { | ||||
| return false; | return false; | ||||
| } | |||||
| face[j] = val; | face[j] = val; | ||||
| } | } | ||||
| mesh()->AddFace(face); | mesh()->AddFace(face); | ||||
| } | } | ||||
| } else if (mesh()->num_points() < (1 << 21) && | } else if (mesh()->num_points() < (1 << 21) && | ||||
| bitstream_version() >= DRACO_BITSTREAM_VERSION(2, 2)) { | bitstream_version() >= DRACO_BITSTREAM_VERSION(2, 2)) { | ||||
| // Decode indices as uint32_t. | // Decode indices as uint32_t. | ||||
| for (uint32_t i = 0; i < num_faces; ++i) { | for (uint32_t i = 0; i < num_faces; ++i) { | ||||
| Mesh::Face face; | Mesh::Face face; | ||||
| for (int j = 0; j < 3; ++j) { | for (int j = 0; j < 3; ++j) { | ||||
| uint32_t val; | uint32_t val; | ||||
| if (!DecodeVarint(&val, buffer())) | if (!DecodeVarint(&val, buffer())) { | ||||
| return false; | return false; | ||||
| } | |||||
| face[j] = val; | face[j] = val; | ||||
| } | } | ||||
| mesh()->AddFace(face); | mesh()->AddFace(face); | ||||
| } | } | ||||
| } else { | } else { | ||||
| // Decode faces as uint32_t (default). | // Decode faces as uint32_t (default). | ||||
| for (uint32_t i = 0; i < num_faces; ++i) { | for (uint32_t i = 0; i < num_faces; ++i) { | ||||
| Mesh::Face face; | Mesh::Face face; | ||||
| for (int j = 0; j < 3; ++j) { | for (int j = 0; j < 3; ++j) { | ||||
| uint32_t val; | uint32_t val; | ||||
| if (!buffer()->Decode(&val)) | if (!buffer()->Decode(&val)) { | ||||
| return false; | return false; | ||||
| } | |||||
| face[j] = val; | face[j] = val; | ||||
| } | } | ||||
| mesh()->AddFace(face); | mesh()->AddFace(face); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| point_cloud()->set_num_points(num_points); | point_cloud()->set_num_points(num_points); | ||||
| return true; | return true; | ||||
| } | } | ||||
| bool MeshSequentialDecoder::CreateAttributesDecoder(int32_t att_decoder_id) { | bool MeshSequentialDecoder::CreateAttributesDecoder(int32_t att_decoder_id) { | ||||
| // Always create the basic attribute decoder. | // Always create the basic attribute decoder. | ||||
| return SetAttributesDecoder( | return SetAttributesDecoder( | ||||
| att_decoder_id, | att_decoder_id, | ||||
| std::unique_ptr<AttributesDecoder>( | std::unique_ptr<AttributesDecoder>( | ||||
| new SequentialAttributeDecodersController( | new SequentialAttributeDecodersController( | ||||
| std::unique_ptr<PointsSequencer>( | std::unique_ptr<PointsSequencer>( | ||||
| new LinearSequencer(point_cloud()->num_points()))))); | new LinearSequencer(point_cloud()->num_points()))))); | ||||
| } | } | ||||
| bool MeshSequentialDecoder::DecodeAndDecompressIndices(uint32_t num_faces) { | bool MeshSequentialDecoder::DecodeAndDecompressIndices(uint32_t num_faces) { | ||||
| // Get decoded indices differences that were encoded with an entropy code. | // Get decoded indices differences that were encoded with an entropy code. | ||||
| std::vector<uint32_t> indices_buffer(num_faces * 3); | std::vector<uint32_t> indices_buffer(num_faces * 3); | ||||
| if (!DecodeSymbols(num_faces * 3, 1, buffer(), indices_buffer.data())) | if (!DecodeSymbols(num_faces * 3, 1, buffer(), indices_buffer.data())) { | ||||
| return false; | return false; | ||||
| } | |||||
| // Reconstruct the indices from the differences. | // Reconstruct the indices from the differences. | ||||
| // See MeshSequentialEncoder::CompressAndEncodeIndices() for more details. | // See MeshSequentialEncoder::CompressAndEncodeIndices() for more details. | ||||
| int32_t last_index_value = 0; | int32_t last_index_value = 0; | ||||
| int vertex_index = 0; | int vertex_index = 0; | ||||
| for (uint32_t i = 0; i < num_faces; ++i) { | for (uint32_t i = 0; i < num_faces; ++i) { | ||||
| Mesh::Face face; | Mesh::Face face; | ||||
| for (int j = 0; j < 3; ++j) { | for (int j = 0; j < 3; ++j) { | ||||
| const uint32_t encoded_val = indices_buffer[vertex_index++]; | const uint32_t encoded_val = indices_buffer[vertex_index++]; | ||||
| int32_t index_diff = (encoded_val >> 1); | int32_t index_diff = (encoded_val >> 1); | ||||
| if (encoded_val & 1) | if (encoded_val & 1) { | ||||
| index_diff = -index_diff; | index_diff = -index_diff; | ||||
| } | |||||
| const int32_t index_value = index_diff + last_index_value; | const int32_t index_value = index_diff + last_index_value; | ||||
| face[j] = index_value; | face[j] = index_value; | ||||
| last_index_value = index_value; | last_index_value = index_value; | ||||
| } | } | ||||
| mesh()->AddFace(face); | mesh()->AddFace(face); | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| } // namespace draco | } // namespace draco | ||||