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 std::string itemMime("image/jpeg"); 23 const string image_data(buffer, buffer_length); 24 ReadXmpFromMemory(image_data, /*XmpSkipExtended*/ false, &xmp_data); 25 26 // Check device presence 27 std::unique_ptr<Device> device = Device::FromXmp(xmp_data); 28 if (device == nullptr) { 29 LOG(ERROR) << "Dynamic depth device element not present!"; 30 return -1; 31 } 32 33 // Check the container items mime type 34 if ((device->GetContainer() == nullptr) || (device->GetContainer()->GetItems().empty())) { 35 LOG(ERROR) << "No container or container items found!"; 36 return -1; 37 } 38 auto items = device->GetContainer()->GetItems(); 39 for (const auto& item : items) { 40 if (item->GetMime() != itemMime) { 41 LOG(ERROR) << "Item MIME type doesn't match the expected value: " << itemMime; 42 return -1; 43 } 44 } 45 // Check profiles 46 const Profiles* profiles = device->GetProfiles(); 47 if (profiles == nullptr) { 48 LOG(ERROR) << "No Profile found in the dynamic depth metadata"; 49 return -1; 50 } 51 52 const std::vector<const Profile*> profile_list = profiles->GetProfiles(); 53 // Stop at the first depth photo profile found. 54 bool depth_photo_profile_found = false; 55 int camera_index = 0; 56 for (auto profile : profile_list) { 57 depth_photo_profile_found = !profile->GetType().compare("DepthPhoto"); 58 if (depth_photo_profile_found) { 59 // Use the first one if available. 60 auto indices = profile->GetCameraIndices(); 61 if (!indices.empty()) { 62 camera_index = indices[0]; 63 } else { 64 camera_index = -1; 65 } 66 break; 67 } 68 } 69 70 if (!depth_photo_profile_found || camera_index < 0) { 71 LOG(ERROR) << "No dynamic depth profile found"; 72 return -1; 73 } 74 75 auto cameras = device->GetCameras(); 76 if (cameras == nullptr || camera_index > cameras->GetCameras().size() || 77 cameras->GetCameras()[camera_index] == nullptr) { 78 LOG(ERROR) << "No camera or depth photo data found"; 79 return -1; 80 } 81 82 auto camera = cameras->GetCameras()[camera_index]; 83 auto depth_map = camera->GetDepthMap(); 84 if (depth_map == nullptr) { 85 LOG(ERROR) << "No depth map found"; 86 return -1; 87 } 88 89 auto depth_uri = depth_map->GetDepthUri(); 90 if (depth_uri.empty()) { 91 LOG(ERROR) << "Invalid depth map URI"; 92 return -1; 93 } 94 95 auto depth_units = depth_map->GetUnits(); 96 if (depth_units != dynamic_depth::DepthUnits::kMeters) { 97 LOG(ERROR) << "Unexpected depth map units"; 98 return -1; 99 } 100 101 auto depth_format = depth_map->GetFormat(); 102 if (depth_format != dynamic_depth::DepthFormat::kRangeInverse) { 103 LOG(ERROR) << "Unexpected depth map format"; 104 return -1; 105 } 106 107 auto near = depth_map->GetNear(); 108 auto far = depth_map->GetFar(); 109 if ((near < 0.f) || (far < 0.f) || (near > far) || (near == far)) { 110 LOG(ERROR) << "Unexpected depth map near and far values"; 111 return -1; 112 } 113 114 auto confidence_uri = depth_map->GetConfidenceUri(); 115 if (confidence_uri.empty()) { 116 LOG(ERROR) << "No confidence URI"; 117 return -1; 118 } 119 120 std::istringstream input_jpeg_stream(std::string(buffer, buffer_length)); 121 std::string depth_payload; 122 if (!GetItemPayload(device->GetContainer(), depth_uri, input_jpeg_stream, &depth_payload)) { 123 LOG(ERROR) << "Unable to retrieve depth map"; 124 return -1; 125 } 126 127 if (depth_payload.empty()) { 128 LOG(ERROR) << "Invalid depth map"; 129 return -1; 130 } 131 132 return 0; 133 } 134 135 } // namespace dynamic_depth 136