Fix chlist attribute size and scan line offset table - #112
Merged
ds5678 merged 1 commit intoAug 14, 2026
Merged
Conversation
OpenEXRFileLayout defines a chlist attribute value as "A sequence of channels followed by a null byte (0x00)", and the attribute size as "the size (in bytes) of the attribute value". Size left out the terminating null byte, so a reader that trusts the declared size lands on that byte and reads it as an empty attribute name, which terminates the header after the first attribute. The same document defines a regular scan line block as "y coordinate | pixel data size | pixel data", and an offset table entry as "the distance, in bytes, between the start of the file and the start of the chunk". The table advanced by one int plus the pixel data, leaving out the y coordinate, so every entry after the first pointed four bytes past the start of its chunk. https://openexr.com/en/latest/OpenEXRFileLayout.html
ds5678
approved these changes
Aug 14, 2026
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.
Fix chlist attribute size and scan line offset table
Two off-by-N errors in
ExrWriterproduce files that violate theOpenEXR file layout.
Both are single-line fixes. Pixel data is unaffected.
1.
ExrChannelList.Sizeomits the terminating null byteThe spec defines a
chlistvalue as "A sequence of channels followed by a null byte(0x00)", and
attribute sizeas "the size (in bytes) of the attribute value".Sizeonly summed the channels, whileWritealso emits the null byte, so the typedisagrees with itself: it reports 18 bytes for a one-channel list and writes 19.
libOpenEXR does not notice, because its
chlistreadValueFromignoressizeandloops until it reads an empty channel name. A reader that skips attributes by their
declared size instead lands on that null byte, reads it as an empty attribute name,
and ends the header after the first attribute.
2. The scan line offset table skips the y coordinate
The spec defines a regular scan line block as "y coordinate | pixel data size | pixel
data", and each offset table entry as "the distance, in bytes, between the start of the
file and the start of the chunk". The table advanced by
sizeof(int) + pixelData,leaving out the y coordinate, so entry n points 4*n bytes past the start of its
block. This is the one that makes files fail to open.
Reproduction
Single file, no test assets, no project to add. Drop it in the repository root and run
dotnet run ExrWriterRepro.cs(requires the .NET 10 SDK's file-based app support).Before:
After:
How I hit it
Exporting a Unity HDR cubemap (128x768, 4 channels, half, so 1024-byte scan lines) as
EXR. Blender refused to open the result: the offset table stride was 1028 where the
blocks are 1032 apart, and the
chlistattribute declared 72 bytes where 73 arewritten. Both reproduce with the generated image above, so nothing about the source
texture is involved.