|
| 1 | +Host Integration |
| 2 | +================ |
| 3 | + |
| 4 | +This guide is for applications that already own the image or container side |
| 5 | +and want OpenMeta to handle metadata. |
| 6 | + |
| 7 | +OpenMeta is not an image encoder. The normal pattern is: |
| 8 | + |
| 9 | +- decode metadata from one source file |
| 10 | +- query or edit it in ``MetaStore`` |
| 11 | +- hand prepared metadata to your own writer, encoder, or SDK |
| 12 | + |
| 13 | +If you want the shortest end-to-end examples first, start with |
| 14 | +:doc:`quick_start`. |
| 15 | + |
| 16 | +Pick the integration path |
| 17 | +------------------------- |
| 18 | + |
| 19 | +Use the narrowest public API that matches your host: |
| 20 | + |
| 21 | +=============================== =========================================================== |
| 22 | +Host owns Use |
| 23 | +=============================== =========================================================== |
| 24 | +Existing target file/template ``execute_prepared_transfer_file(...)`` + |
| 25 | + ``persist_prepared_transfer_file_result(...)`` |
| 26 | +EXR writer ``build_exr_attribute_batch_from_file(...)`` |
| 27 | +OIIO-style typed attributes ``collect_oiio_attributes_typed(...)`` |
| 28 | +JPEG/JXL/WebP/PNG/JP2/BMFF ``prepare_metadata_for_target_file(...)`` + |
| 29 | +encoder path adapter view or backend emitter |
| 30 | +Adobe DNG SDK objects/files ``dng_sdk_adapter.h`` |
| 31 | +=============================== =========================================================== |
| 32 | + |
| 33 | +There is no public fuzzy-search API yet. Query through exact keys and build |
| 34 | +your own display or search layer on top. |
| 35 | + |
| 36 | +Read and query |
| 37 | +-------------- |
| 38 | + |
| 39 | +The basic read path is covered in :doc:`quick_start`. Once you have a |
| 40 | +``MetaStore``, the main lookup API is exact-key lookup through |
| 41 | +``MetaStore::find_all(...)``. |
| 42 | + |
| 43 | +OIIO-style typed attributes |
| 44 | +--------------------------- |
| 45 | + |
| 46 | +Use this when the host wants flattened typed attributes instead of raw |
| 47 | +container payloads. |
| 48 | + |
| 49 | +.. code-block:: cpp |
| 50 | +
|
| 51 | + #include "openmeta/oiio_adapter.h" |
| 52 | +
|
| 53 | + std::vector<openmeta::OiioTypedAttribute> attrs; |
| 54 | + openmeta::OiioAdapterRequest request; |
| 55 | + request.include_makernotes = true; |
| 56 | +
|
| 57 | + openmeta::collect_oiio_attributes_typed(store, &attrs, request); |
| 58 | +
|
| 59 | +This gives you ``name + typed value`` pairs that are easy to map onto an |
| 60 | +OpenImageIO ``ImageSpec`` or a similar metadata API. |
| 61 | + |
| 62 | +EXR attribute batches |
| 63 | +--------------------- |
| 64 | + |
| 65 | +This is the cleanest host-adapter path in OpenMeta today. |
| 66 | + |
| 67 | +.. code-block:: cpp |
| 68 | +
|
| 69 | + #include "openmeta/exr_adapter.h" |
| 70 | +
|
| 71 | + openmeta::ExrAdapterBatch batch; |
| 72 | + openmeta::BuildExrAttributeBatchFileOptions options; |
| 73 | +
|
| 74 | + openmeta::BuildExrAttributeBatchFileResult result = |
| 75 | + openmeta::build_exr_attribute_batch_from_file( |
| 76 | + "source.jpg", &batch, options); |
| 77 | +
|
| 78 | + for (const openmeta::ExrAdapterAttribute& attr : batch.attributes) { |
| 79 | + // Forward attr.name, attr.type_name, and attr.value to your EXR writer. |
| 80 | + } |
| 81 | +
|
| 82 | +OpenMeta does not need OpenEXR headers for this path. It exports a neutral |
| 83 | +batch of EXR-style attributes that your host can apply through OpenEXR, OIIO, |
| 84 | +or its own EXR writer. |
| 85 | + |
| 86 | +Host-owned JPEG or JXL output |
| 87 | +----------------------------- |
| 88 | + |
| 89 | +There are two public patterns for encoder-owned output: |
| 90 | + |
| 91 | +- implement a backend emitter such as ``JpegTransferEmitter`` or |
| 92 | + ``JxlTransferEmitter`` |
| 93 | +- build an adapter view and consume one normalized list of operations |
| 94 | + |
| 95 | +Adapter-view pattern |
| 96 | +~~~~~~~~~~~~~~~~~~~~ |
| 97 | + |
| 98 | +Use this when you want one target-neutral operation list. |
| 99 | + |
| 100 | +.. code-block:: cpp |
| 101 | +
|
| 102 | + #include "openmeta/metadata_transfer.h" |
| 103 | +
|
| 104 | + class MySink final : public openmeta::TransferAdapterSink { |
| 105 | + public: |
| 106 | + openmeta::TransferStatus |
| 107 | + emit_op(const openmeta::PreparedTransferAdapterOp& op, |
| 108 | + std::span<const std::byte> payload) noexcept override |
| 109 | + { |
| 110 | + // Dispatch on op.kind and forward payload into your backend. |
| 111 | + return openmeta::TransferStatus::Ok; |
| 112 | + } |
| 113 | + }; |
| 114 | +
|
| 115 | + openmeta::PrepareTransferFileOptions prepare; |
| 116 | + prepare.prepare.target_format = openmeta::TransferTargetFormat::Jxl; |
| 117 | +
|
| 118 | + openmeta::PrepareTransferFileResult prepared = |
| 119 | + openmeta::prepare_metadata_for_target_file("source.jpg", prepare); |
| 120 | +
|
| 121 | + openmeta::PreparedTransferAdapterView view; |
| 122 | + openmeta::build_prepared_transfer_adapter_view( |
| 123 | + prepared.bundle, &view, openmeta::EmitTransferOptions {}); |
| 124 | +
|
| 125 | + MySink sink; |
| 126 | + openmeta::emit_prepared_transfer_adapter_view(prepared.bundle, view, sink); |
| 127 | +
|
| 128 | +Backend-emitter pattern |
| 129 | +~~~~~~~~~~~~~~~~~~~~~~~ |
| 130 | + |
| 131 | +Use this when your host already looks like one OpenMeta backend. |
| 132 | + |
| 133 | +.. code-block:: cpp |
| 134 | +
|
| 135 | + #include "openmeta/metadata_transfer.h" |
| 136 | +
|
| 137 | + class MyJpegEmitter final : public openmeta::JpegTransferEmitter { |
| 138 | + public: |
| 139 | + openmeta::TransferStatus |
| 140 | + write_app_marker(uint8_t marker_code, |
| 141 | + std::span<const std::byte> payload) noexcept override |
| 142 | + { |
| 143 | + // Write one APPn marker into your JPEG output path. |
| 144 | + return openmeta::TransferStatus::Ok; |
| 145 | + } |
| 146 | + }; |
| 147 | +
|
| 148 | + openmeta::PrepareTransferFileOptions prepare; |
| 149 | + prepare.prepare.target_format = openmeta::TransferTargetFormat::Jpeg; |
| 150 | +
|
| 151 | + openmeta::PrepareTransferFileResult prepared = |
| 152 | + openmeta::prepare_metadata_for_target_file("source.jpg", prepare); |
| 153 | +
|
| 154 | + openmeta::PreparedTransferExecutionPlan plan; |
| 155 | + openmeta::compile_prepared_transfer_execution( |
| 156 | + prepared.bundle, openmeta::EmitTransferOptions {}, &plan); |
| 157 | +
|
| 158 | + MyJpegEmitter emitter; |
| 159 | + openmeta::emit_prepared_transfer_compiled(prepared.bundle, plan, emitter); |
| 160 | +
|
| 161 | +For JXL, implement ``JxlTransferEmitter::set_icc_profile(...)``, |
| 162 | +``add_box(...)``, and ``close_boxes(...)``. |
| 163 | + |
| 164 | +OpenMeta does not ship a TurboJPEG-specific wrapper yet. The intended |
| 165 | +integration path is still through ``JpegTransferEmitter`` or the adapter view. |
| 166 | + |
| 167 | +Edit an existing target file |
| 168 | +---------------------------- |
| 169 | + |
| 170 | +If your host already has a target file or template on disk, use the file |
| 171 | +helper instead of building your own writer path. |
| 172 | + |
| 173 | +.. code-block:: cpp |
| 174 | +
|
| 175 | + #include "openmeta/metadata_transfer.h" |
| 176 | +
|
| 177 | + openmeta::ExecutePreparedTransferFileOptions exec_options; |
| 178 | + exec_options.prepare.prepare.target_format = |
| 179 | + openmeta::TransferTargetFormat::Tiff; |
| 180 | + exec_options.edit_target_path = "rendered.tif"; |
| 181 | +
|
| 182 | + openmeta::ExecutePreparedTransferFileResult exec = |
| 183 | + openmeta::execute_prepared_transfer_file("source.jpg", exec_options); |
| 184 | +
|
| 185 | + openmeta::PersistPreparedTransferFileOptions persist; |
| 186 | + persist.output_path = "rendered_with_meta.tif"; |
| 187 | + persist.overwrite_output = true; |
| 188 | +
|
| 189 | + openmeta::PersistPreparedTransferFileResult saved = |
| 190 | + openmeta::persist_prepared_transfer_file_result(exec, persist); |
| 191 | +
|
| 192 | +Optional Adobe DNG SDK bridge |
| 193 | +----------------------------- |
| 194 | + |
| 195 | +If OpenMeta was built with ``OPENMETA_WITH_DNG_SDK_ADAPTER=ON``, you can use |
| 196 | +the optional SDK bridge in two ways. |
| 197 | + |
| 198 | +Update an existing DNG file |
| 199 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 200 | + |
| 201 | +.. code-block:: cpp |
| 202 | +
|
| 203 | + #include "openmeta/dng_sdk_adapter.h" |
| 204 | +
|
| 205 | + openmeta::ApplyDngSdkMetadataFileResult result = |
| 206 | + openmeta::update_dng_sdk_file_from_file("source.jpg", "target.dng"); |
| 207 | +
|
| 208 | +Apply onto existing SDK objects |
| 209 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 210 | + |
| 211 | +.. code-block:: cpp |
| 212 | +
|
| 213 | + #include "openmeta/dng_sdk_adapter.h" |
| 214 | + #include "openmeta/metadata_transfer.h" |
| 215 | +
|
| 216 | + openmeta::PrepareTransferFileOptions prepare; |
| 217 | + prepare.prepare.target_format = openmeta::TransferTargetFormat::Dng; |
| 218 | +
|
| 219 | + openmeta::PrepareTransferFileResult prepared = |
| 220 | + openmeta::prepare_metadata_for_target_file("source.jpg", prepare); |
| 221 | +
|
| 222 | + openmeta::DngSdkAdapterOptions adapter; |
| 223 | + openmeta::apply_prepared_dng_sdk_metadata( |
| 224 | + prepared.bundle, host, negative, adapter); |
| 225 | +
|
| 226 | +This bridge is for applications that already use the Adobe DNG SDK. OpenMeta |
| 227 | +still does not encode pixels or invent raw-image structure. |
| 228 | + |
| 229 | +Related pages |
| 230 | +------------- |
| 231 | + |
| 232 | +- :doc:`quick_start` |
| 233 | +- :doc:`interop_api` |
| 234 | +- :doc:`development` |
| 235 | +- :doc:`api` |
0 commit comments