xref: /aosp_15_r20/external/dynamic_depth/internal/dynamic_depth/profile.cc (revision a62be0856e8e1158f43b03e41bbad10f4d005fde)
1 #include "dynamic_depth/profile.h"
2 
3 #include "android-base/logging.h"
4 #include "dynamic_depth/const.h"
5 
6 using ::dynamic_depth::xmpmeta::xml::Deserializer;
7 using ::dynamic_depth::xmpmeta::xml::Serializer;
8 
9 namespace dynamic_depth {
10 namespace {
11 
12 const char kType[] = "Type";
13 const char kCameraIndices[] = "CameraIndices";
14 
15 const char kNamespaceHref[] = "http://ns.google.com/photos/dd/1.0/profile/";
16 
17 // Profile type names.
18 constexpr char kArPhoto[] = "ARPhoto";
19 constexpr char kArPhotoLowercase[] = "arphoto";
20 constexpr char kDepthPhoto[] = "DepthPhoto";
21 constexpr char kDepthPhotoLowercase[] = "depthphoto";
22 
23 // Profile camera indices' sizes.
24 constexpr size_t kArPhotoIndicesSize = 1;
25 constexpr size_t kDepthPhotoIndicesSize = 1;
26 
27 // Returns true if the type is unsupported, or if the type is supported in the
28 // Dynamic Depth Profile element and the size of the camera indices matches that
29 // specified in the spec.
ValidateKnownTypeAndIndices(const string & type,size_t camera_indices_size,string * matched_type)30 bool ValidateKnownTypeAndIndices(const string& type, size_t camera_indices_size,
31                                  string* matched_type) {
32   string type_lower = type;
33   std::transform(type_lower.begin(), type_lower.end(), type_lower.begin(),
34                  ::tolower);
35   bool isArPhoto = (kArPhotoLowercase == type_lower);
36   bool isDepthPhoto = (kDepthPhotoLowercase == type_lower);
37   if (!isArPhoto && !isDepthPhoto) {
38     return true;
39   }
40   bool matches =
41       (isArPhoto && camera_indices_size >= kArPhotoIndicesSize) ||
42       (isDepthPhoto && camera_indices_size >= kDepthPhotoIndicesSize);
43   if (!matches) {
44     LOG(WARNING) << "Size of camera indices for "
45                  << (isArPhoto ? kArPhoto : kDepthPhoto) << " must be at least "
46                  << (isArPhoto ? kArPhotoIndicesSize : kDepthPhotoIndicesSize);
47   } else {
48     *matched_type = isArPhoto ? kArPhoto : kDepthPhoto;
49   }
50 
51   return matches;
52 }
53 
54 }  // namespace
55 
56 // Private constructor.
Profile(const string & type,const std::vector<int> & camera_indices)57 Profile::Profile(const string& type, const std::vector<int>& camera_indices)
58     : type_(type), camera_indices_(camera_indices) {}
59 
60 // Public methods.
GetNamespaces(std::unordered_map<string,string> * ns_name_href_map)61 void Profile::GetNamespaces(
62     std::unordered_map<string, string>* ns_name_href_map) {
63   if (ns_name_href_map == nullptr) {
64     LOG(ERROR) << "Namespace list or own namespace is null";
65     return;
66   }
67   ns_name_href_map->emplace(DynamicDepthConst::Profile(), kNamespaceHref);
68 }
69 
FromData(const string & type,const std::vector<int> & camera_indices)70 std::unique_ptr<Profile> Profile::FromData(
71     const string& type, const std::vector<int>& camera_indices) {
72   if (type.empty()) {
73     LOG(ERROR) << "Profile must have a type";
74     return nullptr;
75   }
76   // Check that the camera indices' length is at least the size of that
77   // specified for the type. This has no restrictions on unsupported profile
78   // types.
79   // Ensure also that a consistent case-sensitive profile is stored, even if the
80   // caller provided a case-insensitive name.
81   string matched_type;
82   if (!ValidateKnownTypeAndIndices(type, camera_indices.size(),
83                                    &matched_type)) {
84     return nullptr;
85   }
86 
87   return std::unique_ptr<Profile>(
88       new Profile(matched_type.empty() ? type :
89                   matched_type, camera_indices));  // NOLINT
90 }
91 
FromDeserializer(const Deserializer & parent_deserializer)92 std::unique_ptr<Profile> Profile::FromDeserializer(
93     const Deserializer& parent_deserializer) {
94   std::unique_ptr<Deserializer> deserializer =
95       parent_deserializer.CreateDeserializer(
96           DynamicDepthConst::Namespace(DynamicDepthConst::Profile()),
97           DynamicDepthConst::Profile());
98   if (deserializer == nullptr) {
99     return nullptr;
100   }
101   std::unique_ptr<Profile> profile(new Profile("", {}));
102   if (!deserializer->ParseString(DynamicDepthConst::Profile(), kType,
103                                  &profile->type_)) {
104     return nullptr;
105   }
106   deserializer->ParseIntArray(DynamicDepthConst::Profile(), kCameraIndices,
107                               &profile->camera_indices_);
108   if (!ValidateKnownTypeAndIndices(
109           profile->type_, profile->camera_indices_.size(), &profile->type_)) {
110     return nullptr;
111   }
112   return profile;
113 }
114 
GetType() const115 const string& Profile::GetType() const { return type_; }
116 
GetCameraIndices() const117 const std::vector<int>& Profile::GetCameraIndices() const {
118   return camera_indices_;
119 }
120 
Serialize(Serializer * serializer) const121 bool Profile::Serialize(Serializer* serializer) const {
122   if (serializer == nullptr) {
123     LOG(ERROR) << "Serializer is null";
124     return false;
125   }
126   if (!serializer->WriteProperty(DynamicDepthConst::Profile(), kType, type_)) {
127     return false;
128   }
129   if (camera_indices_.empty()) {
130     return true;
131   }
132   return serializer->WriteIntArray(DynamicDepthConst::Profile(), kCameraIndices,
133                                    camera_indices_);
134 }
135 
136 }  // namespace dynamic_depth
137