fix(makernotes): honour ExifTool's Priority, so a sub-directory copy stops overwriting the Main tag - #414
Merged
Merged
Conversation
swackhamer
enabled auto-merge (squash)
August 2, 2026 04:20
…stops overwriting the Main tag
Five corpus files carry the same Pentax tag twice -- once in `%Pentax::Main`
and once inside a binary sub-directory -- and oxidex printed the sub-directory
copy. That is the worst shape a defect can take here: a real ExifTool tag name
carrying the wrong value, with nothing downstream able to tell.
Pentax/PentaxK100D.jpg LensType M-42 or No Lens -> smc PENTAX-DA 21mm F3.2 AL Limited
Pentax/PentaxK-50.jpg LensType M-42 or No Lens -> Sigma
Pentax/PentaxK-5II.jpg LensType K or M Lens -> Sigma
Pentax/PentaxOptioSVi.jpg PentaxModelID Optio SV -> Optio SVi
Pentax/PentaxOptioL20.jpg PentaxModelID Optio S7 -> Optio L20
ExifTool decides this with `Priority`. `FoundTag` (ExifTool.pm:9448) reads it at
:9469-9473, and on a duplicate name compares against the priority already
recorded (:9564). Two details make the rule: a 0-priority value records no
entry in `PRIORITY` (:9589 stores it "only if exists and is non-zero"), and a
missing entry is promoted to 1 (:9545-9551, "promote existing 0-priority tag so
it takes precedence over a new 0-tag"). Those compose to exactly two rules --
a `Priority => 0` value never displaces a value already present, and a
normal-priority value always displaces whatever is present. The second is what
a plain `HashMap::insert` already does, so only the first needed writing:
`shared::tag_priority::insert_low_priority`.
`%Pentax::LensRec` and `%Pentax::LensInfo*` are BOTH `Priority => 0`
(Pentax.pm:4202, :4248), so the winner is decided by first-found, not by a
priority difference -- and `0 0` is a real lens id ("M-42 or No Lens"), not a
null, which is why the clobber looked like data. `%Pentax::CameraInfo` carries
ExifTool's own reason on the line: "(Optio SVi uses incorrect Optio SV ID
here)" (Pentax.pm:4723).
The generated sub-directory decoder now carries the flag too, so this is fixed
for every vendor's tables rather than for Pentax alone. `codegen_subdirs.py`
had `Priority` in the list of keys that "do not change what a reader produces",
which is how it went missing; it now reads `Priority`/`Avoid`, honours a
table-level `PRIORITY`, and refuses any priority value it does not model rather
than silently treating it as normal. Regenerating the three affected table
files from ExifTool 13.55 reproduces them byte-for-byte apart from the added
flag, and all 155 fields are `low_priority: false` -- no generated table is
affected today, so the codegen change is prevention, not behaviour.
Measured over 1227 files (Pentax, Panasonic, FujiFilm and the corpus root),
105708 compared Group1:Name pairs: 5 fixed, 0 regressed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
swackhamer
force-pushed
the
fix/tag-priority-subdirectory
branch
from
August 2, 2026 09:07
05b0354 to
9d981d4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Five corpus files carry the same Pentax tag twice — once in
%Pentax::Main, once inside a binary sub-directory — and oxidex printed the sub-directory copy. That is the worst shape a defect can take here: a real ExifTool tag name carrying the wrong value, with nothing downstream able to tell.Pentax/PentaxK100D.jpgLensTypeM-42 or No Lenssmc PENTAX-DA 21mm F3.2 AL LimitedPentax/PentaxK-50.jpgLensTypeM-42 or No LensSigmaPentax/PentaxK-5II.jpgLensTypeK or M LensSigmaPentax/PentaxOptioSVi.jpgPentaxModelIDOptio SVOptio SViPentax/PentaxOptioL20.jpgPentaxModelIDOptio S7Optio L20How ExifTool actually decides this
FoundTag(ExifTool.pm:9448) reads the tag's priority at:9469-9473— the tag's ownPriority, else the table'sPRIORITY, else0when the tag isAvoid— and on a duplicate name compares it against the priority already recorded (:9564).Two details make the rule. A 0-priority value records no entry in
PRIORITY(:9589stores it "only if exists and is non-zero"), and a missing entry is promoted to 1 (:9545-9551, whose comment reads "promote existing 0-priority tag so it takes precedence over a new 0-tag"). So:Priority => 00 >= 1is falsePriority => 01 >= 1holdsPriority => 0Priority => 00 >= 1is false1 >= 1holdsWhich composes, for any number of instances in any order, to exactly two rules:
Priority => 0value never displaces a value already present;The second is what a plain
HashMap::insertalready does, so only the first needed writing:shared::tag_priority::insert_low_priority.Why the values looked like data
%Pentax::LensRecand%Pentax::LensInfo*are bothPriority => 0(Pentax.pm:4202,:4248), so the winner is decided by first-found, not by a priority difference — and0 0is a real lens id (M-42 or No Lens), not a null.%Pentax::CameraInfocarries ExifTool's own reason on the line: "(Optio SVi uses incorrect Optio SV ID here)" (Pentax.pm:4723).General, not a special case
The generated sub-directory decoder carries the flag too, so this is fixed for every vendor's tables rather than for Pentax alone.
codegen_subdirs.pylistedPriorityamong the keys that "do not change what a reader produces" — which is how it went missing. It now readsPriority/Avoid, honours a table-levelPRIORITY, and refuses any priority value it does not model rather than silently treating it as normal.Regenerating the three affected table files from ExifTool 13.55 (the version they were generated from) reproduces them byte-for-byte apart from the added flag, and all 155 fields come out
low_priority: false— no generated table is affected today, so that half is prevention, not behaviour change.Measurement
1227 files (Pentax, Panasonic, FujiFilm, corpus root), 105,708 compared
Group1:Namepairs, scored per file against ExifTool 13.59:5 fixed, 0 regressed.
Mutation-tested three ways — reverting the helper to
insert, reverting both Pentax call sites, and reverting only theCameraInfosite — each makes the new tests fail with the exact reported wrong values.just testgreen (4,374 passed).cargo clippyclean on the touched files.Exposure beyond this PR
Across the whole 4,238-file corpus, 856
(file, Group1:Name)pairs have duplicate instances whose values differ; 244 have aPriority => 0loser. 39 of those have the loser in a table oxidex has transcribed — all insrc/exiftool_tables/binary_tables.rs, which is reference data whoseFieldstruct carries no priority. Those are latent, not live: oxidex has a single writer for each today (Nikon:ISOfromNikon::Main,Canon:SharpnessfromCanon::CameraSettings), so they are correct now but would break the moment those tables get wired up.🤖 Generated with Claude Code