exif() returns every EXIF tag in the file, not only the thirteen #156

Closed
opened 2026-10-02 03:01:55 +02:00 by clawbot · 3 comments
Collaborator

Owner's ruling (chat, 2026-10-02 ~01:00 UTC), answering the question in #148 (comment) (should exif() return the thirteen fields quak reads, or every EXIF tag in the file):

return every EXIF tag in the file

return all tags obvs

148 was built and closed with the thirteen-field reading; this issue changes it.

Definition of done

  • await photo.exif() returns every EXIF tag present in the file (JPEG and HEIF/HEIC), not only the thirteen, keyed by tag name. Tags quak does not know still appear, with their decoded values.
  • The thirteen typed async accessors from 148 (make(), model(), lensModel(), dateTimeOriginal(), offsetTimeOriginal(), exposureTime(), fNumber(), iso(), focalLength(), orientation(), gpsLatitude(), gpsLongitude(), gpsAltitude()) stay. Each calls exif() and returns its one value, typed, or undefined when the file lacks it.
  • Tests: on the JPEG and HEIC fixtures, exif() includes tags outside the thirteen (name at least one per fixture), and every accessor matches the corresponding tag in exif().
  • README/API docs describe the full-tag return.
  • quak is pre-1.0: change it in place, no compatibility shim or alias for the old shape.
  • Lands on next with an independent review; milestone PR #134 description updated.

model: opus-5-5

Owner's ruling (chat, 2026-10-02 ~01:00 UTC), answering the question in https://git.eeqj.de/sneak/quak/issues/148#issuecomment-108451 (should `exif()` return the thirteen fields quak reads, or every EXIF tag in the file): > return every EXIF tag in the file > > return all tags obvs 148 was built and closed with the thirteen-field reading; this issue changes it. ## Definition of done - `await photo.exif()` returns every EXIF tag present in the file (JPEG and HEIF/HEIC), not only the thirteen, keyed by tag name. Tags quak does not know still appear, with their decoded values. - The thirteen typed async accessors from 148 (`make()`, `model()`, `lensModel()`, `dateTimeOriginal()`, `offsetTimeOriginal()`, `exposureTime()`, `fNumber()`, `iso()`, `focalLength()`, `orientation()`, `gpsLatitude()`, `gpsLongitude()`, `gpsAltitude()`) stay. Each calls `exif()` and returns its one value, typed, or `undefined` when the file lacks it. - Tests: on the JPEG and HEIC fixtures, `exif()` includes tags outside the thirteen (name at least one per fixture), and every accessor matches the corresponding tag in `exif()`. - README/API docs describe the full-tag return. - quak is pre-1.0: change it in place, no compatibility shim or alias for the old shape. - Lands on `next` with an independent review; milestone PR https://git.eeqj.de/sneak/quak/pulls/134 description updated. model: opus-5-5
clawbot self-assigned this 2026-10-02 03:01:55 +02:00
Author
Collaborator

sneak also wrote on 148 (#148 (comment)): "let exif() return everything. CLI options are not the same as API methods." So quak backup-metadata --exif is no substitute; the API method itself returns every tag.

model: opus-5-5

sneak also wrote on 148 (https://git.eeqj.de/sneak/quak/issues/148#issuecomment-110589): "let exif() return everything. CLI options are not the same as API methods." So `quak backup-metadata --exif` is no substitute; the API method itself returns every tag. model: opus-5-5
Author
Collaborator

Plan.

  • await photo.exif() returns every EXIF tag exifreader reads from the file (JPEG, HEIC/HEIF and the rest), keyed by tag name. Each value is exifreader's own decoded tag, { value, description }. A tag exifreader has no name for is keyed undefined- plus its number, as in the backup-metadata --exif dump. The embedded thumbnail's tags are included too, under keys that cannot hide a main-image tag of the same name. A file with no EXIF, or a video, gives {}. The new return type is exported.
  • The thirteen typed methods stay, with the same names and types. Each calls exif() and derives its one value from the tags the way readPhotoExif does today. That code becomes one function that takes the tag map rather than the bytes, so exif() and the methods read the same data. The type check still fails when a typed field has no method.
  • Tests:
    • On the JPEG and HEIC fixtures, exif() holds at least one named tag outside the thirteen per fixture (for example ExifVersion, ColorSpace or Software).
    • Every method agrees with the tag it is derived from.
    • Existing value tests for the thirteen keep their assertions.
  • Docs: README "Read surface" describes the full-tag return and the methods. The example script's {savePath}.json now carries all tags; its README text says so.
  • quak is pre-1.0, so the shape changes in place: no alias and no shim.

Model: opus-5-5

Plan. - **`await photo.exif()`** returns every EXIF tag `exifreader` reads from the file (JPEG, HEIC/HEIF and the rest), keyed by tag name. Each value is `exifreader`'s own decoded tag, `{ value, description }`. A tag `exifreader` has no name for is keyed `undefined-` plus its number, as in the `backup-metadata --exif` dump. The embedded thumbnail's tags are included too, under keys that cannot hide a main-image tag of the same name. A file with no EXIF, or a video, gives `{}`. The new return type is exported. - **The thirteen typed methods stay**, with the same names and types. Each calls `exif()` and derives its one value from the tags the way `readPhotoExif` does today. That code becomes one function that takes the tag map rather than the bytes, so `exif()` and the methods read the same data. The type check still fails when a typed field has no method. - **Tests:** - On the JPEG and HEIC fixtures, `exif()` holds at least one named tag outside the thirteen per fixture (for example `ExifVersion`, `ColorSpace` or `Software`). - Every method agrees with the tag it is derived from. - Existing value tests for the thirteen keep their assertions. - **Docs:** README "Read surface" describes the full-tag return and the methods. The example script's `{savePath}.json` now carries all tags; its README text says so. - quak is pre-1.0, so the shape changes in place: no alias and no shim. Model: opus-5-5
Author
Collaborator

sneak reopened #148 at 01:01 UTC. The PR for this issue closes both: its title or body carries closes #148 and closes #156.

model: opus-5-5

sneak reopened https://git.eeqj.de/sneak/quak/issues/148 at 01:01 UTC. The PR for this issue closes both: its title or body carries `closes #148` and `closes #156`. model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/quak#156