From 502555a6c8a623d60a1a80f911610f87d79dd513 Mon Sep 17 00:00:00 2001 From: Markus Vogt <49659413+mv1005@users.noreply.github.com> Date: Sat, 2 Aug 2025 23:46:09 +0200 Subject: [PATCH 1/2] Support "ftypmif1" and "ftypavif" (#134) Add support for reading exif tags from files with signatures "ftypmif1" and "ftypavif". Both file types use the same container format as HEIC, so the HEIC tag reader has been extended to recognize those file types. --- exifread/core/find_exif.py | 2 +- exifread/core/heic.py | 2 +- tests/resources/dump.txt | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/exifread/core/find_exif.py b/exifread/core/find_exif.py index 8c7456a..7289922 100644 --- a/exifread/core/find_exif.py +++ b/exifread/core/find_exif.py @@ -84,7 +84,7 @@ def determine_type(fh: BinaryIO) -> Tuple[int, bytes, int]: if data[0:2] in [b"II", b"MM"]: # it's a TIFF file offset, endian = find_tiff_exif(fh) - elif data[4:12] == b"ftypheic": + elif data[4:12] in [b"ftypheic", b"ftypavif", b"ftypmif1"]: fh.seek(0) heic = HEICExifFinder(fh) offset, endian = heic.find_exif() diff --git a/exifread/core/heic.py b/exifread/core/heic.py index c616370..331267b 100644 --- a/exifread/core/heic.py +++ b/exifread/core/heic.py @@ -328,7 +328,7 @@ def _parse_iref(self, box: Box) -> None: def find_exif(self) -> Tuple[int, bytes]: ftyp = self.expect_parse("ftyp") - if ftyp.major_brand != b"heic" or ftyp.minor_version != 0: + if ftyp.major_brand not in [b"heic", b"avif", b"mif1"] or ftyp.minor_version != 0: return 0, b"" meta = self.expect_parse("meta") diff --git a/tests/resources/dump.txt b/tests/resources/dump.txt index 600073f..52fdfd9 100644 --- a/tests/resources/dump.txt +++ b/tests/resources/dump.txt @@ -162,8 +162,9 @@ Image YCbCrPositioning (Short): Centered Image YResolution (Ratio): 72 Opening: tests/resources/heic/spring_1440x960.heic -File format not recognized. -No EXIF information found +EXIF DateTimeOriginal (ASCII): 2020:12:03 15:04:31 +EXIF SubSecTimeOriginal (ASCII): 04 +Image ExifOffset (Long): 26 Opening: tests/resources/jpg/Canon_40D.jpg File has JPEG thumbnail From 74f2720def880587c6cb526b8a170966d64c262c Mon Sep 17 00:00:00 2001 From: Markus Vogt <49659413+mv1005@users.noreply.github.com> Date: Sat, 2 Aug 2025 23:46:12 +0200 Subject: [PATCH 2/2] Added AVIF file to tests Added an image file using AVIF format to test support for reading those kind of tags. --- Makefile | 2 +- tests/resources/avif/mountains.avif | Bin 0 -> 45864 bytes tests/resources/dump.txt | 51 ++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/resources/avif/mountains.avif diff --git a/Makefile b/Makefile index 8331837..6903d6b 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ endif EXIF_PY := $(if $(shell which EXIF.py),EXIF.py,./EXIF.py) # Find images, support multiple case insensitive extensions and file names with spaces -FIND_IMAGES := find tests/resources -regextype posix-egrep -iregex ".*\.(bmp|gif|heic|heif|jpg|jpeg|png|tiff|webp|arw)" -print0 | LC_COLLATE=C sort -fz | xargs -0 +FIND_IMAGES := find tests/resources -regextype posix-egrep -iregex ".*\.(bmp|gif|heic|heif|jpg|jpeg|png|tiff|webp|arw|avif)" -print0 | LC_COLLATE=C sort -fz | xargs -0 .PHONY: help diff --git a/tests/resources/avif/mountains.avif b/tests/resources/avif/mountains.avif new file mode 100644 index 0000000000000000000000000000000000000000..fdb9b556476fe2a3f781c65f82dec44bd7b100f8 GIT binary patch literal 45864 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 literal 0 HcmV?d00001 diff --git a/tests/resources/dump.txt b/tests/resources/dump.txt index 52fdfd9..db1761c 100644 --- a/tests/resources/dump.txt +++ b/tests/resources/dump.txt @@ -1,3 +1,54 @@ +Opening: tests/resources/avif/mountains.avif +EXIF ColorSpace (Short): sRGB +EXIF ComponentsConfiguration (Undefined): YCbCr +EXIF Contrast (Short): Normal +EXIF CustomRendered (Short): Normal +EXIF DateTimeDigitized (ASCII): 2024:04:05 10:59:24 +EXIF DateTimeOriginal (ASCII): 2024:04:05 10:59:24 +EXIF DigitalZoomRatio (Ratio): 1 +EXIF ExifImageLength (Long): 1080 +EXIF ExifImageWidth (Long): 1920 +EXIF ExifVersion (Undefined): 0230 +EXIF ExposureBiasValue (Signed Ratio): 0 +EXIF ExposureMode (Short): Auto Exposure +EXIF ExposureProgram (Short): Aperture Priority +EXIF ExposureTime (Ratio): 1/1000 +EXIF FNumber (Ratio): 5 +EXIF FileSource (Undefined): Digital Camera +EXIF Flash (Short): Flash did not fire, auto mode +EXIF FlashPixVersion (Undefined): 0100 +EXIF FocalLength (Ratio): 25 +EXIF GainControl (Short): Low gain up +EXIF ISOSpeedRatings (Short): 200 +EXIF LensModel (ASCII): LEICA DG SUMMILUX 25/F1.4 +EXIF LensSpecification (Ratio): [25, 25, 7/5, 7/5] +EXIF LightSource (Short): Unknown +EXIF MakerNote (Undefined): [79, 77, 32, 83, 89, 83, 84, 69, 77, 0, 0, 0, 73, 73, 4, 0, 7, 0, 9, 2, ... ] +EXIF MaxApertureValue (Ratio): 1 +EXIF MeteringMode (Short): Pattern +EXIF Saturation (Short): Normal +EXIF SceneCaptureType (Short): Standard +EXIF SensitivityType (Short): Standard Output Sensitivity +EXIF Sharpness (Short): Normal +EXIF UserComment (Undefined): +EXIF WhiteBalance (Short): Auto +GPS GPSVersionID (Byte): [2, 3, 0, 0] +Image Artist (ASCII): +Image Copyright (ASCII): +Image DateTime (ASCII): 2025:08:02 22:48:04 +Image ExifOffset (Long): 932 +Image GPSInfo (Long): 16626 +Image ImageDescription (ASCII): +Image Make (ASCII): OLYMPUS CORPORATION +Image Model (ASCII): E-PL8 +Image Orientation (Short): Horizontal (normal) +Image PrintIM (Undefined): [80, 114, 105, 110, 116, 73, 77, 0, 48, 51, 48, 48, 0, 0, 37, 0, 1, 0, 20, 0, ... ] +Image ResolutionUnit (Short): Pixels/Inch +Image Software (ASCII): GIMP 2.10.36 +Image XResolution (Ratio): 350 +Image YCbCrPositioning (Short): Co-sited +Image YResolution (Ratio): 350 + Opening: tests/resources/heic/heic_hdlr_box.jpg No EXIF information found