#include "dynamic_depth/depth_jpeg.h"
|
|
#include <fstream>
|
#include <sstream>
|
|
#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 = 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<const Profile*> 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
|