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 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 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. 48 Image::Image() {} 49 50 // Public methods. 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 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 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 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 138 const string& Image::GetItemUri() const { return item_uri_; } 139 ImageItemSemantic Image::GetItemSemantic() const { return item_semantic_; } 140 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 158 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. 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