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 where other raw processors reproduce it. The value sits in the same
proprietary directory as the crop tags getDefaultCrop() already reads, two
entries along, stored height then width like the cropped size 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: Fujifilm's
own cropped size here stays at the native shape whatever ratio is selected,
so there is no usable rectangle to hand out.
The tag is written whether or not a ratio was picked, so a plain 3:2 frame
carries one too. Reporting that would have consumers crop every raf to an
exact 3:2 and trim the sensor margins off images nobody chose a ratio for, so
it is compared against the cropped size and only a differing ratio is
reported.
FiffParser needs the tag listed among those read as SHORT. Left to the
default UNDEFINED its count comes out as the byte length rather than the
number of shorts, and the entry cannot be read at all.
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.
Verified against CC0 samples from raw.pixls.us: Fujifilm X-T200
DSCF0074.RAF, shot at 16:9, reports {16, 9} and exports 16:9 through
darktable; Fujifilm X100V DSCF0734.RAF, shot at the native 3:2, reports
nothing and exports the full frame. The X100V pair also confirms the byte
order, reading (2, 3) against a cropped size of (4160, 6240).
Not covered: fuji_xe4_32_lossy.RAF from the same database fails to
decompress on develop with "compressed RAF header check", which happens
before this code and is unrelated, but leaves lossy compressed rafs
unverified here.
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>
This branch has not been deployed
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.
Supersedes #986, which was closed so the work could be squashed into a single
commit. Same change, plus the two fixes that testing forced out.
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:FUJI_RAWIMAGEASPECTRATIO = 0x0115inTiffTag.h, aliasingSAMPLESPERPIXELthe same wayFUJI_RAWIMAGECROPTOPLEFTaliasesMODELFiffParserreads asSHORT; left to thedefault
UNDEFINEDits count is the byte length rather than the number ofshorts and the entry cannot be read at all
ImageMetaData::cameraAspectRatio, anOptional<std::array<int, 2>>RafDecoder::decodeMetaDataInternal(), ignoring it when itmatches the cropped size, since the tag is written whether or not a ratio
was picked and reporting a native 3:2 would have consumers crop every raf
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 center
it on whatever it actually received. It is also all there is here: Fujifilm's
RawImageCroppedSizebeside this tag stays at the native shape whateverratio is selected, so there is no usable rectangle to hand out.
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.
Testing
CC0 samples from raw.pixls.us, consumed end to end through darktable:
DSCF0074.RAF{16, 9}, exports 16:9DSCF0734.RAFThe X100V pair also settles the byte order, reading
(2, 3)against acropped size of
(4160, 6240), so height first, asgetDefaultCrop()already assumes for the sibling tag.
Both problems above were found by running it rather than by reading it, which
is worth saying plainly: as first submitted to #986 this read nothing at all,
and once reading, it would have cropped every raf.
Not covered:
fuji_xe4_32_lossy.RAFfrom the same database fails todecompress on current develop with "compressed RAF header check". That is
unrelated and happens before this code, but it leaves lossy compressed rafs
unverified here.
Happy to add a test if you point me at where a sample would live.
Context
The consuming side is darktable-org/darktable#22088, which reproduces this
framing as an editable crop and already reads Canon and Olympus through
Exiv2. Fujifilm cannot be read that way, the value being in the raf container
rather than the Exif makernote, which is why it wants doing here. Consuming
this field is a follow-up and not part of this PR.