Skip to content

Commit e7f424c

Browse files
committed
Remove OIIO adapter; add FlatHost export
Remove the in-library OIIO adapter and replace the OIIO naming surface with a neutral flat-host export style. Deleted oiio_adapter header/impl and tests, removed oiio entries from CMakeLists and test lists. Update interop_export to rename OIIO -> FlatHost (ExportNameStyle, mapping functions, builders) and expose visit_metadata/ExportOptions as the intended host-owned traversal surface. Replace references across docs and sphinx sources to describe host-owned metadata mapping, EXR host-apply adapters, and the FlatHost naming policy. metadata_transfer now includes interop_export and safety/format internals and adds helpers for EXR projected text handling. Overall goal: move host-specific payload/attribute mapping out of library internals and steer integrations toward visit_metadata and dedicated host adapters.
1 parent c6f218d commit e7f424c

23 files changed

Lines changed: 1292 additions & 3425 deletions

CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,6 @@ set(OPENMETA_SOURCES
261261
src/openmeta/meta_edit.cc
262262
src/openmeta/meta_value.cc
263263
src/openmeta/ocio_adapter.cc
264-
src/openmeta/oiio_adapter.cc
265264
src/openmeta/photoshop_irb_decode.cc
266265
src/openmeta/preview_extract.cc
267266
src/openmeta/printim_decode.cc
@@ -614,7 +613,6 @@ if(OPENMETA_BUILD_TESTS)
614613
tests/meta_store_test.cc
615614
tests/mpf_decode_test.cc
616615
tests/ocio_adapter_test.cc
617-
tests/oiio_adapter_test.cc
618616
tests/photoshop_irb_decode_test.cc
619617
tests/preview_extract_test.cc
620618
tests/printim_decode_test.cc

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ That guide covers the shortest useful paths for:
4848
- reading and querying metadata in C++
4949
- building and editing `MetaStore`
5050
- copying metadata into an existing JPEG, TIFF, or DNG target
51-
- building EXR and OIIO-style host-API metadata outputs
51+
- building EXR and host-API metadata outputs
5252
- using the optional Adobe DNG SDK bridge
5353

5454
If you already own the encoder, SDK objects, or output container, follow

docs/development.md

Lines changed: 57 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -813,8 +813,8 @@ Read release gate:
813813
- `SimpleMetaRead.*`
814814
- `XmpDecodeTest.*`
815815
- `JumbfDecode.*`
816-
- `OiioAdapter.*`
817816
- `OcioAdapter.*`
817+
- `ExrAdapter.*`
818818
- `ValidateFile.*`
819819

820820
Build + run:
@@ -1059,84 +1059,56 @@ If you are building offline (or want strict control of the build environment),
10591059
install `scikit-build-core` into your Python environment and enable:
10601060
`-DOPENMETA_WHEEL_NO_BUILD_ISOLATION=ON`.
10611061

1062-
## Interop Adapters
1062+
## Interop Surfaces
10631063

1064-
Interop adapter APIs for ASF integration targets:
1064+
Interop surfaces are split deliberately:
10651065

1066-
- `openmeta/interop_export.h`: shared traversal and naming styles
1067-
(`Canonical`, `XmpPortable`, `Oiio`).
1068-
- `openmeta/oiio_adapter.h`: flat OIIO-style name/value export.
1069-
- `openmeta/ocio_adapter.h`: deterministic OCIO-style metadata tree export.
1070-
- `openmeta/exr_adapter.h`: EXR-native per-part attribute export.
1066+
- export-only naming/traversal surface:
1067+
`openmeta/interop_export.h` with the shared export naming styles. This is
1068+
the intended base for host-owned metadata mapping layers.
1069+
- export-only adapter:
1070+
`openmeta/ocio_adapter.h` for deterministic OCIO-style metadata trees.
1071+
- host-apply adapter:
1072+
`openmeta/exr_adapter.h` for EXR-native per-part attribute export.
1073+
- direct bridge:
1074+
`openmeta/dng_sdk_adapter.h` for applications that already use Adobe DNG
1075+
SDK objects/files.
1076+
- narrow translator:
1077+
`openmeta/libraw_adapter.h` for explicit orientation mapping into LibRaw's
1078+
flip convention.
10711079

10721080
Current Python binding entry points:
10731081

10741082
- `Document.export_names(style=..., include_makernotes=...)`
1075-
- `Document.oiio_attributes(...)`
1076-
- `Document.unsafe_oiio_attributes(...)`
1077-
- `Document.oiio_attributes_typed(...)`
1078-
- `Document.unsafe_oiio_attributes_typed(...)`
10791083
- `Document.ocio_metadata_tree(...)`
10801084
- `Document.unsafe_ocio_metadata_tree(...)`
10811085
- `Document.dump_xmp_sidecar(format=...)`
10821086

1083-
Current C++ adapter entry points:
1084-
1085-
- `openmeta/oiio_adapter.h`:
1086-
- safe API: `collect_oiio_attributes_safe(..., InteropSafetyError*)`
1087-
- unsafe API: `collect_oiio_attributes(...)`
1088-
- `collect_oiio_attributes(..., const OiioAdapterRequest&)` (stable flat request API)
1089-
- `collect_oiio_attributes(..., const OiioAdapterOptions&)` (advanced/legacy shape)
1090-
- safe typed API: `collect_oiio_attributes_typed_safe(..., InteropSafetyError*)`
1091-
- unsafe typed API: `collect_oiio_attributes_typed(...)`
1092-
- `collect_oiio_attributes_typed(..., const OiioAdapterRequest&)` (typed values)
1093-
- `collect_oiio_attributes_typed(..., const OiioAdapterOptions&)` (typed values)
1094-
- typed payload model: `OiioTypedValue` / `OiioTypedAttribute`
1095-
- prepared transfer bridge:
1096-
`collect_oiio_transfer_payload_views(...)`
1097-
returns one zero-copy payload list over a `PreparedTransferBundle`
1098-
for host/plugin write integrations
1099-
- owned transfer bridge:
1100-
`build_oiio_transfer_payload_batch(...)`
1101-
copies that same payload contract into one stable owned batch for caching
1102-
or cross-layer handoff
1103-
- persisted payload bridge:
1104-
`collect_oiio_transfer_payload_views(const PreparedTransferPayloadBatch&, ...)`
1105-
and `replay_oiio_transfer_payload_batch(...)`
1106-
consume the same semantic payload contract after
1107-
`serialize_prepared_transfer_payload_batch(...)` /
1108-
`deserialize_prepared_transfer_payload_batch(...)`
1087+
Current C++ interop entry points:
1088+
1089+
- `openmeta/interop_export.h`:
1090+
- `visit_metadata(...)`
1091+
- use the shared naming styles when a host-owned metadata mapping layer
1092+
needs deterministic exported names
11091093
- `openmeta/exr_adapter.h`:
11101094
- `build_exr_attribute_batch(...)`
1111-
exports one owned EXR-native attribute batch from `MetaStore`
1112-
- the batch carries:
1113-
`part_index`, `name`, `type_name`, `value` bytes, and `is_opaque`
11141095
- `build_exr_attribute_part_spans(...)`
1115-
groups the batch into deterministic contiguous per-part spans
11161096
- `build_exr_attribute_part_views(...)`
1117-
exposes zero-copy grouped per-part views over the same batch
11181097
- `replay_exr_attribute_batch(...)`
1119-
replays the grouped batch through explicit host callbacks
1120-
- unlike the prepared JPEG/TIFF/JXL transfer path, this bridge is
1121-
store-based because typed `MetaValue` entries must be re-encoded into EXR
1122-
attribute bytes
1123-
1124-
Python typed behavior:
1125-
- `Document.oiio_attributes(...)` is safe-by-default and raises on unsafe raw
1126-
byte payloads; use `Document.unsafe_oiio_attributes(...)` for legacy/raw
1127-
fallback output.
1128-
- `Document.oiio_attributes_typed(...)` decodes text values to Python `str` in
1129-
safe mode and raises on unsafe/invalid text bytes.
1130-
- `Document.unsafe_oiio_attributes_typed(...)` returns raw text bytes for
1131-
explicit unsafe workflows.
1132-
- `Document.ocio_metadata_tree(...)` is safe-by-default and raises on unsafe
1133-
raw byte payloads; use `Document.unsafe_ocio_metadata_tree(...)` for
1134-
legacy/raw fallback output.
1098+
- the batch carries:
1099+
`part_index`, `name`, `type_name`, `value` bytes, and `is_opaque`
11351100
- `openmeta/ocio_adapter.h`:
11361101
- safe API: `build_ocio_metadata_tree_safe(..., InteropSafetyError*)`
11371102
- unsafe API: `build_ocio_metadata_tree(...)`
1138-
- `build_ocio_metadata_tree(..., const OcioAdapterRequest&)` (stable flat request API)
1139-
- `build_ocio_metadata_tree(..., const OcioAdapterOptions&)` (advanced/legacy shape)
1103+
- `build_ocio_metadata_tree(..., const OcioAdapterRequest&)`
1104+
- `build_ocio_metadata_tree(..., const OcioAdapterOptions&)`
1105+
1106+
Python interop behavior:
1107+
- `Document.export_names(style=ExportNameStyle.FlatHost, ...)` exposes the
1108+
shared flat-host naming contract used by host-side metadata mapping layers.
1109+
- `Document.ocio_metadata_tree(...)` is safe-by-default and raises on unsafe
1110+
raw byte payloads; use `Document.unsafe_ocio_metadata_tree(...)` for
1111+
legacy/raw fallback output.
11401112

11411113
Current C++ sidecar entry points:
11421114

@@ -1255,36 +1227,20 @@ Draft C++ transfer entry points (prepare/emit scaffold):
12551227
without pushing route parsing into host adapters.
12561228
- `replay_prepared_transfer_package_batch(...)` is the matching target-neutral
12571229
callback replay path over the same persisted batch.
1258-
- `collect_oiio_transfer_package_views(...)` is the first host bridge above
1259-
that persisted batch: it now maps the target-neutral semantic package view
1260-
into OIIO-oriented names, so the host no longer depends on the original
1261-
prepared bundle lifetime or route parsing.
1262-
- `collect_oiio_transfer_payload_views(...)` and
1263-
`build_oiio_transfer_payload_batch(...)` now sit on top of the generic
1264-
semantic payload layer rather than re-classifying prepared blocks inside
1265-
the OIIO adapter.
1266-
- `replay_oiio_transfer_package_batch(...)` is the higher-level consume path
1267-
above that same persisted batch, replaying semantic package chunks through
1268-
explicit host callbacks in deterministic output order.
1269-
- `PreparedTransferAdapterView` is the parallel adapter-facing surface for
1270-
host integrations that want explicit per-block operations without route
1271-
parsing.
1272-
- `collect_oiio_transfer_payload_views(...)` is the first thin
1273-
host-facing bridge on top of that adapter view, exposing one zero-copy
1274-
OIIO-oriented semantic payload list without adding new transfer core
1275-
logic.
1276-
- `build_oiio_transfer_payload_batch(...)` is the owned form of that
1277-
bridge when the host needs payload lifetime independent from the
1278-
prepared bundle.
1279-
- `build_exr_attribute_batch(...)`,
1280-
`build_exr_attribute_part_spans(...)`,
1281-
`build_exr_attribute_part_views(...)`, and
1282-
`replay_exr_attribute_batch(...)` are the EXR-native bridge for
1283-
OpenEXR/OIIO header-attribute workflows. They stay outside the
1284-
`PreparedTransferBundle` path because EXR metadata is attribute-native,
1285-
not block-native.
1286-
- `build_prepared_transfer_emit_package(...)`,
1287-
`build_prepared_transfer_adapter_view(...)`,
1230+
- OpenMeta no longer ships an in-library host-specific payload/package
1231+
bridge above the target-neutral package and adapter surfaces.
1232+
- `PreparedTransferAdapterView` is the parallel adapter-facing surface for
1233+
host integrations that want explicit per-block operations without route
1234+
parsing.
1235+
- `build_exr_attribute_batch(...)`,
1236+
`build_exr_attribute_part_spans(...)`,
1237+
`build_exr_attribute_part_views(...)`, and
1238+
`replay_exr_attribute_batch(...)` are the EXR-native bridge for
1239+
OpenEXR header-attribute workflows. They stay outside the
1240+
`PreparedTransferBundle` path because EXR metadata is attribute-native,
1241+
not block-native.
1242+
- `build_prepared_transfer_emit_package(...)`,
1243+
`build_prepared_transfer_adapter_view(...)`,
12881244
`emit_prepared_transfer_adapter_view(...)`,
12891245
`build_prepared_bundle_jpeg_package(...)`,
12901246
`build_prepared_bundle_tiff_package(...)`, and
@@ -1328,27 +1284,29 @@ Current adapter/name-policy behavior:
13281284
- `ExportNamePolicy::ExifToolAlias` applies compatibility aliases for
13291285
interop-name parity workflows.
13301286
- `ExportNamePolicy::Spec` preserves spec/native names.
1331-
- OIIO adapter keeps numeric unknown names (for example `Exif_0x....`) even
1332-
when value formatting is empty, and keeps `Exif:MakerNote` in spec mode.
1287+
- Shared flat-host interop naming keeps numeric unknown names (for example
1288+
`Exif_0x....`) for parity workflows.
13331289
- When DNG context is detected (`DNGVersion` present in the same IFD), DNG
13341290
color/CCM tags are exported with dedicated adapter namespaces:
1335-
`dng:*` (portable) and `DNG:*` (OIIO).
1291+
`dng:*` (portable) and a flat host-style variant.
13361292
- ICC entries are exported with adapter-friendly names:
1337-
`icc:*` (portable) and `ICC:*` (OIIO), alongside canonical `icc:header:*`
1338-
/ `icc:tag:*` naming.
1293+
`icc:*` (portable) and a flat host-style variant, alongside canonical
1294+
`icc:header:*` / `icc:tag:*` naming.
13391295

13401296
Adapter-focused tests (public tree):
13411297

13421298
```bash
13431299
cmake --build build-tests --target openmeta_tests
1344-
./build-tests/openmeta_tests --gtest_filter='InteropExport.*:OiioAdapter.*:OcioAdapter.*'
1300+
./build-tests/openmeta_tests --gtest_filter='InteropExport.*:OcioAdapter.*:ExrAdapter.*'
1301+
./build-tests/openmeta_tests --gtest_filter='ExrAdapter.*'
13451302
./build-tests/openmeta_tests --gtest_filter='CrwCiffDecode.*'
13461303
```
13471304

13481305
Notes:
1306+
- `InteropExport` tests cover alias/spec behavior and the flat host-style
1307+
naming contract.
1308+
- `ExrAdapter` tests cover EXR batch export and replay behavior.
13491309
- `CrwCiffDecode` tests cover CRW/CIFF derived EXIF mapping for legacy Canon RAW.
1350-
- `OiioAdapter` tests cover stable handling of empty-value attributes needed by
1351-
interop parity workflows.
13521310

13531311
## Doxygen (Optional)
13541312

docs/doxygen.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Documentation
22

3-
OpenMeta uses Doxygen for API extraction. For the "site" style docs (like OIIO),
4-
we render Doxygen XML via Sphinx + Breathe.
3+
OpenMeta uses Doxygen for API extraction. For the published site docs, we
4+
render Doxygen XML via Sphinx + Breathe.
55

66
## Requirements
77

docs/host_integration.md

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,28 @@ Use the narrowest public API that matches your host:
2020
| --- | --- |
2121
| Existing target file or template | `execute_prepared_transfer_file(...)` + `persist_prepared_transfer_file_result(...)` |
2222
| EXR writer | `build_exr_attribute_batch_from_file(...)` |
23-
| OIIO-style typed attributes | `collect_oiio_attributes_typed(...)` |
23+
| Host-owned metadata object model | `visit_metadata(...)` |
2424
| JPEG/JXL/WebP/PNG/JP2/BMFF encoder path | `prepare_metadata_for_target_file(...)` + adapter view or backend emitter |
2525
| Adobe DNG SDK objects/files | `dng_sdk_adapter.h` |
2626

2727
There is no public fuzzy-search API yet. Query through exact keys and build
2828
your own display or search layer on top.
2929

30+
## Adapter Classes
31+
32+
OpenMeta splits host integration surfaces deliberately:
33+
34+
- export-only naming/traversal surface:
35+
`visit_metadata(...)` for host-owned metadata mapping layers
36+
- export-only adapter:
37+
`build_ocio_metadata_tree(...)` for OCIO-style metadata trees
38+
- host-apply adapter:
39+
`build_exr_attribute_batch(...)` for EXR/OpenEXR header workflows
40+
- direct bridge:
41+
`dng_sdk_adapter.h` for applications that already use Adobe DNG SDK objects
42+
- narrow translator:
43+
`libraw_adapter.h` for orientation mapping into LibRaw flip space
44+
3045
## 1. Read Into `MetaStore`
3146

3247
```cpp
@@ -80,23 +95,32 @@ for (openmeta::EntryId id : store.find_all(key)) {
8095
This is the public lookup model today. If you need fuzzy search, substring
8196
search, or ExifTool-style display lookup, add that in your application layer.
8297

83-
## 3. Export Typed Metadata For OIIO-Style Hosts
98+
## 3. Generic Host Metadata Traversal
8499

85-
Use this when the host wants flattened typed attributes instead of raw
86-
container payloads.
100+
Use the traversal API when your application owns the metadata object model and
101+
needs deterministic exported names plus the original `Entry`.
87102

88103
```cpp
89-
#include "openmeta/oiio_adapter.h"
104+
#include "openmeta/interop_export.h"
105+
106+
class MyMetadataSink final : public openmeta::MetadataSink {
107+
public:
108+
void on_item(const openmeta::ExportItem& item) noexcept override
109+
{
110+
// Map item.name + item.entry into your host metadata object.
111+
}
112+
};
90113

91-
std::vector<openmeta::OiioTypedAttribute> attrs;
92-
openmeta::OiioAdapterRequest request;
93-
request.include_makernotes = true;
114+
openmeta::ExportOptions options;
115+
options.style = openmeta::ExportNameStyle::FlatHost;
116+
options.name_policy = openmeta::ExportNamePolicy::ExifToolAlias;
117+
options.include_makernotes = true;
94118

95-
openmeta::collect_oiio_attributes_typed(store, &attrs, request);
119+
MyMetadataSink sink;
120+
openmeta::visit_metadata(store, options, sink);
96121
```
97122
98-
That gives you `name + typed value` pairs that are easy to map onto an
99-
OpenImageIO `ImageSpec` or a similar metadata API.
123+
This keeps host-specific object ownership and write behavior outside OpenMeta.
100124
101125
## 4. Build An EXR Attribute Batch
102126
@@ -118,8 +142,8 @@ for (const openmeta::ExrAdapterAttribute& attr : batch.attributes) {
118142
```
119143

120144
OpenMeta does not need OpenEXR headers for this path. It exports a neutral
121-
batch of EXR-style attributes that your host can apply through OpenEXR, OIIO,
122-
or its own EXR writer.
145+
batch of EXR-style attributes that your host can apply through OpenEXR or its
146+
own EXR writer.
123147

124148
## 5. Feed A Host-Owned JPEG Or JXL Encoder
125149

docs/metadata_backend_matrix.md

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ backends without per-backend metadata logic duplication.
1414
| libjpeg-turbo | `jpeg_write_marker`, `jpeg_write_m_header`, `jpeg_write_m_byte`, `jpeg_write_icc_profile` | Primary JPEG metadata emitter (APP1/APP2/APP13 direct control) |
1515
| libtiff | `TIFFSetField`, `TIFFCreateEXIFDirectory`, `TIFFCreateGPSDirectory`, `TIFFWriteCustomDirectory`, `TIFFMergeFieldInfo` | Primary TIFF metadata emitter (native tag and IFD path) |
1616
| libjxl | `JxlEncoderUseBoxes`, `JxlEncoderAddBox`, `JxlEncoderCloseBoxes`, `JxlEncoderSetICCProfile` | Primary JXL metadata emitter (`Exif`, `xml `, `jumb`, optional `brob`) plus encoder ICC profile |
17-
| OpenImageIO | Plugin-level writes use backend APIs (JPEG/TIFF/JXL/OpenEXR) | Optional adapter layer when host app already writes through OIIO |
1817
| OpenEXR | `Header::insert`, typed attributes, `OpaqueAttribute` for unknown attr types | EXR header attribute path (not EXIF block packaging) |
1918

2019
## Container-Level Notes
@@ -293,7 +292,7 @@ container call mapping.
293292
input stream or prepared bundle storage.
294293
- `serialize_prepared_transfer_package_batch(...)` and
295294
`deserialize_prepared_transfer_package_batch(...)` persist that owned
296-
batch so host layers can move it across process or plugin boundaries
295+
batch so host layers can move it across process or integration boundaries
297296
without reopening the source file or rebuilding the bundle.
298297
- `collect_prepared_transfer_payload_views(...)` and
299298
`build_prepared_transfer_payload_batch(...)` now provide the matching
@@ -306,27 +305,16 @@ container call mapping.
306305
semantic package surface above that persisted batch.
307306
- `replay_prepared_transfer_package_batch(...)` is the target-neutral
308307
callback replay surface above that same persisted batch.
309-
- `collect_oiio_transfer_package_views(...)` is the first host bridge on
310-
top of that persisted batch: it provides zero-copy semantic package
311-
views for OIIO-style integrations after deserialize by mapping the
312-
target-neutral semantic surface into OIIO-facing names.
313-
- `replay_oiio_transfer_package_batch(...)` is the higher-level replay
314-
path on top of that same persisted batch, so OIIO/plugin hosts can
315-
consume the stable package through callbacks without reparsing routes.
308+
- OpenMeta no longer ships an in-library host-specific payload/package
309+
bridge above these target-neutral package views and replay APIs.
316310
- `build_prepared_transfer_adapter_view(...)` now provides the parallel
317311
target-neutral adapter view for JPEG/TIFF/JXL host integrations that
318312
want explicit compiled operations without route parsing.
319313
- `emit_prepared_transfer_adapter_view(...)` replays that compiled view
320314
through one generic host sink.
321-
- `collect_oiio_transfer_payload_views(...)` and
322-
`build_oiio_transfer_payload_batch(...)` now sit on top of that core
323-
semantic payload surface, mapping it into OIIO-facing names rather than
324-
re-classifying prepared blocks inside the adapter.
325-
- `replay_prepared_transfer_payload_batch(...)`,
326-
`collect_oiio_transfer_payload_views(const PreparedTransferPayloadBatch&, ...)`,
327-
and `replay_oiio_transfer_payload_batch(...)`
328-
now reuse that same earlier persisted semantic payload stage directly,
329-
before final package materialization.
315+
- `replay_prepared_transfer_payload_batch(...)` now reuses that same
316+
earlier persisted semantic payload stage directly, before final package
317+
materialization.
330318
- File-based JPEG prepare can preserve an existing OpenMeta draft
331319
invalidation payload as raw APP11 C2PA (`TransferC2paMode::PreserveRaw`).
332320
- Content-bound `Keep` still resolves to `Drop`.
@@ -343,9 +331,9 @@ container call mapping.
343331
1. JPEG and TIFF direct backends (highest transfer value).
344332
2. JXL box emitter parity for EXIF/XMP plus bounded JUMBF/C2PA preserve or
345333
projection.
346-
3. Extend the new OIIO transfer bridge beyond the current zero-copy payload
347-
view and owned batch if host-specific persistence or replay formats are
348-
needed.
334+
3. If a future host-specific bridge needs persistence or replay formats,
335+
build that on top of the target-neutral package and adapter surfaces
336+
rather than adding a host-specific wrapper inside OpenMeta.
349337
4. Extend the current EXR attribute batch bridge if host-side replay or
350338
persistence formats are needed.
351339

0 commit comments

Comments
 (0)