#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& camera_indices) : type_(type), camera_indices_(camera_indices) {} // Public methods. void Profile::GetNamespaces( std::unordered_map* 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::FromData( const string& type, const std::vector& 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( new Profile(matched_type.empty() ? type : matched_type, camera_indices)); // NOLINT } std::unique_ptr Profile::FromDeserializer( const Deserializer& parent_deserializer) { std::unique_ptr deserializer = parent_deserializer.CreateDeserializer( DynamicDepthConst::Namespace(DynamicDepthConst::Profile()), DynamicDepthConst::Profile()); if (deserializer == nullptr) { return nullptr; } std::unique_ptr 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& 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