Skip to content

Commit 386b6f6

Browse files
committed
Improve XMP parsing and GUI tree rendering
1 parent 6814857 commit 386b6f6

File tree

2 files changed

+30
-16
lines changed

2 files changed

+30
-16
lines changed

src/image_gui.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ void Image::draw_info()
467467
// Handle objects (nested structures)
468468
if (field_val.is_object())
469469
{
470-
if (ImGui::PE::TreeNode(key.c_str(), ImGuiTreeNodeFlags_DefaultOpen))
470+
if (ImGui::PE::TreeNode(key.c_str(), ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_DrawLinesFull))
471471
{
472472
add_xmp_fields(field_val, depth + 1, prefix + ":" + key);
473473
ImGui::PE::TreePop();
@@ -501,7 +501,8 @@ void Image::draw_info()
501501
// }
502502

503503
// Otherwise, handle mixed or object arrays element-by-element as before.
504-
auto open = ImGui::PE::TreeNode(key.c_str(), ImGuiTreeNodeFlags_DefaultOpen);
504+
auto open =
505+
ImGui::PE::TreeNode(key.c_str(), ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_DrawLinesFull);
505506
ImGui::TableNextColumn();
506507
ImGui::SetNextItemWidth(-FLT_MIN);
507508
ImGui::TextUnformatted(fmt::format("[{} item{}]", arr.size(), arr.size() == 1 ? "" : "s").c_str());
@@ -512,7 +513,8 @@ void Image::draw_info()
512513
std::string idx = fmt::format("#{}", i + 1);
513514
if (arr[i].is_object())
514515
{
515-
if (ImGui::PE::TreeNode(idx.c_str(), ImGuiTreeNodeFlags_DefaultOpen))
516+
if (ImGui::PE::TreeNode(idx.c_str(),
517+
ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_DrawLinesFull))
516518
{
517519
add_xmp_fields(arr[i], depth + 1, prefix + ":" + key);
518520
ImGui::PE::TreePop();

src/imageio/xmp.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ json parse_xml_element(const XMLElement *element)
5151
// key/value pairs in the resulting JSON.
5252
if (attr_name == "xml:lang")
5353
result[attr_name] = attr_value;
54+
else if (attr_name.find("stEvt:") == 0 || attr_name.find("stRef:") == 0)
55+
{
56+
// Special case: Adobe event structure - keep as flat key/value pairs
57+
result[attr_name.substr(6)] = attr_value;
58+
}
5459
else
5560
{
5661
// Extract namespace prefix
@@ -128,13 +133,11 @@ json parse_xml_element(const XMLElement *element)
128133
{
129134
std::string child_name = child->Name();
130135
size_t colon_pos = child_name.find(':');
131-
json child_json;
136+
json child_json = parse_xml_element(child);
132137

133138
// Special handling for rdf:Description - skip the wrapper and merge contents directly
134139
if (child_name == "rdf:Description")
135140
{
136-
child_json = parse_xml_element(child);
137-
138141
// Merge the contents directly into result (skip rdf:Description wrapper)
139142
for (auto &[key, value] : child_json.items())
140143
{
@@ -151,14 +154,10 @@ json parse_xml_element(const XMLElement *element)
151154
result[key] = value;
152155
}
153156
}
154-
child = child->NextSiblingElement();
155-
continue;
156157
}
157-
158-
child_json = parse_xml_element(child);
159158
// Special-case xml:lang: preserve the full key and use the XML value
160159
// directly as the JSON value.
161-
if (child_name == "xml:lang")
160+
else if (child_name == "xml:lang")
162161
{
163162
if (child_json.is_string())
164163
result["xml:lang"] = child_json.get<std::string>();
@@ -169,11 +168,24 @@ json parse_xml_element(const XMLElement *element)
169168
{
170169
std::string ns_prefix = child_name.substr(0, colon_pos);
171170
std::string local_name = child_name.substr(colon_pos + 1);
172-
if (!result.contains(ns_prefix))
171+
172+
// if (ns_prefix == "crs")
173+
// {
174+
// // if (result.is_null())
175+
// // result = json::object();
176+
177+
// spdlog::info("Found crs element: {}:{}", ns_prefix, local_name);
178+
// if (child_json.is_string())
179+
// result[local_name] = child_json.get<std::string>();
180+
// else
181+
// result[local_name] = child_json;
182+
// }
183+
// else
173184
{
174-
result[ns_prefix] = json::object();
185+
if (!result.contains(ns_prefix))
186+
result[ns_prefix] = json::object();
187+
result[ns_prefix][local_name] = child_json;
175188
}
176-
result[ns_prefix][local_name] = child_json;
177189
}
178190
else
179191
{
@@ -200,10 +212,10 @@ void add_xmlns_entries(const XMLElement *e, json &xmlns)
200212
{"http://ns.adobe.com/xap/1.0/mm/", "Media Management"},
201213

202214
// Media-specific namespaces
203-
{"http://ns.adobe.com/exif/1.0/", "EXIF 2.2 or earlier"},
215+
{"http://ns.adobe.com/exif/1.0/", "EXIF"},
216+
{"http://ns.adobe.com/exif/1.0/aux/", "EXIF Auxiliary"},
204217
{"http://cipa.jp/exif/1.0/", "EXIF 2.21 or later"},
205218
{"http://ns.adobe.com/tiff/1.0/", "TIFF Rev. 6.0"},
206-
{"http://ns.adobe.com/exif/1.0/aux/", "EXIF Auxiliary"},
207219
{"http://ns.adobe.com/photoshop/1.0/", "Photoshop"},
208220
{"http://ns.adobe.com/camera-raw-settings/1.0/", "Camera Raw Settings"},
209221

0 commit comments

Comments
 (0)