12#include <spdlog/spdlog.h>
13#include <exiv2/exiv2.hpp>
15#include <magic_enum/magic_enum.hpp>
20 std::unique_ptr<IXmpProvider> xmp_provider,
21 std::unique_ptr<IXmpPathStrategy> xmp_path_strategy)
22 : m_xmp_provider(std::move(xmp_provider))
23 , m_xmp_path_strategy(std::move(xmp_path_strategy))
25 if (!m_xmp_provider || !m_xmp_path_strategy) {
26 spdlog::error(
"FileSerializerWriter: Constructor received a null IXmpProvider or IXmpPathStrategy.");
27 throw std::invalid_argument(
"FileSerializerWriter: IXmpProvider and IXmpPathStrategy cannot be null.");
29 spdlog::debug(
"FileSerializerWriter: Constructed with IXmpProvider and IXmpPathStrategy.");
34 if (source_image_path.empty()) {
35 spdlog::error(
"FileSerializerWriter::saveToFile: Source image path is empty.");
38 spdlog::debug(
"FileSerializerWriter::saveToFile: Attempting to save {} operations for image: {}", operations.size(), source_image_path);
44 std::string xmp_file_path { m_xmp_path_strategy->getXmpPathForImage(source_image_path) };
45 spdlog::debug(
"FileSerializerWriter::saveToFile: Determined XMP file path: {}", xmp_file_path);
48 std::string xmp_packet { serializeOperationsToXmp(operations, source_image_path) };
49 if (xmp_packet.empty()) {
50 spdlog::error(
"FileSerializerWriter::saveToFile: Failed to serialize operations to XMP for image: {}", source_image_path);
55 bool write_success { m_xmp_provider->writeXmp(xmp_file_path, xmp_packet) };
58 spdlog::info(
"FileSerializerWriter::saveToFile: Successfully saved operations to XMP file: {} for image: {}", xmp_file_path, source_image_path);
60 spdlog::error(
"FileSerializerWriter::saveToFile: IXmpProvider failed to write XMP data to file: {} for image: {}", xmp_file_path, source_image_path);
66std::string FileSerializerWriter::serializeOperationsToXmp(
67 std::span<const Operations::OperationDescriptor> operations,
68 std::string_view source_image_path)
const
70 spdlog::debug(
"FileSerializerWriter::serializeOperationsToXmp: Serializing {} operations for image: {}", operations.size(), source_image_path);
73 const std::string ns_uri {
"https://github.com/YacinoBen/CaptureMoment/" };
74 const std::string ns_prefix {
"cm" };
78 Exiv2::XmpProperties::registerNs(ns_uri, ns_prefix);
80 Exiv2::XmpData xmp_data;
84 xmp_data[
"Xmp.cm.serializedBy"] =
"CaptureMoment";
85 xmp_data[
"Xmp.cm.version"] =
"1.0";
87 xmp_data[
"Xmp.cm.sourceImagePath"] = std::string(source_image_path);
90 for (
size_t i = 0; i < operations.size(); ++i) {
91 const auto& op = operations[i];
92 std::string index_str { std::to_string(i + 1) };
95 std::string_view type_name_view { magic_enum::enum_name(op.type) };
96 xmp_data[
"Xmp.cm.operation[" + index_str +
"].type"] = std::string(type_name_view);
97 xmp_data[
"Xmp.cm.operation[" + index_str +
"].name"] = op.name;
98 xmp_data[
"Xmp.cm.operation[" + index_str +
"].enabled"] = op.enabled;
101 for (
const auto& [param_name, param_value] : op.params)
107 std::string xmp_param_key {
"Xmp.cm.operation[" + index_str +
"].param." + param_name };
108 xmp_data[xmp_param_key] = serialized_param_value;
113 std::string xmp_packet;
114 if (Exiv2::XmpParser::encode(xmp_packet, xmp_data) != 0) {
115 spdlog::error(
"FileSerializerWriter::serializeOperationsToXmp: Failed to encode XMP packet.");
119 spdlog::debug(
"FileSerializerWriter::serializeOperationsToXmp: Successfully serialized to XMP packet (size {}).", xmp_packet.size());
122 }
catch (
const Exiv2::Error& e) {
123 spdlog::error(
"FileSerializerWriter::serializeOperationsToXmp: Exiv2 error during serialization: {}", e.what());
125 }
catch (
const std::exception& e) {
126 spdlog::error(
"FileSerializerWriter::serializeOperationsToXmp: General error during serialization: {}", e.what());
static void initialize()
Initializes the Exiv2 XMP parser if not already done. This function is thread-safe.
FileSerializerWriter(std::unique_ptr< IXmpProvider > xmp_provider, std::unique_ptr< IXmpPathStrategy > xmp_path_strategy)
Constructs a FileSerializerWriter.
bool saveToFile(std::string_view source_image_path, std::span< const Operations::OperationDescriptor > operations) const override
Saves the provided list of operations to an XMP file determined by the path strategy.
Declaration of Exiv2Initializer class.
Declaration of FileSerializerWriter class.
std::string serializeParameter(const Operations::OperationValue &value)
Namespace containing utilities for serializing and deserializing OperationDescriptor parameters....
Declaration of OperationSerialization interface.