• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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