• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "dynamic_depth/depth_jpeg.h"
2 
3 #include <fstream>
4 #include <sstream>
5 
6 #include "android-base/logging.h"
7 #include "dynamic_depth/container.h"
8 #include "dynamic_depth/device.h"
9 #include "dynamic_depth/dynamic_depth.h"
10 #include "dynamic_depth/item.h"
11 #include "image_io/gcontainer/gcontainer.h"
12 #include "xmpmeta/xmp_data.h"
13 #include "xmpmeta/xmp_parser.h"
14 #include "xmpmeta/xmp_writer.h"
15 
16 using ::dynamic_depth::xmpmeta::XmpData;
17 
18 namespace dynamic_depth {
19 
ValidateAndroidDynamicDepthBuffer(const char * buffer,size_t buffer_length)20 int32_t ValidateAndroidDynamicDepthBuffer(const char* buffer, size_t buffer_length) {
21   XmpData xmp_data;
22   const string image_data(buffer, buffer_length);
23   ReadXmpFromMemory(image_data, /*XmpSkipExtended*/ false, &xmp_data);
24 
25   // Check device presence
26   std::unique_ptr<Device> device = Device::FromXmp(xmp_data);
27   if (device == nullptr) {
28     LOG(ERROR) << "Dynamic depth device element not present!";
29     return -1;
30   }
31 
32   // Check profiles
33   const Profiles* profiles = device->GetProfiles();
34   if (profiles == nullptr) {
35     LOG(ERROR) << "No Profile found in the dynamic depth metadata";
36     return -1;
37   }
38 
39   const std::vector<const Profile*> profile_list = profiles->GetProfiles();
40   // Stop at the first depth photo profile found.
41   bool depth_photo_profile_found = false;
42   int camera_index = 0;
43   for (auto profile : profile_list) {
44     depth_photo_profile_found = !profile->GetType().compare("DepthPhoto");
45     if (depth_photo_profile_found) {
46       // Use the first one if available.
47       auto indices = profile->GetCameraIndices();
48       if (!indices.empty()) {
49         camera_index = indices[0];
50       } else {
51         camera_index = -1;
52       }
53       break;
54     }
55   }
56 
57   if (!depth_photo_profile_found || camera_index < 0) {
58     LOG(ERROR) << "No dynamic depth profile found";
59     return -1;
60   }
61 
62   auto cameras = device->GetCameras();
63   if (cameras == nullptr || camera_index > cameras->GetCameras().size() ||
64       cameras->GetCameras()[camera_index] == nullptr) {
65     LOG(ERROR) << "No camera or depth photo data found";
66     return -1;
67   }
68 
69   auto camera = cameras->GetCameras()[camera_index];
70   auto depth_map = camera->GetDepthMap();
71   if (depth_map == nullptr) {
72     LOG(ERROR) << "No depth map found";
73     return -1;
74   }
75 
76   auto depth_uri = depth_map->GetDepthUri();
77   if (depth_uri.empty()) {
78     LOG(ERROR) << "Invalid depth map URI";
79     return -1;
80   }
81 
82   auto depth_units = depth_map->GetUnits();
83   if (depth_units != dynamic_depth::DepthUnits::kMeters) {
84     LOG(ERROR) << "Unexpected depth map units";
85     return -1;
86   }
87 
88   auto depth_format = depth_map->GetFormat();
89   if (depth_format != dynamic_depth::DepthFormat::kRangeInverse) {
90     LOG(ERROR) << "Unexpected depth map format";
91     return -1;
92   }
93 
94   auto near = depth_map->GetNear();
95   auto far = depth_map->GetFar();
96   if ((near < 0.f) || (far < 0.f) || (near > far) || (near == far)) {
97     LOG(ERROR) << "Unexpected depth map near and far values";
98     return -1;
99   }
100 
101   auto confidence_uri = depth_map->GetConfidenceUri();
102   if (confidence_uri.empty()) {
103     LOG(ERROR) << "No confidence URI";
104     return -1;
105   }
106 
107   std::istringstream input_jpeg_stream(std::string(buffer, buffer_length));
108   std::string depth_payload;
109   if (!GetItemPayload(device->GetContainer(), depth_uri, input_jpeg_stream, &depth_payload)) {
110     LOG(ERROR) << "Unable to retrieve depth map";
111     return -1;
112   }
113 
114   if (depth_payload.empty()) {
115     LOG(ERROR) << "Invalid depth map";
116     return -1;
117   }
118 
119   return 0;
120 }
121 
122 }  // namespace dynamic_depth
123