@@ -2344,9 +2344,13 @@ build_test_creator_tool_png_xmp_itxt_payload(std::string_view creator_tool,
23442344static std::vector<std::byte>
23452345make_minimal_tiff_little_endian();
23462346
2347+ static std::vector<std::byte>
2348+ make_minimal_bigtiff_little_endian();
2349+
23472350static bool
2348- build_test_tiff_with_creator_tool_xmp(std::string_view creator_tool,
2349- std::vector<std::byte>* out)
2351+ build_test_tiff_like_with_creator_tool_xmp(
2352+ std::string_view creator_tool, std::span<const std::byte> input_tiff,
2353+ std::vector<std::byte>* out)
23502354{
23512355 if (!out) {
23522356 return false;
@@ -2384,15 +2388,13 @@ build_test_tiff_with_creator_tool_xmp(std::string_view creator_tool,
23842388 return false;
23852389 }
23862390
2387- const std::vector<std::byte> input = make_minimal_tiff_little_endian();
23882391 openmeta::ExecutePreparedTransferOptions options;
23892392 options.edit_requested = true;
23902393 options.edit_apply = true;
23912394
23922395 const openmeta::ExecutePreparedTransferResult result
23932396 = openmeta::execute_prepared_transfer(
2394- &bundle,
2395- std::span<const std::byte>(input.data(), input.size()), options);
2397+ &bundle, input_tiff, options);
23962398 if (result.edit_apply.status != openmeta::TransferStatus::Ok
23972399 || result.edited_output.empty()) {
23982400 return false;
@@ -2402,6 +2404,26 @@ build_test_tiff_with_creator_tool_xmp(std::string_view creator_tool,
24022404 return true;
24032405}
24042406
2407+ static bool
2408+ build_test_tiff_with_creator_tool_xmp(std::string_view creator_tool,
2409+ std::vector<std::byte>* out)
2410+ {
2411+ const std::vector<std::byte> input = make_minimal_tiff_little_endian();
2412+ return build_test_tiff_like_with_creator_tool_xmp(
2413+ creator_tool,
2414+ std::span<const std::byte>(input.data(), input.size()), out);
2415+ }
2416+
2417+ static bool
2418+ build_test_bigtiff_with_creator_tool_xmp(std::string_view creator_tool,
2419+ std::vector<std::byte>* out)
2420+ {
2421+ const std::vector<std::byte> input = make_minimal_bigtiff_little_endian();
2422+ return build_test_tiff_like_with_creator_tool_xmp(
2423+ creator_tool,
2424+ std::span<const std::byte>(input.data(), input.size()), out);
2425+ }
2426+
24052427static bool
24062428build_test_target_with_existing_creator_tool_xmp(
24072429 openmeta::TransferTargetFormat format, std::string_view creator_tool,
@@ -9963,6 +9985,80 @@ TEST(MetadataTransferApi,
99639985 result.execute.edited_output.size())));
99649986}
99659987
9988+ TEST(MetadataTransferApi,
9989+ ExecutePreparedTransferFileBigTiffSidecarOnlyCanStripExistingDestinationEmbeddedXmp)
9990+ {
9991+ std::vector<std::byte> source_jpeg;
9992+ ASSERT_TRUE(build_test_transfer_source_jpeg_bytes(&source_jpeg));
9993+ const std::string source_path = unique_temp_path(".jpg");
9994+ ASSERT_TRUE(write_bytes_file(
9995+ source_path,
9996+ std::span<const std::byte>(source_jpeg.data(), source_jpeg.size())));
9997+
9998+ std::vector<std::byte> target_tiff;
9999+ ASSERT_TRUE(build_test_bigtiff_with_creator_tool_xmp(
10000+ "Target Embedded Existing", &target_tiff));
10001+ const std::string target_path = unique_temp_path(".tif");
10002+ ASSERT_TRUE(write_bytes_file(
10003+ target_path,
10004+ std::span<const std::byte>(target_tiff.data(), target_tiff.size())));
10005+
10006+ openmeta::ExecutePreparedTransferFileOptions options;
10007+ options.prepare.prepare.target_format = openmeta::TransferTargetFormat::Tiff;
10008+ options.prepare.prepare.include_icc_app2 = false;
10009+ options.prepare.prepare.include_iptc_app13 = false;
10010+ options.edit_target_path = target_path;
10011+ options.execute.edit_apply = true;
10012+ options.xmp_writeback_mode
10013+ = openmeta::XmpWritebackMode::SidecarOnly;
10014+ options.xmp_destination_embedded_mode
10015+ = openmeta::XmpDestinationEmbeddedMode::StripExisting;
10016+
10017+ const openmeta::ExecutePreparedTransferFileResult result
10018+ = openmeta::execute_prepared_transfer_file(source_path.c_str(), options);
10019+ std::remove(source_path.c_str());
10020+ std::remove(target_path.c_str());
10021+
10022+ ASSERT_EQ(result.prepared.file_status, openmeta::TransferFileStatus::Ok);
10023+ ASSERT_EQ(result.prepared.prepare.status, openmeta::TransferStatus::Ok);
10024+ ASSERT_EQ(result.execute.edit_apply.status, openmeta::TransferStatus::Ok);
10025+ ASSERT_FALSE(result.execute.edited_output.empty());
10026+ ASSERT_FALSE(result.xmp_sidecar_output.empty());
10027+
10028+ const std::span<const std::byte> edited_bytes(
10029+ result.execute.edited_output.data(), result.execute.edited_output.size());
10030+ ASSERT_GE(edited_bytes.size(), 16U);
10031+ EXPECT_EQ(read_u16le(edited_bytes, 2U), 43U);
10032+
10033+ const uint64_t ifd0_off = read_u64le(edited_bytes, 8U);
10034+ ASSERT_NE(ifd0_off, 0U);
10035+ uint64_t ignored_value = 0U;
10036+ EXPECT_FALSE(find_bigtiff_tag_entry_le(edited_bytes, ifd0_off, 700U,
10037+ nullptr, nullptr,
10038+ &ignored_value));
10039+
10040+ openmeta::MetaStore edited_store;
10041+ ASSERT_TRUE(decode_transfer_roundtrip_store(edited_bytes, &edited_store));
10042+ EXPECT_FALSE(store_has_text_entry(
10043+ edited_store,
10044+ xmp_key_view("http://ns.adobe.com/xap/1.0/", "CreatorTool"),
10045+ "Target Embedded Existing"));
10046+ EXPECT_FALSE(store_has_text_entry(
10047+ edited_store,
10048+ xmp_key_view("http://ns.adobe.com/xap/1.0/", "CreatorTool"),
10049+ "OpenMeta Transfer Source"));
10050+
10051+ openmeta::MetaStore sidecar_store;
10052+ ASSERT_TRUE(decode_transfer_roundtrip_store(
10053+ std::span<const std::byte>(result.xmp_sidecar_output.data(),
10054+ result.xmp_sidecar_output.size()),
10055+ &sidecar_store));
10056+ EXPECT_TRUE(store_has_text_entry(
10057+ sidecar_store,
10058+ xmp_key_view("http://ns.adobe.com/xap/1.0/", "CreatorTool"),
10059+ "OpenMeta Transfer Source"));
10060+ }
10061+
996610062TEST(MetadataTransferApi,
996710063 ExecutePreparedTransferFileBigTiffRoundTripsDngSourceMetadata)
996810064{
0 commit comments