Skip to content

EXIF write/edit path (exif::Builder + Exif::edit) — deferred until a consumer needs it #18

@lilith

Description

@lilith

Context

zencodec::exif is read + filter today (PR #17): Exif::parsefilteredto_bytes, plus Metadata::filtered. There is no public write API — we never construct EXIF fields from user input; a rewrite only preserves/prunes the source's bytes.

A future need may arise: a pipeline that injects Orientation or stamps a Copyright string on every processed image. This issue records the agreed design so it can be built when a concrete consumer lands. Deferred for now (no API added without a real use).

Agreed shape

  • exif::Builder (construct from scratch) + Exif::edit() (edit a parsed blob), each ending in build() -> Vec<u8>, reusing the existing canonical serializer (to_bytes).
  • Mechanism: relax Entry.value: &'a [u8]Cow<'a, [u8]> so parsed entries stay borrowed (zero-copy reads unchanged) while injected ones are owned. (Alternative: a separate Builder that copies entries — editing allocates anyway.) Re-fuzz after.
  • Encoding (spec-correct): a string setter picks the TIFF type — ASCII (type 2) when pure 7-bit, else UTF-8 (type 129) — NUL-terminated, count incl. NUL. Never stuff non-ASCII into a type-2 field.
  • Interop default: ASCII-if-possible, else UTF-8 (129). Type 129 has thin reader support today (ExifTool reads it; kamadak-exif / Pillow / most don't), so prefer ASCII when the string allows. For broad readability of a copyright, a likely companion is also writing XMP dc:rights (universally UTF-8).
  • Reconcile Metadata::orientation (the field codecs apply) with any Orientation entry the builder writes into the EXIF blob — keep them consistent.

Additive (semver-minor) when implemented. Design recorded in docs/spec.md → "Planned (not implemented): EXIF write / edit path".

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions