Differential D9642 Diff 31337 extern/draco/draco/src/draco/compression/point_cloud/point_cloud_decoder.cc
Changeset View
Changeset View
Standalone View
Standalone View
extern/draco/draco/src/draco/compression/point_cloud/point_cloud_decoder.cc
- This file was moved from extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_decoder.cc.
| Show All 22 Lines | : point_cloud_(nullptr), | ||||
| buffer_(nullptr), | buffer_(nullptr), | ||||
| version_major_(0), | version_major_(0), | ||||
| version_minor_(0), | version_minor_(0), | ||||
| options_(nullptr) {} | options_(nullptr) {} | ||||
| Status PointCloudDecoder::DecodeHeader(DecoderBuffer *buffer, | Status PointCloudDecoder::DecodeHeader(DecoderBuffer *buffer, | ||||
| DracoHeader *out_header) { | DracoHeader *out_header) { | ||||
| constexpr char kIoErrorMsg[] = "Failed to parse Draco header."; | constexpr char kIoErrorMsg[] = "Failed to parse Draco header."; | ||||
| if (!buffer->Decode(out_header->draco_string, 5)) | if (!buffer->Decode(out_header->draco_string, 5)) { | ||||
| return Status(Status::IO_ERROR, kIoErrorMsg); | return Status(Status::IO_ERROR, kIoErrorMsg); | ||||
| if (memcmp(out_header->draco_string, "DRACO", 5) != 0) | } | ||||
| if (memcmp(out_header->draco_string, "DRACO", 5) != 0) { | |||||
| return Status(Status::DRACO_ERROR, "Not a Draco file."); | return Status(Status::DRACO_ERROR, "Not a Draco file."); | ||||
| if (!buffer->Decode(&(out_header->version_major))) | } | ||||
| if (!buffer->Decode(&(out_header->version_major))) { | |||||
| return Status(Status::IO_ERROR, kIoErrorMsg); | return Status(Status::IO_ERROR, kIoErrorMsg); | ||||
| if (!buffer->Decode(&(out_header->version_minor))) | } | ||||
| if (!buffer->Decode(&(out_header->version_minor))) { | |||||
| return Status(Status::IO_ERROR, kIoErrorMsg); | return Status(Status::IO_ERROR, kIoErrorMsg); | ||||
| if (!buffer->Decode(&(out_header->encoder_type))) | } | ||||
| if (!buffer->Decode(&(out_header->encoder_type))) { | |||||
| return Status(Status::IO_ERROR, kIoErrorMsg); | return Status(Status::IO_ERROR, kIoErrorMsg); | ||||
| if (!buffer->Decode(&(out_header->encoder_method))) | } | ||||
| if (!buffer->Decode(&(out_header->encoder_method))) { | |||||
| return Status(Status::IO_ERROR, kIoErrorMsg); | return Status(Status::IO_ERROR, kIoErrorMsg); | ||||
| if (!buffer->Decode(&(out_header->flags))) | } | ||||
| if (!buffer->Decode(&(out_header->flags))) { | |||||
| return Status(Status::IO_ERROR, kIoErrorMsg); | return Status(Status::IO_ERROR, kIoErrorMsg); | ||||
| } | |||||
| return OkStatus(); | return OkStatus(); | ||||
| } | } | ||||
| Status PointCloudDecoder::DecodeMetadata() { | Status PointCloudDecoder::DecodeMetadata() { | ||||
| std::unique_ptr<GeometryMetadata> metadata = | std::unique_ptr<GeometryMetadata> metadata = | ||||
| std::unique_ptr<GeometryMetadata>(new GeometryMetadata()); | std::unique_ptr<GeometryMetadata>(new GeometryMetadata()); | ||||
| MetadataDecoder metadata_decoder; | MetadataDecoder metadata_decoder; | ||||
| if (!metadata_decoder.DecodeGeometryMetadata(buffer_, metadata.get())) | if (!metadata_decoder.DecodeGeometryMetadata(buffer_, metadata.get())) { | ||||
| return Status(Status::DRACO_ERROR, "Failed to decode metadata."); | return Status(Status::DRACO_ERROR, "Failed to decode metadata."); | ||||
| } | |||||
| point_cloud_->AddMetadata(std::move(metadata)); | point_cloud_->AddMetadata(std::move(metadata)); | ||||
| return OkStatus(); | return OkStatus(); | ||||
| } | } | ||||
| Status PointCloudDecoder::Decode(const DecoderOptions &options, | Status PointCloudDecoder::Decode(const DecoderOptions &options, | ||||
| DecoderBuffer *in_buffer, | DecoderBuffer *in_buffer, | ||||
| PointCloud *out_point_cloud) { | PointCloud *out_point_cloud) { | ||||
| options_ = &options; | options_ = &options; | ||||
| buffer_ = in_buffer; | buffer_ = in_buffer; | ||||
| point_cloud_ = out_point_cloud; | point_cloud_ = out_point_cloud; | ||||
| DracoHeader header; | DracoHeader header; | ||||
| DRACO_RETURN_IF_ERROR(DecodeHeader(buffer_, &header)) | DRACO_RETURN_IF_ERROR(DecodeHeader(buffer_, &header)) | ||||
| // Sanity check that we are really using the right decoder (mostly for cases | // Sanity check that we are really using the right decoder (mostly for cases | ||||
| // where the Decode method was called manually outside of our main API. | // where the Decode method was called manually outside of our main API. | ||||
| if (header.encoder_type != GetGeometryType()) | if (header.encoder_type != GetGeometryType()) { | ||||
| return Status(Status::DRACO_ERROR, | return Status(Status::DRACO_ERROR, | ||||
| "Using incompatible decoder for the input geometry."); | "Using incompatible decoder for the input geometry."); | ||||
| } | |||||
| // TODO(ostava): We should check the method as well, but currently decoders | // TODO(ostava): We should check the method as well, but currently decoders | ||||
| // don't expose the decoding method id. | // don't expose the decoding method id. | ||||
| version_major_ = header.version_major; | version_major_ = header.version_major; | ||||
| version_minor_ = header.version_minor; | version_minor_ = header.version_minor; | ||||
| const uint8_t max_supported_major_version = | const uint8_t max_supported_major_version = | ||||
| header.encoder_type == POINT_CLOUD ? kDracoPointCloudBitstreamVersionMajor | header.encoder_type == POINT_CLOUD ? kDracoPointCloudBitstreamVersionMajor | ||||
| : kDracoMeshBitstreamVersionMajor; | : kDracoMeshBitstreamVersionMajor; | ||||
| const uint8_t max_supported_minor_version = | const uint8_t max_supported_minor_version = | ||||
| header.encoder_type == POINT_CLOUD ? kDracoPointCloudBitstreamVersionMinor | header.encoder_type == POINT_CLOUD ? kDracoPointCloudBitstreamVersionMinor | ||||
| : kDracoMeshBitstreamVersionMinor; | : kDracoMeshBitstreamVersionMinor; | ||||
| // Check for version compatibility. | // Check for version compatibility. | ||||
| if (version_major_ < 1 || version_major_ > max_supported_major_version) | if (version_major_ < 1 || version_major_ > max_supported_major_version) { | ||||
| return Status(Status::UNKNOWN_VERSION, "Unknown major version."); | return Status(Status::UNKNOWN_VERSION, "Unknown major version."); | ||||
| } | |||||
| if (version_major_ == max_supported_major_version && | if (version_major_ == max_supported_major_version && | ||||
| version_minor_ > max_supported_minor_version) | version_minor_ > max_supported_minor_version) { | ||||
| return Status(Status::UNKNOWN_VERSION, "Unknown minor version."); | return Status(Status::UNKNOWN_VERSION, "Unknown minor version."); | ||||
| } | |||||
| buffer_->set_bitstream_version( | buffer_->set_bitstream_version( | ||||
| DRACO_BITSTREAM_VERSION(version_major_, version_minor_)); | DRACO_BITSTREAM_VERSION(version_major_, version_minor_)); | ||||
| if (bitstream_version() >= DRACO_BITSTREAM_VERSION(1, 3) && | if (bitstream_version() >= DRACO_BITSTREAM_VERSION(1, 3) && | ||||
| (header.flags & METADATA_FLAG_MASK)) { | (header.flags & METADATA_FLAG_MASK)) { | ||||
| DRACO_RETURN_IF_ERROR(DecodeMetadata()) | DRACO_RETURN_IF_ERROR(DecodeMetadata()) | ||||
| } | } | ||||
| if (!InitializeDecoder()) | if (!InitializeDecoder()) { | ||||
| return Status(Status::DRACO_ERROR, "Failed to initialize the decoder."); | return Status(Status::DRACO_ERROR, "Failed to initialize the decoder."); | ||||
| if (!DecodeGeometryData()) | } | ||||
| if (!DecodeGeometryData()) { | |||||
| return Status(Status::DRACO_ERROR, "Failed to decode geometry data."); | return Status(Status::DRACO_ERROR, "Failed to decode geometry data."); | ||||
| if (!DecodePointAttributes()) | } | ||||
| if (!DecodePointAttributes()) { | |||||
| return Status(Status::DRACO_ERROR, "Failed to decode point attributes."); | return Status(Status::DRACO_ERROR, "Failed to decode point attributes."); | ||||
| } | |||||
| return OkStatus(); | return OkStatus(); | ||||
| } | } | ||||
| bool PointCloudDecoder::DecodePointAttributes() { | bool PointCloudDecoder::DecodePointAttributes() { | ||||
| uint8_t num_attributes_decoders; | uint8_t num_attributes_decoders; | ||||
| if (!buffer_->Decode(&num_attributes_decoders)) | if (!buffer_->Decode(&num_attributes_decoders)) { | ||||
| return false; | return false; | ||||
| } | |||||
| // Create all attribute decoders. This is implementation specific and the | // Create all attribute decoders. This is implementation specific and the | ||||
| // derived classes can use any data encoded in the | // derived classes can use any data encoded in the | ||||
| // PointCloudEncoder::EncodeAttributesEncoderIdentifier() call. | // PointCloudEncoder::EncodeAttributesEncoderIdentifier() call. | ||||
| for (int i = 0; i < num_attributes_decoders; ++i) { | for (int i = 0; i < num_attributes_decoders; ++i) { | ||||
| if (!CreateAttributesDecoder(i)) | if (!CreateAttributesDecoder(i)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | |||||
| // Initialize all attributes decoders. No data is decoded here. | // Initialize all attributes decoders. No data is decoded here. | ||||
| for (auto &att_dec : attributes_decoders_) { | for (auto &att_dec : attributes_decoders_) { | ||||
| if (!att_dec->Init(this, point_cloud_)) | if (!att_dec->Init(this, point_cloud_)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | |||||
| // Decode any data needed by the attribute decoders. | // Decode any data needed by the attribute decoders. | ||||
| for (int i = 0; i < num_attributes_decoders; ++i) { | for (int i = 0; i < num_attributes_decoders; ++i) { | ||||
| if (!attributes_decoders_[i]->DecodeAttributesDecoderData(buffer_)) | if (!attributes_decoders_[i]->DecodeAttributesDecoderData(buffer_)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | |||||
| // Create map between attribute and decoder ids. | // Create map between attribute and decoder ids. | ||||
| for (int i = 0; i < num_attributes_decoders; ++i) { | for (int i = 0; i < num_attributes_decoders; ++i) { | ||||
| const int32_t num_attributes = attributes_decoders_[i]->GetNumAttributes(); | const int32_t num_attributes = attributes_decoders_[i]->GetNumAttributes(); | ||||
| for (int j = 0; j < num_attributes; ++j) { | for (int j = 0; j < num_attributes; ++j) { | ||||
| int att_id = attributes_decoders_[i]->GetAttributeId(j); | int att_id = attributes_decoders_[i]->GetAttributeId(j); | ||||
| if (att_id >= attribute_to_decoder_map_.size()) { | if (att_id >= attribute_to_decoder_map_.size()) { | ||||
| attribute_to_decoder_map_.resize(att_id + 1); | attribute_to_decoder_map_.resize(att_id + 1); | ||||
| } | } | ||||
| attribute_to_decoder_map_[att_id] = i; | attribute_to_decoder_map_[att_id] = i; | ||||
| } | } | ||||
| } | } | ||||
| // Decode the actual attributes using the created attribute decoders. | // Decode the actual attributes using the created attribute decoders. | ||||
| if (!DecodeAllAttributes()) | if (!DecodeAllAttributes()) { | ||||
| return false; | return false; | ||||
| } | |||||
| if (!OnAttributesDecoded()) | if (!OnAttributesDecoded()) { | ||||
| return false; | return false; | ||||
| } | |||||
| return true; | return true; | ||||
| } | } | ||||
| bool PointCloudDecoder::DecodeAllAttributes() { | bool PointCloudDecoder::DecodeAllAttributes() { | ||||
| for (auto &att_dec : attributes_decoders_) { | for (auto &att_dec : attributes_decoders_) { | ||||
| if (!att_dec->DecodeAttributes(buffer_)) | if (!att_dec->DecodeAttributes(buffer_)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | |||||
| return true; | return true; | ||||
| } | } | ||||
| const PointAttribute *PointCloudDecoder::GetPortableAttribute( | const PointAttribute *PointCloudDecoder::GetPortableAttribute( | ||||
| int32_t parent_att_id) { | int32_t parent_att_id) { | ||||
| if (parent_att_id < 0 || parent_att_id >= point_cloud_->num_attributes()) | if (parent_att_id < 0 || parent_att_id >= point_cloud_->num_attributes()) { | ||||
| return nullptr; | return nullptr; | ||||
| } | |||||
| const int32_t parent_att_decoder_id = | const int32_t parent_att_decoder_id = | ||||
| attribute_to_decoder_map_[parent_att_id]; | attribute_to_decoder_map_[parent_att_id]; | ||||
| return attributes_decoders_[parent_att_decoder_id]->GetPortableAttribute( | return attributes_decoders_[parent_att_decoder_id]->GetPortableAttribute( | ||||
| parent_att_id); | parent_att_id); | ||||
| } | } | ||||
| } // namespace draco | } // namespace draco | ||||