1 #include "dynamic_depth/image.h"
2
3 #include "android-base/logging.h"
4 #include "dynamic_depth/const.h"
5 #include "dynamic_depth/item.h"
6
7 using ::dynamic_depth::Item;
8 using ::dynamic_depth::xmpmeta::xml::Deserializer;
9 using ::dynamic_depth::xmpmeta::xml::Serializer;
10
11 namespace dynamic_depth {
12 namespace {
13
14 constexpr char kItemUri[] = "ItemURI";
15 constexpr char kItemSemantic[] = "ItemSemantic";
16
17 constexpr char kNamespaceHref[] = "http://ns.google.com/photos/dd/1.0/image/";
18 constexpr char kPrimaryImagePlaceholderItemUri[] = "primary_image";
19
20 constexpr char kItemSemanticPrimary[] = "Primary";
21 constexpr char kItemSemanticOriginal[] = "Original";
22 constexpr char kItemSemanticPrimaryLower[] = "primary";
23
ItemSemanticToString(ImageItemSemantic item_semantic)24 string ItemSemanticToString(ImageItemSemantic item_semantic) {
25 switch (item_semantic) {
26 case ImageItemSemantic::kPrimary:
27 return kItemSemanticPrimary;
28 case ImageItemSemantic::kOriginal:
29 return kItemSemanticOriginal;
30 }
31 }
32
StringToItemSemantic(const string & item_semantic_str)33 ImageItemSemantic StringToItemSemantic(const string& item_semantic_str) {
34 string item_semantic_str_lower = item_semantic_str;
35 std::transform(item_semantic_str_lower.begin(), item_semantic_str_lower.end(),
36 item_semantic_str_lower.begin(), ::tolower);
37 if (kItemSemanticPrimaryLower == item_semantic_str_lower) {
38 return ImageItemSemantic::kPrimary;
39 }
40
41 // Don't fail, default to Original.
42 return ImageItemSemantic::kOriginal;
43 }
44
45 } // namespace
46
47 // Private constructor.
Image()48 Image::Image() {}
49
50 // Public methods.
GetNamespaces(std::unordered_map<string,string> * ns_name_href_map)51 void Image::GetNamespaces(
52 std::unordered_map<string, string>* ns_name_href_map) {
53 if (ns_name_href_map == nullptr) {
54 LOG(ERROR) << "Namespace list or own namespace is null";
55 return;
56 }
57 ns_name_href_map->emplace(DynamicDepthConst::Image(), kNamespaceHref);
58 }
59
FromData(const string & data,const string & mime,const string & item_uri,std::vector<std::unique_ptr<Item>> * items)60 std::unique_ptr<Image> Image::FromData(
61 const string& data, const string& mime, const string& item_uri,
62 std::vector<std::unique_ptr<Item>>* items) {
63 if (data.empty() || mime.empty()) {
64 LOG(ERROR) << "No image data or mimetype given";
65 return nullptr;
66 }
67
68 if (item_uri.empty()) {
69 LOG(ERROR) << "Item URI must be provided";
70 return nullptr;
71 }
72
73 if (items == nullptr) {
74 LOG(ERROR) << "List of items is null";
75 return nullptr;
76 }
77
78 ItemParams item_params(mime, data.size(), item_uri);
79 item_params.payload_to_serialize = data;
80 items->emplace_back(Item::FromData(item_params));
81
82 std::unique_ptr<Image> image(std::unique_ptr<Image>(new Image())); // NOLINT
83 image->item_uri_ = item_uri;
84 image->item_semantic_ = ImageItemSemantic::kOriginal;
85 return image;
86 }
87
FromDataForPrimaryImage(const string & mime,std::vector<std::unique_ptr<Item>> * items)88 std::unique_ptr<Image> Image::FromDataForPrimaryImage(
89 const string& mime, std::vector<std::unique_ptr<Item>>* items) {
90 if (mime.empty()) {
91 LOG(ERROR) << "No mimetype given";
92 return nullptr;
93 }
94
95 if (items == nullptr) {
96 LOG(ERROR) << "List of items is null";
97 return nullptr;
98 }
99
100 ItemParams item_params(mime, 0, kPrimaryImagePlaceholderItemUri);
101 items->emplace_back(Item::FromData(item_params));
102
103 std::unique_ptr<Image> image(std::unique_ptr<Image>(new Image())); // NOLINT
104 image->item_uri_ = kPrimaryImagePlaceholderItemUri;
105 image->item_semantic_ = ImageItemSemantic::kPrimary;
106 return image;
107 }
108
FromData(const uint8_t * data,size_t data_size,const string & mime,const string & item_uri,std::vector<std::unique_ptr<Item>> * items)109 std::unique_ptr<Image> Image::FromData(
110 const uint8_t* data, size_t data_size, const string& mime,
111 const string& item_uri, std::vector<std::unique_ptr<Item>>* items) {
112 if ((data == nullptr || data_size == 0) || mime.empty()) {
113 LOG(ERROR) << "No image data or mimetype given";
114 return nullptr;
115 }
116
117 if (item_uri.empty()) {
118 LOG(ERROR) << "Item URI must be provided";
119 return nullptr;
120 }
121
122 if (items == nullptr) {
123 LOG(ERROR) << "List of items is null";
124 return nullptr;
125 }
126
127 ItemParams item_params(mime, data_size, item_uri);
128 item_params.payload_to_serialize =
129 std::string(reinterpret_cast<const char*>(data), data_size);
130 items->emplace_back(Item::FromData(item_params));
131
132 std::unique_ptr<Image> image(std::unique_ptr<Image>(new Image())); // NOLINT
133 image->item_uri_ = item_uri;
134 image->item_semantic_ = ImageItemSemantic::kOriginal;
135 return image;
136 }
137
GetItemUri() const138 const string& Image::GetItemUri() const { return item_uri_; }
GetItemSemantic() const139 ImageItemSemantic Image::GetItemSemantic() const { return item_semantic_; }
140
FromDeserializer(const Deserializer & parent_deserializer)141 std::unique_ptr<Image> Image::FromDeserializer(
142 const Deserializer& parent_deserializer) {
143 std::unique_ptr<Deserializer> deserializer =
144 parent_deserializer.CreateDeserializer(
145 DynamicDepthConst::Namespace(DynamicDepthConst::Image()),
146 DynamicDepthConst::Image());
147 if (deserializer == nullptr) {
148 return nullptr;
149 }
150
151 std::unique_ptr<Image> image(new Image());
152 if (!image->ParseImageFields(*deserializer)) {
153 return nullptr;
154 }
155 return image;
156 }
157
Serialize(Serializer * serializer) const158 bool Image::Serialize(Serializer* serializer) const {
159 if (serializer == nullptr) {
160 LOG(ERROR) << "Serializer is null";
161 return false;
162 }
163
164 if (item_uri_.empty()) {
165 LOG(ERROR) << "Item URI is empty";
166 return false;
167 }
168
169 return serializer->WriteProperty(DynamicDepthConst::Image(), kItemSemantic,
170 ItemSemanticToString(item_semantic_)) &&
171 serializer->WriteProperty(DynamicDepthConst::Image(), kItemUri,
172 item_uri_);
173 }
174
175 // Private methods.
ParseImageFields(const Deserializer & deserializer)176 bool Image::ParseImageFields(const Deserializer& deserializer) {
177 string item_uri;
178 string item_semantic_str;
179 if (!deserializer.ParseString(DynamicDepthConst::Image(), kItemSemantic,
180 &item_semantic_str) ||
181 !deserializer.ParseString(DynamicDepthConst::Image(), kItemUri,
182 &item_uri)) {
183 return false;
184 }
185
186 item_uri_ = item_uri;
187 item_semantic_ = StringToItemSemantic(item_semantic_str);
188 return true;
189 }
190
191 } // namespace dynamic_depth
192