summaryrefslogtreecommitdiff
path: root/internal/dynamic_depth/profile.cc
blob: c24629f09208722af45ea1e1692bed77af20d403 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "dynamic_depth/profile.h"

#include "android-base/logging.h"
#include "dynamic_depth/const.h"

using ::dynamic_depth::xmpmeta::xml::Deserializer;
using ::dynamic_depth::xmpmeta::xml::Serializer;

namespace dynamic_depth {
namespace {

const char kType[] = "Type";
const char kCameraIndices[] = "CameraIndices";

const char kNamespaceHref[] = "http://ns.google.com/photos/dd/1.0/profile/";

// Profile type names.
constexpr char kArPhoto[] = "ARPhoto";
constexpr char kArPhotoLowercase[] = "arphoto";
constexpr char kDepthPhoto[] = "DepthPhoto";
constexpr char kDepthPhotoLowercase[] = "depthphoto";

// Profile camera indices' sizes.
constexpr size_t kArPhotoIndicesSize = 1;
constexpr size_t kDepthPhotoIndicesSize = 1;

// Returns true if the type is unsupported, or if the type is supported in the
// Dynamic Depth Profile element and the size of the camera indices matches that
// specified in the spec.
bool ValidateKnownTypeAndIndices(const string& type, size_t camera_indices_size,
                                 string* matched_type) {
  string type_lower = type;
  std::transform(type_lower.begin(), type_lower.end(), type_lower.begin(),
                 ::tolower);
  bool isArPhoto = (kArPhotoLowercase == type_lower);
  bool isDepthPhoto = (kDepthPhotoLowercase == type_lower);
  if (!isArPhoto && !isDepthPhoto) {
    return true;
  }
  bool matches =
      (isArPhoto && camera_indices_size >= kArPhotoIndicesSize) ||
      (isDepthPhoto && camera_indices_size >= kDepthPhotoIndicesSize);
  if (!matches) {
    LOG(WARNING) << "Size of camera indices for "
                 << (isArPhoto ? kArPhoto : kDepthPhoto) << " must be at least "
                 << (isArPhoto ? kArPhotoIndicesSize : kDepthPhotoIndicesSize);
  } else {
    *matched_type = isArPhoto ? kArPhoto : kDepthPhoto;
  }

  return matches;
}

}  // namespace

// Private constructor.
Profile::Profile(const string& type, const std::vector<int>& camera_indices)
    : type_(type), camera_indices_(camera_indices) {}

// Public methods.
void Profile::GetNamespaces(
    std::unordered_map<string, string>* ns_name_href_map) {
  if (ns_name_href_map == nullptr) {
    LOG(ERROR) << "Namespace list or own namespace is null";
    return;
  }
  ns_name_href_map->emplace(DynamicDepthConst::Profile(), kNamespaceHref);
}

std::unique_ptr<Profile> Profile::FromData(
    const string& type, const std::vector<int>& camera_indices) {
  if (type.empty()) {
    LOG(ERROR) << "Profile must have a type";
    return nullptr;
  }
  // Check that the camera indices' length is at least the size of that
  // specified for the type. This has no restrictions on unsupported profile
  // types.
  // Ensure also that a consistent case-sensitive profile is stored, even if the
  // caller provided a case-insensitive name.
  string matched_type;
  if (!ValidateKnownTypeAndIndices(type, camera_indices.size(),
                                   &matched_type)) {
    return nullptr;
  }

  return std::unique_ptr<Profile>(
      new Profile(matched_type.empty() ? type :
                  matched_type, camera_indices));  // NOLINT
}

std::unique_ptr<Profile> Profile::FromDeserializer(
    const Deserializer& parent_deserializer) {
  std::unique_ptr<Deserializer> deserializer =
      parent_deserializer.CreateDeserializer(
          DynamicDepthConst::Namespace(DynamicDepthConst::Profile()),
          DynamicDepthConst::Profile());
  if (deserializer == nullptr) {
    return nullptr;
  }
  std::unique_ptr<Profile> profile(new Profile("", {}));
  if (!deserializer->ParseString(DynamicDepthConst::Profile(), kType,
                                 &profile->type_)) {
    return nullptr;
  }
  deserializer->ParseIntArray(DynamicDepthConst::Profile(), kCameraIndices,
                              &profile->camera_indices_);
  if (!ValidateKnownTypeAndIndices(
          profile->type_, profile->camera_indices_.size(), &profile->type_)) {
    return nullptr;
  }
  return profile;
}

const string& Profile::GetType() const { return type_; }

const std::vector<int>& Profile::GetCameraIndices() const {
  return camera_indices_;
}

bool Profile::Serialize(Serializer* serializer) const {
  if (serializer == nullptr) {
    LOG(ERROR) << "Serializer is null";
    return false;
  }
  if (!serializer->WriteProperty(DynamicDepthConst::Profile(), kType, type_)) {
    return false;
  }
  if (camera_indices_.empty()) {
    return true;
  }
  return serializer->WriteIntArray(DynamicDepthConst::Profile(), kCameraIndices,
                                   camera_indices_);
}

}  // namespace dynamic_depth