fix: try all 3 EXIF date tags + raw bytes scan in _read_cr2_exif

This commit is contained in:
admin committed 2026-06-28 18:29:34 +02:00
1 parent 1bc1150fa8
commit 6a0fe3c163
1 file changed
+27 -11
+27 -11
View File
@@ -176,18 +176,24 @@ def _read_other_exif_pil(path: Path) -> str | None:
def _read_cr2_exif(path: Path) -> str | None:
"""CR2/CR3 (Canon Raw): try piexif first, then PIL embedded JPEG."""
# Tier 1: piexif on CR2 (TIFF-based EXIF)
"""CR2/CR3 (Canon Raw): try piexif, then PIL, then raw bytes scan."""
# ── Tier 1: piexif (TIFF-based EXIF) ──────────────────────
if HAS_PIEXIF:
try:
exif_dict = piexif.load(str(path))
raw_val = exif_dict.get('Exif', {}).get(piexif.ExifIFD.DateTimeOriginal)
if raw_val:
return raw_val.decode('utf-8')
# All possible date tag locations in EXIF
for ifd_name, tag_id in (
('Exif', piexif.ExifIFD.DateTimeOriginal), # 36867
('Exif', piexif.ExifIFD.DateTimeDigitized), # 36868
('Image', piexif.ImageIFD.DateTime), # 306
):
raw_val = exif_dict.get(ifd_name, {}).get(tag_id)
if raw_val:
return raw_val.decode('utf-8')
except Exception:
pass
# Tier 2: PIL can read EXIF from CR2's embedded JPEG preview
# ── Tier 2: PIL (embedded JPEG preview) ───────────────────
try:
from PIL import Image
from PIL.ExifTags import TAGS
@@ -195,11 +201,21 @@ def _read_cr2_exif(path: Path) -> str | None:
raw = img._getexif()
img.close()
if raw:
tag_map = {v: k for k, v in TAGS.items()}
for tag_name in ('DateTimeOriginal', 'DateTime'):
tag_code = tag_map.get(tag_name)
if tag_code and tag_code in raw:
return raw[tag_code]
for tag_code in (36867, 36868, 306): # DateTimeOriginal, Digitized, DateTime
val = raw.get(tag_code)
if val:
return val
except Exception:
pass
# ── Tier 3: raw bytes scan (last resort) ──────────────────
try:
data = path.read_bytes()
# CR2 stores dates as ASCII 'YYYY:MM:DD HH:MM:SS'
import re
m = re.search(rb'(\d{4}:\d{2}:\d{2} \d{2}:\d{2}:\d{2})', data)
if m:
return m.group(1).decode('ascii')
except Exception:
pass
return None