Coverage Report

Created: 2024-09-08 06:48

/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
225
    int8_t method) {
34
225
  if (method == POINT_CLOUD_SEQUENTIAL_ENCODING) {
35
35
    return std::unique_ptr<PointCloudDecoder>(
36
35
        new PointCloudSequentialDecoder());
37
190
  } else if (method == POINT_CLOUD_KD_TREE_ENCODING) {
38
190
    return std::unique_ptr<PointCloudDecoder>(new PointCloudKdTreeDecoder());
39
190
  }
40
0
  return Status(Status::DRACO_ERROR, "Unsupported encoding method.");
41
225
}
42
#endif
43
44
#ifdef DRACO_MESH_COMPRESSION_SUPPORTED
45
589
StatusOr<std::unique_ptr<MeshDecoder>> CreateMeshDecoder(uint8_t method) {
46
589
  if (method == MESH_SEQUENTIAL_ENCODING) {
47
132
    return std::unique_ptr<MeshDecoder>(new MeshSequentialDecoder());
48
457
  } else if (method == MESH_EDGEBREAKER_ENCODING) {
49
457
    return std::unique_ptr<MeshDecoder>(new MeshEdgebreakerDecoder());
50
457
  }
51
0
  return Status(Status::DRACO_ERROR, "Unsupported encoding method.");
52
589
}
53
#endif
54
55
StatusOr<EncodedGeometryType> Decoder::GetEncodedGeometryType(
56
814
    DecoderBuffer *in_buffer) {
57
814
  DecoderBuffer temp_buffer(*in_buffer);
58
814
  DracoHeader header;
59
814
  DRACO_RETURN_IF_ERROR(PointCloudDecoder::DecodeHeader(&temp_buffer, &header));
60
814
  if (header.encoder_type >= NUM_ENCODED_GEOMETRY_TYPES) {
61
0
    return Status(Status::DRACO_ERROR, "Unsupported geometry type.");
62
0
  }
63
814
  return static_cast<EncodedGeometryType>(header.encoder_type);
64
814
}
65
66
StatusOr<std::unique_ptr<PointCloud>> Decoder::DecodePointCloudFromBuffer(
67
814
    DecoderBuffer *in_buffer) {
68
814
  DRACO_ASSIGN_OR_RETURN(EncodedGeometryType type,
69
814
                         GetEncodedGeometryType(in_buffer))
70
814
  if (type == POINT_CLOUD) {
71
225
#ifdef DRACO_POINT_CLOUD_COMPRESSION_SUPPORTED
72
225
    std::unique_ptr<PointCloud> point_cloud(new PointCloud());
73
225
    DRACO_RETURN_IF_ERROR(DecodeBufferToGeometry(in_buffer, point_cloud.get()))
74
4
    return std::move(point_cloud);
75
225
#endif
76
589
  } else if (type == TRIANGULAR_MESH) {
77
589
#ifdef DRACO_MESH_COMPRESSION_SUPPORTED
78
589
    std::unique_ptr<Mesh> mesh(new Mesh());
79
589
    DRACO_RETURN_IF_ERROR(DecodeBufferToGeometry(in_buffer, mesh.get()))
80
25
    return static_cast<std::unique_ptr<PointCloud>>(std::move(mesh));
81
589
#endif
82
589
  }
83
0
  return Status(Status::DRACO_ERROR, "Unsupported geometry type.");
84
814
}
85
86
StatusOr<std::unique_ptr<Mesh>> Decoder::DecodeMeshFromBuffer(
87
0
    DecoderBuffer *in_buffer) {
88
0
  std::unique_ptr<Mesh> mesh(new Mesh());
89
0
  DRACO_RETURN_IF_ERROR(DecodeBufferToGeometry(in_buffer, mesh.get()))
90
0
  return std::move(mesh);
91
0
}
92
93
Status Decoder::DecodeBufferToGeometry(DecoderBuffer *in_buffer,
94
225
                                       PointCloud *out_geometry) {
95
225
#ifdef DRACO_POINT_CLOUD_COMPRESSION_SUPPORTED
96
225
  DecoderBuffer temp_buffer(*in_buffer);
97
225
  DracoHeader header;
98
225
  DRACO_RETURN_IF_ERROR(PointCloudDecoder::DecodeHeader(&temp_buffer, &header))
99
225
  if (header.encoder_type != POINT_CLOUD) {
100
0
    return Status(Status::DRACO_ERROR, "Input is not a point cloud.");
101
0
  }
102
450
  DRACO_ASSIGN_OR_RETURN(std::unique_ptr<PointCloudDecoder> decoder,
103
450
                         CreatePointCloudDecoder(header.encoder_method))
104
105
450
  DRACO_RETURN_IF_ERROR(decoder->Decode(options_, in_buffer, out_geometry))
106
4
  return OkStatus();
107
#else
108
  return Status(Status::DRACO_ERROR, "Unsupported geometry type.");
109
#endif
110
450
}
111
112
Status Decoder::DecodeBufferToGeometry(DecoderBuffer *in_buffer,
113
589
                                       Mesh *out_geometry) {
114
589
#ifdef DRACO_MESH_COMPRESSION_SUPPORTED
115
589
  DecoderBuffer temp_buffer(*in_buffer);
116
589
  DracoHeader header;
117
589
  DRACO_RETURN_IF_ERROR(PointCloudDecoder::DecodeHeader(&temp_buffer, &header))
118
589
  if (header.encoder_type != TRIANGULAR_MESH) {
119
0
    return Status(Status::DRACO_ERROR, "Input is not a mesh.");
120
0
  }
121
1.17k
  DRACO_ASSIGN_OR_RETURN(std::unique_ptr<MeshDecoder> decoder,
122
1.17k
                         CreateMeshDecoder(header.encoder_method))
123
124
1.17k
  DRACO_RETURN_IF_ERROR(decoder->Decode(options_, in_buffer, out_geometry))
125
25
  return OkStatus();
126
#else
127
  return Status(Status::DRACO_ERROR, "Unsupported geometry type.");
128
#endif
129
1.17k
}
130
131
0
void Decoder::SetSkipAttributeTransform(GeometryAttribute::Type att_type) {
132
0
  options_.SetAttributeBool(att_type, "skip_attribute_transform", true);
133
0
}
134
135
}  // namespace draco