From d1bde69f9bf4b3df99c90fdaee2479d872ff29c9 Mon Sep 17 00:00:00 2001 From: ShiyumeMeguri <102138304+ShiyumeMeguri@users.noreply.github.com> Date: Fri, 14 Aug 2026 10:57:09 +0900 Subject: [PATCH] Fix chlist attribute size and scan line offset table 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 --- AssetRipper.TextureDecoder/Exr/ExrChannelList.cs | 2 +- AssetRipper.TextureDecoder/Exr/ExrWriter.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/AssetRipper.TextureDecoder/Exr/ExrChannelList.cs b/AssetRipper.TextureDecoder/Exr/ExrChannelList.cs index c23487c..8f042ed 100644 --- a/AssetRipper.TextureDecoder/Exr/ExrChannelList.cs +++ b/AssetRipper.TextureDecoder/Exr/ExrChannelList.cs @@ -4,7 +4,7 @@ public readonly record struct ExrChannelList(ExrChannel[] Channels) : IExrDataTy { public static ReadOnlySpan TypeName => "chlist"u8; - public int Size => Channels.Sum(c => c.Size); + public int Size => Channels.Sum(c => c.Size) + sizeof(byte); public void Write(BinaryWriter writer) { diff --git a/AssetRipper.TextureDecoder/Exr/ExrWriter.cs b/AssetRipper.TextureDecoder/Exr/ExrWriter.cs index 5f73e78..056325b 100644 --- a/AssetRipper.TextureDecoder/Exr/ExrWriter.cs +++ b/AssetRipper.TextureDecoder/Exr/ExrWriter.cs @@ -75,7 +75,7 @@ public static void Write(Stream stream, int width, int he for (int i = 0; i < height; i++) { writer.Write(offset); - offset += sizeof(int) + ChannelCount * ChannelSize * width; + offset += sizeof(int) + sizeof(int) + ChannelCount * ChannelSize * width; } //Scan lines