1 #ifndef DYNAMIC_DEPTH_INCLUDES_DYNAMIC_DEPTH_DEVICE_H_ // NOLINT 2 #define DYNAMIC_DEPTH_INCLUDES_DYNAMIC_DEPTH_DEVICE_H_ // NOLINT 3 4 #include <libxml/parser.h> 5 #include <libxml/tree.h> 6 #include <libxml/xmlmemory.h> 7 #include <libxml/xpath.h> 8 9 #include <memory> 10 #include <string> 11 #include <unordered_map> 12 #include <utility> 13 14 #include "dynamic_depth/app_info.h" 15 #include "dynamic_depth/cameras.h" 16 #include "dynamic_depth/container.h" 17 #include "dynamic_depth/earth_pose.h" 18 #include "dynamic_depth/planes.h" 19 #include "dynamic_depth/pose.h" 20 #include "dynamic_depth/profiles.h" 21 #include "dynamic_depth/vendor_info.h" 22 #include "xmpmeta/xmp_data.h" 23 24 namespace dynamic_depth { 25 26 struct DeviceParams { 27 // Cameras must be present (i.e. contain at least one camera). 28 std::unique_ptr<Cameras> cameras; 29 30 // GContainer. Optional, depending on element presence or user choice. 31 std::unique_ptr<Container> container; 32 33 // Optional elements. 34 std::unique_ptr<Profiles> profiles; 35 std::unique_ptr<Planes> planes; 36 std::unique_ptr<EarthPose> earth_pose; 37 std::unique_ptr<Pose> pose; 38 std::unique_ptr<VendorInfo> vendor_info; 39 std::unique_ptr<AppInfo> app_info; 40 DeviceParamsDeviceParams41 explicit DeviceParams(std::unique_ptr<Cameras> new_cameras) 42 : container(nullptr), 43 profiles(nullptr), 44 planes(nullptr), 45 earth_pose(nullptr), 46 pose(nullptr), 47 vendor_info(nullptr), 48 app_info(nullptr) { 49 cameras = std::move(new_cameras); 50 } 51 52 inline bool operator==(const DeviceParams& other) const { 53 return cameras.get() == other.cameras.get() && 54 container.get() == other.container.get() && 55 profiles.get() == other.profiles.get() && 56 planes.get() == other.planes.get() && 57 earth_pose.get() == other.earth_pose.get() && 58 pose.get() == other.pose.get() && 59 vendor_info.get() == other.vendor_info.get() && 60 app_info.get() == other.app_info.get(); 61 } 62 63 inline bool operator!=(const DeviceParams& other) const { 64 return !(*this == other); 65 } 66 }; 67 68 // Implements a Device from the Dynamic Depth specification, with serialization 69 // and deserialization. 70 // Does not implement the Element interface because Device is at the top level 71 // in the tree. 72 class Device { 73 public: 74 // Creates a Device from the given elements. 75 static std::unique_ptr<Device> FromData(std::unique_ptr<DeviceParams> params); 76 77 // Creates a Device from pre-extracted XMP metadata. Returns null if 78 // parsing fails. Both the standard and extended XMP sections are required. 79 static std::unique_ptr<Device> FromXmp( 80 const ::dynamic_depth::xmpmeta::XmpData& xmp); 81 82 // Creates a Device by extracting XMP metadata from a JPEG and parsing it. 83 // If using XMP for other things as well, FromXmp() should be used instead to 84 // prevent redundant extraction of XMP from the JPEG. 85 static std::unique_ptr<Device> FromJpegFile(const string& filename); 86 87 // Creates a Device by parsing XML file containing the metadata. 88 static std::unique_ptr<Device> FromXmlFile(const string& filename); 89 90 // Getters. 91 // May return null values for optional fields. 92 const Cameras* GetCameras() const; 93 const Container* GetContainer() const; 94 const EarthPose* GetEarthPose() const; 95 const Pose* GetPose() const; 96 const Planes* GetPlanes() const; 97 const Profiles* GetProfiles() const; 98 const VendorInfo* GetVendorInfo() const; 99 const AppInfo* GetAppInfo() const; 100 101 // Not const for XML memory management reasons. More info in source comments. 102 bool SerializeToXmp(::dynamic_depth::xmpmeta::XmpData* xmp); 103 104 // Saves Device metadata to a .xml file. 105 bool SerializeToXmlFile(const char* filename); 106 107 // Disallow copying. 108 Device(const Device&) = delete; 109 void operator=(const Device&) = delete; 110 111 private: 112 explicit Device(std::unique_ptr<DeviceParams> params); 113 114 // Retrieves the namespaces of all child elements. 115 void GetNamespaces( 116 std::unordered_map<string, string>* ns_name_href_map) const; 117 // Gathers all the XML namespaces of child elements. 118 void PopulateNamespaces(); 119 bool Serialize(xmlDocPtr* xmlDoc); 120 121 // Keep a reference to the XML namespaces, so that they are created only once 122 // when Device is constructed. 123 std::unordered_map<string, xmlNsPtr> namespaces_; 124 125 std::unique_ptr<DeviceParams> params_; 126 }; 127 128 } // namespace dynamic_depth 129 130 #endif // DYNAMIC_DEPTH_INCLUDES_DYNAMIC_DEPTH_DEVICE_H_ // NOLINT 131