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)20int32_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