RafDecoder: read the aspect ratio dialed in on the camera - #986
Conversation
Fujifilm bodies with an aspect ratio setting record the choice but leave the raw data uncropped, so the framing chosen while shooting is otherwise lost to consumers. The value sits in the same proprietary directory as the crop tags getDefaultCrop() already reads, two entries along, stored height then width like the FUJI_RAWIMAGECROPPEDSIZE beside it. Expose it as ImageMetaData::cameraAspectRatio rather than as a rectangle. The box a vendor describes is relative to that vendor's own output area, which is not the area we hand out, so a consumer that centers a ratio itself does not have to track the difference. It is also all some vendors record. UNTESTED: I have no Fujifilm body and no raf sample to try this on. The tag number and its layout are taken from ExifTool's FujiFilm::RAF table and cross-checked against LibRaw's fuji.cpp, and the byte order matches the sibling tag already read a few lines away in getDefaultCrop(), but none of that is a substitute for running it. Verification by someone with a Fujifilm body would be very welcome. AI disclosure, per AGENTS.md: this change was written with AI assistance (Claude Code with Claude Opus 5). I have reviewed it, it builds clean, and I take responsibility for it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Without this the entry falls to the default UNDEFINED case and its count
comes out as the byte length rather than the number of shorts, so
RafDecoder cannot read it and the ratio is silently dropped.
Found by running the previous commit against Fujifilm X-T200 sample
DSCF0074.RAF from raw.pixls.us, which is shot at 16:9. It now reads as
{16, 9}, and a 3:2 sample from the same database still reads as absent
rather than as a ratio.
AI disclosure, per AGENTS.md: written with AI assistance (Claude Code with
Claude Opus 5). I have reviewed it and take responsibility for it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The tag is written whether or not a ratio was picked on the camera, so a
plain 3:2 frame carries one too. Reporting that would have consumers crop
every raf to an exact 3:2, trimming the sensor margins off images nobody
chose a ratio for.
Compare it against the cropped size in the same directory, which stays at
the native shape whatever ratio is selected, and only report a ratio that
differs from it.
Checked against raw.pixls.us samples: Fujifilm X-T200 DSCF0074.RAF, shot at
16:9, reports {16, 9}; Fujifilm X100V DSCF0734.RAF, shot at the native 3:2,
reports nothing.
AI disclosure, per AGENTS.md: written with AI assistance (Claude Code with
Claude Opus 5). I have reviewed it and take responsibility for it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
It is no longer untested. @gi-man pointed me at raw.pixls.us on the darktable Two things were wrong with what I first pushed, both of which only running it The entry was parsed as UNDEFINED. The tag is present even at the native ratio. A plain 3:2 frame carries Verified end to end through darktable with the field consumed:
The samples also settle the byte order I had inferred rather than observed: One thing I could not test: Happy to add a test if you point me at where a sample would live. Disclosure, per AGENTS.md: written with AI assistance (Claude Code with |
AI disclosure
Per AGENTS.md, this change was written with AI assistance (Claude Code
with Claude Opus 5). I have read and reviewed it, it builds clean, and I
bear responsibility for it. I am happy to argue any part of it.
What
Fujifilm bodies with an aspect ratio setting record the choice but leave the
raw data uncropped. Consumers therefore see the full sensor readout and the
framing chosen while shooting is lost, where other raw processors reproduce
it and let the user take it back.
The value is tag
0x0115in the same Fujifilm proprietary directory thatRafDecoder::getDefaultCrop()already reads0x0110and0x0111from, sothis is a small addition rather than new parsing:
FUJI_RAWIMAGEASPECTRATIO = 0x0115inTiffTag.h, aliasingSAMPLESPERPIXELthe same wayFUJI_RAWIMAGECROPTOPLEFTaliasesMODELImageMetaData::cameraAspectRatio, anOptional<std::array<int, 2>>RafDecoder::decodeMetaDataInternal()Why a ratio and not a rectangle
The box a vendor describes is relative to that vendor's own output area,
which is not the area rawspeed hands out. A consumer given a rectangle would
have to track that difference per vendor; a consumer given a ratio can just
center it on whatever it actually received. It is also the only thing some
vendors record - Fujifilm's own
RawImageCroppedSizebeside this tag holdsthe native area, not the selected one, so there is no usable rectangle here
in the first place.
The field is named for the concept rather than for Fujifilm, so the other
decoders can fill it as and when someone does that work.
Untested - a Fujifilm owner is needed
I have no Fujifilm body and no raf file to try this on. What I did check:
FujiFilm::RAFtablesrc/metadata/fuji.cppand maps it toraw_aspectFUJI_RAWIMAGECROPPEDSIZE, read a fewlines away in
getDefaultCrop()with the same orderinghasEntryRecursive()guards the lookup, sincegetIFDWithTag()throws andnot every raf carries that directory
None of that substitutes for running it on a real file. If someone with a
Fujifilm body that has an aspect ratio setting could verify that a raf shot
at 1:1 or 16:9 comes out with
cameraAspectRatioset to the matching pair,and that ordinary raf files are unaffected, I would be grateful. I am happy
to add a test if you can point me at where a sample would live.
Context
This is the missing half of darktable-org/darktable#22088, which reproduces
this framing as an editable crop. That side reads the ratio through Exiv2,
which reaches Canon but cannot see Fujifilm's - the value is in the raf
container rather than the Exif makernote, which is why it wants doing here.
Consuming this field in darktable is a follow-up and not part of this PR.