A text tag whose value lies outside the file, which exifreader reads as
"<faulty value>", no longer gives a make, model, lens model or offset
field. Tests cover such a JPEG and the backup-metadata dump keying a tag
exifreader has no name for as undefined-<tag number>.
Model: opus-5-5
exif() takes the altitude from the GPSAltitude tag and negates it only when
GPSAltitudeRef is 1, so a file with GPSAltitude and no GPSAltitudeRef keeps its
altitude, above sea level. A test covers that file.
backup-metadata --exif keeps the EXIF tags exifreader has no name for. The
comments in src/exif.ts say the thumbnail's tags are not kept and that a tag
with several values computes to an array.
Model: opus-5-5
Add a readPhotoExif test: EXIF whose DateTimeOriginal is
0000:00:00 00:00:00, as a camera with an unset clock writes it, gives no
dateTimeOriginal while its other fields are still read. Remove the README
sentence describing the backup's exif field in dumps from an earlier
version.
Model: opus-5-5
photo.exif() and backup-metadata --exif read EXIF with exifreader,
which reads JPEG, HEIC/HEIF, AVIF, PNG and WebP, so a HEIC original or
a live photo's HEIC image gets its EXIF. exifreader replaces
exif-reader and the hand-written JPEG segment scan. PhotoExif is
unchanged. The exif field of backup-metadata --exif is now
exifreader's tag output, and exifRaw holds the whole EXIF block it
could not read. Tests use a real 933-byte HEIC fixture, test/exif.heic,
whose recipe is in test/exif-heic.ts.
Model: opus-5-5
`Photo` gains:
- `savePath` and `isLocal`: synchronous, disk only. Where `lib.backup()` writes the original under the library's `downloadDirectory`, and whether all of it is there; a copy only in the cache does not count.
- `content()` and `exif()`: async, may download. `exif()` reads the common EXIF fields of a JPEG and returns `{}` for anything else.
- The getters `modifiedAt` and `hash`, also on `PhotoRecord`, and `year`.
For a live photo the backup has not stored yet, `savePath` carries the title's extension, and the image may be stored under a different one. The JPEG EXIF scan moved to `src/exif.ts`. The exported `PhotoContent` interface gains `savePath` and `isLocal`.
Judgement call: `iso` is read only when the file stores it as a single number.
Model: opus-5-5
The download idle deadline's timer is unref'd so it never holds the
process open, and a test checks no timer is left after a download
completes or fails. A test covers the rejection of "#" in a request
path. The EXIF scan accepts an APP1 segment only when its length is at
least 8, since a shorter one cannot hold the six-byte Exif header;
tests cover lengths 7 and 8.
Model: opus-5-5
The segment scan behind `backup-metadata --exif` now checks every
segment length against the bytes that remain and stops on lengths
under 2, so a truncated or corrupt original can neither throw nor loop.
A malformed or unparseable EXIF segment is recorded as
`imageMetadata.exifError`, and a failure to read the original as
`imageMetadataError` in the per-file JSON, instead of the field being
silently left out. Tests use short hand-built byte arrays.
Model: opus-5-5