xref: /aosp_15_r20/external/dynamic_depth/internal/dynamic_depth/plane.cc (revision a62be0856e8e1158f43b03e41bbad10f4d005fde)
1 #include "dynamic_depth/plane.h"
2 
3 #include "android-base/logging.h"
4 #include "dynamic_depth/const.h"
5 #include "strings/numbers.h"
6 #include "xmpmeta/base64.h"
7 
8 using ::dynamic_depth::xmpmeta::EncodeFloatArrayBase64;
9 using ::dynamic_depth::xmpmeta::xml::Deserializer;
10 using ::dynamic_depth::xmpmeta::xml::Serializer;
11 
12 namespace dynamic_depth {
13 namespace {
14 
15 constexpr char kBoundary[] = "Boundary";
16 constexpr char kBoundaryVertexCount[] = "BoundaryVertexCount";
17 constexpr char kExtentX[] = "ExtentX";
18 constexpr char kExtentZ[] = "ExtentZ";
19 
20 constexpr char kNamespaceHref[] = "http://ns.google.com/photos/dd/1.0/plane/";
21 
22 }  // namespace
23 
24 // Private constructor.
Plane()25 Plane::Plane() {}
26 
27 // Public methods.
GetNamespaces(std::unordered_map<string,string> * ns_name_href_map)28 void Plane::GetNamespaces(
29     std::unordered_map<string, string>* ns_name_href_map) {
30   if (ns_name_href_map == nullptr) {
31     LOG(ERROR) << "Namespace list is null";
32     return;
33   }
34   ns_name_href_map->emplace(DynamicDepthConst::Plane(), kNamespaceHref);
35 
36   if (pose_ != nullptr) {
37     pose_->GetNamespaces(ns_name_href_map);
38   }
39 }
40 
FromData(std::unique_ptr<Pose> pose,const std::vector<float> & boundary,const double extent_x,const double extent_z)41 std::unique_ptr<Plane> Plane::FromData(std::unique_ptr<Pose> pose,
42                                        const std::vector<float>& boundary,
43                                        const double extent_x,
44                                        const double extent_z) {
45   if (pose == nullptr) {
46     LOG(ERROR) << "The Plane's pose must be provided";
47     return nullptr;
48   }
49 
50   if (boundary.size() % 2 != 0) {
51     LOG(ERROR) << "Number of vertices in the boundary polygon must be 2-tuples";
52     return nullptr;
53   }
54 
55   std::unique_ptr<Plane> plane(std::unique_ptr<Plane>(new Plane()));  // NOLINT
56   plane->pose_ = std::move(pose);
57   plane->boundary_vertex_count_ = boundary.size() / 2;
58   if (!boundary.empty()) {
59     plane->boundary_ = boundary;
60   }
61 
62   plane->extent_x_ = extent_x;
63   plane->extent_z_ = extent_z;
64   return plane;
65 }
66 
FromDeserializer(const Deserializer & parent_deserializer)67 std::unique_ptr<Plane> Plane::FromDeserializer(
68     const Deserializer& parent_deserializer) {
69   std::unique_ptr<Deserializer> deserializer =
70       parent_deserializer.CreateDeserializer(
71           DynamicDepthConst::Namespace(DynamicDepthConst::Plane()),
72           DynamicDepthConst::Plane());
73   if (deserializer == nullptr) {
74     return nullptr;
75   }
76 
77   std::unique_ptr<Plane> plane(std::unique_ptr<Plane>(new Plane()));  // NOLINT
78   if (!plane->ParsePlaneFields(*deserializer)) {
79     return nullptr;
80   }
81 
82   return plane;
83 }
84 
GetPose() const85 const Pose* Plane::GetPose() const { return pose_.get(); }
86 
GetBoundary() const87 const std::vector<float>& Plane::GetBoundary() const { return boundary_; }
88 
GetBoundaryVertexCount() const89 int Plane::GetBoundaryVertexCount() const { return boundary_vertex_count_; }
90 
GetExtentX() const91 const double Plane::GetExtentX() const { return extent_x_; }
92 
GetExtentZ() const93 const double Plane::GetExtentZ() const { return extent_z_; }
94 
Serialize(Serializer * serializer) const95 bool Plane::Serialize(Serializer* serializer) const {
96   if (serializer == nullptr) {
97     LOG(ERROR) << "Serializer is null";
98     return false;
99   }
100 
101   if (pose_ == nullptr) {
102     LOG(ERROR) << "Plane's pose must be present, not serializing";
103     return false;
104   }
105 
106   if (!serializer->WriteProperty(
107           DynamicDepthConst::Plane(), kBoundaryVertexCount,
108           ::dynamic_depth::strings::SimpleItoa(boundary_vertex_count_))) {
109     return false;
110   }
111   if (!boundary_.empty()) {
112     string base64_encoded_boundary;
113     if (!EncodeFloatArrayBase64(boundary_, &base64_encoded_boundary)) {
114       LOG(ERROR) << "Boundary polygon encoding failed.";
115       return false;
116     }
117 
118     if (!serializer->WriteProperty(DynamicDepthConst::Plane(), kBoundary,
119                                    base64_encoded_boundary)) {
120       return false;
121     }
122   }
123 
124   if (!serializer->WriteProperty(DynamicDepthConst::Plane(), kExtentX,
125                                  std::to_string(extent_x_))) {
126     return false;
127   }
128 
129   if (!serializer->WriteProperty(DynamicDepthConst::Plane(), kExtentZ,
130                                  std::to_string(extent_z_))) {
131     return false;
132   }
133 
134   std::unique_ptr<Serializer> pose_serializer = serializer->CreateSerializer(
135       DynamicDepthConst::Plane(), DynamicDepthConst::Pose());
136   return pose_->Serialize(pose_serializer.get());
137 }
138 
139 // Private methods.
ParsePlaneFields(const Deserializer & deserializer)140 bool Plane::ParsePlaneFields(const Deserializer& deserializer) {
141   std::unique_ptr<Pose> pose =
142       Pose::FromDeserializer(deserializer, DynamicDepthConst::Plane());
143   if (pose == nullptr) {
144     LOG(ERROR) << "Plane's pose could not be parsed, stopping deserialization";
145     return false;
146   }
147 
148   // The BoundaryVertexCount field is required only if the Boundary field is
149   // populated.
150   std::vector<float> boundary;
151   int boundary_vertex_count = 0;
152   if (deserializer.ParseFloatArrayBase64(DynamicDepthConst::Plane(), kBoundary,
153                                          &boundary)) {
154     if (!deserializer.ParseInt(DynamicDepthConst::Plane(), kBoundaryVertexCount,
155                                &boundary_vertex_count)) {
156       return false;
157     }
158   }
159 
160   double extent_x = -1;
161   deserializer.ParseDouble(DynamicDepthConst::Plane(), kExtentX, &extent_x);
162 
163   double extent_z = -1;
164   deserializer.ParseDouble(DynamicDepthConst::Plane(), kExtentZ, &extent_z);
165 
166   pose_ = std::move(pose);
167   boundary_ = boundary;
168   boundary_vertex_count_ = boundary_vertex_count;
169   extent_x_ = extent_x;
170   extent_z_ = extent_z;
171 
172   return true;
173 }
174 
175 }  // namespace dynamic_depth
176