#include "dynamic_depth/depth_jpeg.h" #include #include #include "android-base/logging.h" #include "dynamic_depth/container.h" #include "dynamic_depth/device.h" #include "dynamic_depth/dynamic_depth.h" #include "dynamic_depth/item.h" #include "image_io/gcontainer/gcontainer.h" #include "xmpmeta/xmp_data.h" #include "xmpmeta/xmp_parser.h" #include "xmpmeta/xmp_writer.h" using ::dynamic_depth::xmpmeta::XmpData; namespace dynamic_depth { int32_t ValidateAndroidDynamicDepthBuffer(const char* buffer, size_t buffer_length) { XmpData xmp_data; const string image_data(buffer, buffer_length); ReadXmpFromMemory(image_data, /*XmpSkipExtended*/ false, &xmp_data); // Check device presence std::unique_ptr device = Device::FromXmp(xmp_data); if (device == nullptr) { LOG(ERROR) << "Dynamic depth device element not present!"; return -1; } // Check profiles const Profiles* profiles = device->GetProfiles(); if (profiles == nullptr) { LOG(ERROR) << "No Profile found in the dynamic depth metadata"; return -1; } const std::vector profile_list = profiles->GetProfiles(); // Stop at the first depth photo profile found. bool depth_photo_profile_found = false; int camera_index = 0; for (auto profile : profile_list) { depth_photo_profile_found = !profile->GetType().compare("DepthPhoto"); if (depth_photo_profile_found) { // Use the first one if available. auto indices = profile->GetCameraIndices(); if (!indices.empty()) { camera_index = indices[0]; } else { camera_index = -1; } break; } } if (!depth_photo_profile_found || camera_index < 0) { LOG(ERROR) << "No dynamic depth profile found"; return -1; } auto cameras = device->GetCameras(); if (cameras == nullptr || camera_index > cameras->GetCameras().size() || cameras->GetCameras()[camera_index] == nullptr) { LOG(ERROR) << "No camera or depth photo data found"; return -1; } auto camera = cameras->GetCameras()[camera_index]; auto depth_map = camera->GetDepthMap(); if (depth_map == nullptr) { LOG(ERROR) << "No depth map found"; return -1; } auto depth_uri = depth_map->GetDepthUri(); if (depth_uri.empty()) { LOG(ERROR) << "Invalid depth map URI"; return -1; } auto depth_units = depth_map->GetUnits(); if (depth_units != dynamic_depth::DepthUnits::kMeters) { LOG(ERROR) << "Unexpected depth map units"; return -1; } auto depth_format = depth_map->GetFormat(); if (depth_format != dynamic_depth::DepthFormat::kRangeInverse) { LOG(ERROR) << "Unexpected depth map format"; return -1; } auto near = depth_map->GetNear(); auto far = depth_map->GetFar(); if ((near < 0.f) || (far < 0.f) || (near > far) || (near == far)) { LOG(ERROR) << "Unexpected depth map near and far values"; return -1; } auto confidence_uri = depth_map->GetConfidenceUri(); if (confidence_uri.empty()) { LOG(ERROR) << "No confidence URI"; return -1; } std::istringstream input_jpeg_stream(std::string(buffer, buffer_length)); std::string depth_payload; if (!GetItemPayload(device->GetContainer(), depth_uri, input_jpeg_stream, &depth_payload)) { LOG(ERROR) << "Unable to retrieve depth map"; return -1; } if (depth_payload.empty()) { LOG(ERROR) << "Invalid depth map"; return -1; } return 0; } } // namespace dynamic_depth