diff options
Diffstat (limited to 'internal/dynamic_depth/dynamic_depth.cc')
-rw-r--r-- | internal/dynamic_depth/dynamic_depth.cc | 135 |
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 |