Test the unset-clock EXIF date; drop the old dump layout from README
check / check (push) Successful in 1m16s

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
This commit is contained in:
2026-10-01 19:14:59 +00:00
parent a13ec66bca
commit 9c0c7c9489
2 changed files with 30 additions and 6 deletions
+26
View File
@@ -27,6 +27,25 @@ const TIFF_ORIENTATION_6 = [
0x00, 0x00,
];
// A big-endian TIFF block holding Orientation 6 and DateTimeOriginal
// "0000:00:00 00:00:00", which a camera with an unset clock writes.
const TIFF_UNSET_DATE = [
...[0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08], // the first IFD at 8
// The first IFD, at 8: two entries, then no next IFD.
...[0x00, 0x02],
// Orientation (0x0112), SHORT, 6.
...[0x01, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00],
// The Exif IFD's offset (0x8769), LONG, 38.
...[0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x26],
...[0x00, 0x00, 0x00, 0x00],
// The Exif IFD, at 38: one entry, then no next IFD.
...[0x00, 0x01],
// DateTimeOriginal (0x9003), 20 ASCII bytes at 56.
...[0x90, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x38],
...[0x00, 0x00, 0x00, 0x00],
...new TextEncoder().encode("0000:00:00 00:00:00\0"), // at 56
];
// An APP1 segment whose length field matches its data.
const app1 = (data: number[]): number[] => {
const len = data.length + 2;
@@ -44,6 +63,13 @@ describe("readPhotoExif", () => {
});
});
it("gives no dateTimeOriginal for a DateTimeOriginal of 0000:00:00 00:00:00", () => {
const data = [...EXIF_HEADER, ...TIFF_UNSET_DATE];
expect(readPhotoExif(bytes(SOI, app1(data), SOS))).toStrictEqual({
orientation: 6,
});
});
it.each([
[
"a file that is not an image",