Coverage Report

Created: 2024-09-08 06:47

/src/draco/src/draco/compression/decode.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2016 The Draco Authors.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
//
15
#include "draco/compression/decode.h"
16
17
#include "draco/compression/config/compression_shared.h"
18
19
#ifdef DRACO_MESH_COMPRESSION_SUPPORTED
20
#include "draco/compression/mesh/mesh_edgebreaker_decoder.h"
21
#include "draco/compression/mesh/mesh_sequential_decoder.h"
22
#endif
23
24
#ifdef DRACO_POINT_CLOUD_COMPRESSION_SUPPORTED
25
#include "draco/compression/point_cloud/point_cloud_kd_tree_decoder.h"
26
#include "draco/compression/point_cloud/point_cloud_sequential_decoder.h"
27
#endif
28
29
namespace draco {
30
31
#ifdef DRACO_POINT_CLOUD_COMPRESSION_SUPPORTED
32
StatusOr<std::unique_ptr<PointCloudDecoder>> CreatePointCloudDecoder(
33
0
    int8_t method) {
34
0
  if (method == POINT_CLOUD_SEQUENTIAL_ENCODING) {
35
0
    return std::unique_ptr<PointCloudDecoder>(
36
0
        new PointCloudSequentialDecoder());
37
0
  } else if (method == POINT_CLOUD_KD_TREE_ENCODING) {
38
0
    return std::unique_ptr<PointCloudDecoder>(new PointCloudKdTreeDecoder());
39
0
  }
40
0
  return Status(Status::DRACO_ERROR, "Unsupported encoding method.");
41
0
}
42
#endif
43
44
#ifdef DRACO_MESH_COMPRESSION_SUPPORTED
45
1.36k
StatusOr<std::unique_ptr<MeshDecoder>> CreateMeshDecoder(uint8_t method) {
46
1.36k
  if (method == MESH_SEQUENTIAL_ENCODING) {
47
431
    return std::unique_ptr<MeshDecoder>(new MeshSequentialDecoder());
48
935
  } else if (method == MESH_EDGEBREAKER_ENCODING) {
49
935
    return std::unique_ptr<MeshDecoder>(new MeshEdgebreakerDecoder());
50
935
  }
51
0
  return Status(Status::DRACO_ERROR, "Unsupported encoding method.");
52
1.36k
}
53
#endif
54
55
StatusOr<EncodedGeometryType> Decoder::GetEncodedGeometryType(
56
0
    DecoderBuffer *in_buffer) {
57
0
  DecoderBuffer temp_buffer(*in_buffer);
58
0
  DracoHeader header;
59
0
  DRACO_RETURN_IF_ERROR(PointCloudDecoder::DecodeHeader(&temp_buffer, &header));
60
0
  if (header.encoder_type >= NUM_ENCODED_GEOMETRY_TYPES) {
61
0
    return Status(Status::DRACO_ERROR, "Unsupported geometry type.");
62
0
  }
63
0
  return static_cast<EncodedGeometryType>(header.encoder_type);
64
0
}
65
66
StatusOr<std::unique_ptr<PointCloud>> Decoder::DecodePointCloudFromBuffer(
67
0
    DecoderBuffer *in_buffer) {
68
0
  DRACO_ASSIGN_OR_RETURN(EncodedGeometryType type,
69
0
                         GetEncodedGeometryType(in_buffer))
70
0
  if (type == POINT_CLOUD) {
71
0
#ifdef DRACO_POINT_CLOUD_COMPRESSION_SUPPORTED
72
0
    std::unique_ptr<PointCloud> point_cloud(new PointCloud());
73
0
    DRACO_RETURN_IF_ERROR(DecodeBufferToGeometry(in_buffer, point_cloud.get()))
74
0
    return std::move(point_cloud);
75
0
#endif
76
0
  } else if (type == TRIANGULAR_MESH) {
77
0
#ifdef DRACO_MESH_COMPRESSION_SUPPORTED
78
0
    std::unique_ptr<Mesh> mesh(new Mesh());
79
0
    DRACO_RETURN_IF_ERROR(DecodeBufferToGeometry(in_buffer, mesh.get()))
80
0
    return static_cast<std::unique_ptr<PointCloud>>(std::move(mesh));
81
0
#endif
82
0
  }
83
0
  return Status(Status::DRACO_ERROR, "Unsupported geometry type.");
84
0
}
85
86
StatusOr<std::unique_ptr<Mesh>> Decoder::DecodeMeshFromBuffer(
87
1.36k
    DecoderBuffer *in_buffer) {
88
1.36k
  std::unique_ptr<Mesh> mesh(new Mesh());
89
1.36k
  DRACO_RETURN_IF_ERROR(DecodeBufferToGeometry(in_buffer, mesh.get()))
90
70
  return std::move(mesh);
91
1.36k
}
92
93
Status Decoder::DecodeBufferToGeometry(DecoderBuffer *in_buffer,
94
0
                                       PointCloud *out_geometry) {
95
0
#ifdef DRACO_POINT_CLOUD_COMPRESSION_SUPPORTED
96
0
  DecoderBuffer temp_buffer(*in_buffer);
97
0
  DracoHeader header;
98
0
  DRACO_RETURN_IF_ERROR(PointCloudDecoder::DecodeHeader(&temp_buffer, &header))
99
0
  if (header.encoder_type != POINT_CLOUD) {
100
0
    return Status(Status::DRACO_ERROR, "Input is not a point cloud.");
101
0
  }
102
0
  DRACO_ASSIGN_OR_RETURN(std::unique_ptr<PointCloudDecoder> decoder,
103
0
                         CreatePointCloudDecoder(header.encoder_method))
104
105
0
  DRACO_RETURN_IF_ERROR(decoder->Decode(options_, in_buffer, out_geometry))
106
0
  return OkStatus();
107
#else
108
  return Status(Status::DRACO_ERROR, "Unsupported geometry type.");
109
#endif
110
0
}
111
112
Status Decoder::DecodeBufferToGeometry(DecoderBuffer *in_buffer,
113
1.36k
                                       Mesh *out_geometry) {
114
1.36k
#ifdef DRACO_MESH_COMPRESSION_SUPPORTED
115
1.36k
  DecoderBuffer temp_buffer(*in_buffer);
116
1.36k
  DracoHeader header;
117
1.36k
  DRACO_RETURN_IF_ERROR(PointCloudDecoder::DecodeHeader(&temp_buffer, &header))
118
1.36k
  if (header.encoder_type != TRIANGULAR_MESH) {
119
1
    return Status(Status::DRACO_ERROR, "Input is not a mesh.");
120
1
  }
121
2.73k
  DRACO_ASSIGN_OR_RETURN(std::unique_ptr<MeshDecoder> decoder,
122
2.73k
                         CreateMeshDecoder(header.encoder_method))
123
124
2.73k
  DRACO_RETURN_IF_ERROR(decoder->Decode(options_, in_buffer, out_geometry))
125
70
  return OkStatus();
126
#else
127
  return Status(Status::DRACO_ERROR, "Unsupported geometry type.");
128
#endif
129
2.73k
}
130
131
1.36k
void Decoder::SetSkipAttributeTransform(GeometryAttribute::Type att_type) {
132
1.36k
  options_.SetAttributeBool(att_type, "skip_attribute_transform", true);
133
1.36k
}
134
135
}  // namespace draco