summaryrefslogtreecommitdiff
path: root/internal/dynamic_depth/dynamic_depth.cc
diff options
context:
space:
mode:
Diffstat (limited to 'internal/dynamic_depth/dynamic_depth.cc')
-rw-r--r--internal/dynamic_depth/dynamic_depth.cc135
1 files changed, 116 insertions, 19 deletions
diff --git a/internal/dynamic_depth/dynamic_depth.cc b/internal/dynamic_depth/dynamic_depth.cc
index 3b2b114..fa3983e 100644
--- a/internal/dynamic_depth/dynamic_depth.cc
+++ b/internal/dynamic_depth/dynamic_depth.cc
@@ -8,14 +8,14 @@
#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"
-namespace photos_editing_formats {
namespace dynamic_depth {
namespace {
-using photos_editing_formats::CreateXmpData;
-using photos_editing_formats::XmpData;
+using ::dynamic_depth::xmpmeta::CreateXmpData;
+using ::dynamic_depth::xmpmeta::XmpData;
constexpr char kImageMimePrefix[] = "image";
@@ -29,22 +29,15 @@ bool IsMimeTypeImage(const string& mime) {
} // namespace
-bool WriteImageAndMetadataAndContainer(const string& out_filename,
- const uint8_t* primary_image_bytes,
- size_t primary_image_bytes_count,
- Device* device) {
+bool WriteImageAndMetadataAndContainer(std::istream* input_jpeg_stream,
+ Device* device,
+ std::ostream* output_jpeg_stream) {
const std::unique_ptr<XmpData> xmp_data = CreateXmpData(true);
device->SerializeToXmp(xmp_data.get());
- std::istringstream input_jpeg_stream(
- std::string(reinterpret_cast<const char*>(primary_image_bytes),
- primary_image_bytes_count));
- std::ofstream output_jpeg_stream;
- output_jpeg_stream.open(out_filename, std::ostream::out);
- bool success = WriteLeftEyeAndXmpMeta(
- out_filename, *xmp_data, &input_jpeg_stream, &output_jpeg_stream);
+ bool success =
+ WriteLeftEyeAndXmpMeta(*xmp_data, input_jpeg_stream, output_jpeg_stream);
if (device->GetContainer() == nullptr) {
- output_jpeg_stream.close();
return success;
}
@@ -55,9 +48,23 @@ bool WriteImageAndMetadataAndContainer(const string& out_filename,
if (payload_size <= 0 || payload.empty()) {
continue;
}
- output_jpeg_stream.write(payload.c_str(), payload_size);
+ output_jpeg_stream->write(payload.c_str(), payload_size);
}
+ return success;
+}
+
+bool WriteImageAndMetadataAndContainer(const string& out_filename,
+ const uint8_t* primary_image_bytes,
+ size_t primary_image_bytes_count,
+ Device* device) {
+ std::istringstream input_jpeg_stream(
+ std::string(reinterpret_cast<const char*>(primary_image_bytes),
+ primary_image_bytes_count));
+ std::ofstream output_jpeg_stream;
+ output_jpeg_stream.open(out_filename, std::ostream::out);
+ bool success = WriteImageAndMetadataAndContainer(&input_jpeg_stream, device,
+ &output_jpeg_stream);
output_jpeg_stream.close();
return success;
}
@@ -115,11 +122,101 @@ bool GetItemPayload(const string& input_image_filename,
}
std::string std_payload;
- bool success = image_io::gcontainer::ParseFileAfterImage(
- input_image_filename, file_offset, file_length, &std_payload);
+ bool success =
+ ::photos_editing_formats::image_io::gcontainer::ParseFileAfterImage(
+ input_image_filename, file_offset, file_length, &std_payload);
*out_payload = std_payload;
return success;
}
+extern "C" 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;
+ }
+
+ return 0;
+}
+
} // namespace dynamic_depth
-} // namespace photos_editing_formats