CaptureMoment 0.1.0
Free and open-source non-destructive photo editor
Loading...
Searching...
No Matches
exiv2_provider.cpp
Go to the documentation of this file.
1
11#include <spdlog/spdlog.h>
12#include <exiv2/exiv2.hpp>
13#include <string>
14
16
17std::string Exiv2Provider::readXmp(std::string_view file_path) const
18{
19 if (file_path.empty()) {
20 spdlog::error("Exiv2Provider::readXmp: File path is empty.");
21 return {};
22 }
23
24 spdlog::debug("Exiv2Provider::readXmp: Attempting to read XMP from file: {}", file_path);
25
26 // Ensure Exiv2 is initialized
28
29 try {
30 // Open the image file
31 Exiv2::Image::UniquePtr image = Exiv2::ImageFactory::open(file_path.data());
32 if (!image) {
33 spdlog::warn("Exiv2Provider::readXmp: Failed to open image file with Exiv2: {}", file_path);
34 return {};
35 }
36
37 // Read metadata from file into memory
38 image->readMetadata();
39
40 const Exiv2::XmpData& xmp_data = image->xmpData();
41
42 if (xmp_data.empty()) {
43 spdlog::debug("Exiv2Provider::readXmp: No XMP data found in file: {}", file_path);
44 return {};
45 }
46
47 // Encode XmpData structure into a raw XML string (packet)
48 std::string xmp_packet;
49 if (Exiv2::XmpParser::encode(xmp_packet, xmp_data) != 0) {
50 spdlog::error("Exiv2Provider::readXmp: Failed to encode XMP data to packet for file: {}", file_path);
51 return {};
52 }
53
54 spdlog::debug("Exiv2Provider::readXmp: Successfully read XMP packet (size {}) from file: {}", xmp_packet.size(), file_path);
55 return xmp_packet;
56 } catch (const Exiv2::Error& e) {
57 spdlog::error("Exiv2Provider::readXmp: Exiv2 error reading XMP from file '{}': {}", file_path, e.what());
58 return {};
59 } catch (const std::exception& e) {
60 spdlog::error("Exiv2Provider::readXmp: Standard exception reading XMP from file '{}': {}", file_path, e.what());
61 return {};
62 }
63}
64
65bool Exiv2Provider::writeXmp(std::string_view file_path, std::string_view xmp_data) const
66{
67 if (file_path.empty()) {
68 spdlog::error("Exiv2Provider::writeXmp: File path is empty.");
69 return false;
70 }
71
72 spdlog::debug("Exiv2Provider::writeXmp: Attempting to write XMP packet (size {}) to file: {}", xmp_data.size(), file_path);
73
74 // Ensure Exiv2 is initialized
76
77 try {
78 // Open the image file for writing
79 Exiv2::Image::UniquePtr image = Exiv2::ImageFactory::open(file_path.data());
80 if (!image) {
81 spdlog::error("Exiv2Provider::writeXmp: Failed to open image file with Exiv2 for writing: {}", file_path);
82 return false;
83 }
84
85 // Read existing metadata to preserve EXIF/IPTC if possible
86 image->readMetadata();
87
88 Exiv2::XmpData xmp_container;
89
90 // If we have new XMP data, decode it into the container
91 if (!xmp_data.empty()) {
92 if (Exiv2::XmpParser::decode(xmp_container, xmp_data.data()) != 0) {
93 spdlog::error("Exiv2Provider::writeXmp: Failed to decode provided XMP packet for file: {}", file_path);
94 return false;
95 }
96 } else {
97 spdlog::warn("Exiv2Provider::writeXmp: Attempting to write empty XMP packet. This will effectively remove XMP metadata.");
98 }
99
100 // Set the XMP data (replaces any existing XMP)
101 image->setXmpData(xmp_container);
102
103 // Write all metadata (Exif, Iptc, Xmp) back to the file
104 image->writeMetadata();
105
106 spdlog::info("Exiv2Provider::writeXmp: Successfully wrote XMP packet to file: {}", file_path);
107 return true;
108 } catch (const Exiv2::Error& e) {
109 spdlog::error("Exiv2Provider::writeXmp: Exiv2 error writing XMP to file '{}': {}", file_path, e.what());
110 return false;
111 } catch (const std::exception& e) {
112 spdlog::error("Exiv2Provider::writeXmp: Standard exception writing XMP to file '{}': {}", file_path, e.what());
113 return false;
114 }
115}
116
117} // namespace CaptureMoment::Core::Serializer
static void initialize()
Initializes the Exiv2 XMP parser if not already done. This function is thread-safe.
std::string readXmp(std::string_view file_path) const override
Reads the raw XMP packet data from the specified file.
bool writeXmp(std::string_view filePath, std::string_view xmpData) const override
Writes the provided raw XMP packet data to the specified file.
Declaration of Exiv2Initializer class.
Declaration of Exiv2Provider class.
CaptureMoment — footer