From 344d49d86fb172409430c31b03cc3a3b1798ba2c Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Fri, 24 Apr 2026 13:26:23 +0200 Subject: [PATCH] Use Width Property from ExrBaseDecompressor --- .../Compressors/NoneExrCompressor.cs | 5 +-- .../Compressors/ZipExrCompressor.cs | 5 +-- .../Decompressors/B44ExrCompression.cs | 33 +++++++++---------- .../Decompressors/NoneExrCompression.cs | 5 +-- .../Decompressors/Pxr24Compression.cs | 17 ++++++---- .../Decompressors/RunLengthExrCompression.cs | 5 +-- .../Decompressors/ZipExrCompression.cs | 5 +-- .../Exr/Compression/ExrBaseCompression.cs | 4 ++- .../Exr/Compression/ExrBaseDecompressor.cs | 5 +-- .../Exr/Compression/ExrCompressorFactory.cs | 8 +++-- .../Exr/Compression/ExrDecompressorFactory.cs | 8 ++--- .../Formats/Exr/ExrBaseCompressor.cs | 5 +-- src/ImageSharp/Formats/Exr/ExrEncoderCore.cs | 4 +-- 13 files changed, 60 insertions(+), 49 deletions(-) diff --git a/src/ImageSharp/Formats/Exr/Compression/Compressors/NoneExrCompressor.cs b/src/ImageSharp/Formats/Exr/Compression/Compressors/NoneExrCompressor.cs index 58768e990f..c1240667e7 100644 --- a/src/ImageSharp/Formats/Exr/Compression/Compressors/NoneExrCompressor.cs +++ b/src/ImageSharp/Formats/Exr/Compression/Compressors/NoneExrCompressor.cs @@ -17,8 +17,9 @@ internal class NoneExrCompressor : ExrBaseCompressor /// The memory allocator. /// Bytes per row block. /// Bytes per pixel row. - public NoneExrCompressor(Stream output, MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow) - : base(output, allocator, bytesPerBlock, bytesPerRow) + /// The witdh of one row in pixels. + public NoneExrCompressor(Stream output, MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, int width) + : base(output, allocator, bytesPerBlock, bytesPerRow, width) { } diff --git a/src/ImageSharp/Formats/Exr/Compression/Compressors/ZipExrCompressor.cs b/src/ImageSharp/Formats/Exr/Compression/Compressors/ZipExrCompressor.cs index ef7285da0c..bf5f078585 100644 --- a/src/ImageSharp/Formats/Exr/Compression/Compressors/ZipExrCompressor.cs +++ b/src/ImageSharp/Formats/Exr/Compression/Compressors/ZipExrCompressor.cs @@ -24,9 +24,10 @@ internal class ZipExrCompressor : ExrBaseCompressor /// The memory allocator. /// The bytes per block. /// The bytes per row. + /// The witdh of one row in pixels. /// The compression level for deflate compression. - public ZipExrCompressor(Stream output, MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, DeflateCompressionLevel compressionLevel) - : base(output, allocator, bytesPerBlock, bytesPerRow) + public ZipExrCompressor(Stream output, MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, int width, DeflateCompressionLevel compressionLevel) + : base(output, allocator, bytesPerBlock, bytesPerRow, width) { this.compressionLevel = compressionLevel; this.buffer = allocator.Allocate((int)bytesPerBlock); diff --git a/src/ImageSharp/Formats/Exr/Compression/Decompressors/B44ExrCompression.cs b/src/ImageSharp/Formats/Exr/Compression/Decompressors/B44ExrCompression.cs index 3c4e6b1483..64774537fa 100644 --- a/src/ImageSharp/Formats/Exr/Compression/Decompressors/B44ExrCompression.cs +++ b/src/ImageSharp/Formats/Exr/Compression/Decompressors/B44ExrCompression.cs @@ -13,8 +13,6 @@ namespace SixLabors.ImageSharp.Formats.Exr.Compression.Decompressors; /// internal class B44ExrCompression : ExrBaseDecompressor { - private readonly int width; - private readonly uint rowsPerBlock; private readonly int channelCount; @@ -35,9 +33,8 @@ internal class B44ExrCompression : ExrBaseDecompressor /// The width of a pixel row in pixels. /// The number of channels of the image. public B44ExrCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, uint rowsPerBlock, int width, int channelCount) - : base(allocator, bytesPerBlock, bytesPerRow) + : base(allocator, bytesPerBlock, bytesPerRow, width) { - this.width = width; this.rowsPerBlock = rowsPerBlock; this.channelCount = channelCount; this.tmpBuffer = allocator.Allocate((int)(width * rowsPerBlock * channelCount)); @@ -54,17 +51,17 @@ internal class B44ExrCompression : ExrBaseDecompressor { for (int y = 0; y < this.rowsPerBlock; y += 4) { - Span row0 = decompressed.Slice(outputOffset, this.width); - outputOffset += this.width; - Span row1 = decompressed.Slice(outputOffset, this.width); - outputOffset += this.width; - Span row2 = decompressed.Slice(outputOffset, this.width); - outputOffset += this.width; - Span row3 = decompressed.Slice(outputOffset, this.width); - outputOffset += this.width; + Span row0 = decompressed.Slice(outputOffset, this.Width); + outputOffset += this.Width; + Span row1 = decompressed.Slice(outputOffset, this.Width); + outputOffset += this.Width; + Span row2 = decompressed.Slice(outputOffset, this.Width); + outputOffset += this.Width; + Span row3 = decompressed.Slice(outputOffset, this.Width); + outputOffset += this.Width; int rowOffset = 0; - for (int x = 0; x < this.width && bytesLeft > 0; x += 4) + for (int x = 0; x < this.Width && bytesLeft > 0; x += 4) { int bytesRead = stream.Read(this.scratch, 0, 3); if (bytesRead == 0) @@ -90,7 +87,7 @@ internal class B44ExrCompression : ExrBaseDecompressor bytesLeft -= 14; } - int n = x + 3 < this.width ? 4 : this.width - x; + int n = x + 3 < this.Width ? 4 : this.Width - x; if (y + 3 < this.rowsPerBlock) { this.s.AsSpan(0, n).CopyTo(row0[rowOffset..]); @@ -125,16 +122,16 @@ internal class B44ExrCompression : ExrBaseDecompressor // Rearrange the decompressed data such that the data for each scan line form a contiguous block. int offsetDecompressed = 0; int offsetOutput = 0; - int blockSize = (int)(this.width * this.rowsPerBlock); + int blockSize = (int)(this.Width * this.rowsPerBlock); for (int y = 0; y < this.rowsPerBlock; y++) { for (int i = 0; i < this.channelCount; i++) { - decompressed.Slice(offsetDecompressed + (i * blockSize), this.width).CopyTo(outputBuffer[offsetOutput..]); - offsetOutput += this.width; + decompressed.Slice(offsetDecompressed + (i * blockSize), this.Width).CopyTo(outputBuffer[offsetOutput..]); + offsetOutput += this.Width; } - offsetDecompressed += this.width; + offsetDecompressed += this.Width; } } diff --git a/src/ImageSharp/Formats/Exr/Compression/Decompressors/NoneExrCompression.cs b/src/ImageSharp/Formats/Exr/Compression/Decompressors/NoneExrCompression.cs index c15ffbe325..1b045bdeb7 100644 --- a/src/ImageSharp/Formats/Exr/Compression/Decompressors/NoneExrCompression.cs +++ b/src/ImageSharp/Formats/Exr/Compression/Decompressors/NoneExrCompression.cs @@ -17,8 +17,9 @@ internal class NoneExrCompression : ExrBaseDecompressor /// The memory allocator. /// The bytes per pixel row block. /// The bytes per pixel row. - public NoneExrCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow) - : base(allocator, bytesPerBlock, bytesPerRow) + /// The number of pixels per row. + public NoneExrCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, int width) + : base(allocator, bytesPerBlock, bytesPerRow, width) { } diff --git a/src/ImageSharp/Formats/Exr/Compression/Decompressors/Pxr24Compression.cs b/src/ImageSharp/Formats/Exr/Compression/Decompressors/Pxr24Compression.cs index 9e97fd0ad5..d720c190f9 100644 --- a/src/ImageSharp/Formats/Exr/Compression/Decompressors/Pxr24Compression.cs +++ b/src/ImageSharp/Formats/Exr/Compression/Decompressors/Pxr24Compression.cs @@ -10,6 +10,9 @@ using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Formats.Exr.Compression.Decompressors; +/// +/// Implementation of PXR24 decompressor for EXR image data. +/// internal class Pxr24Compression : ExrBaseDecompressor { private readonly IMemoryOwner tmpBuffer; @@ -18,20 +21,20 @@ internal class Pxr24Compression : ExrBaseDecompressor private readonly int channelCount; - private readonly int width; - /// /// Initializes a new instance of the class. /// /// The memory allocator. /// The bytes per pixel row block. /// The bytes per pixel row. + /// The pixel rows per block. + /// The witdh of one row in pixels. + /// The number of channels for a pixel. public Pxr24Compression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, uint rowsPerBlock, int width, int channelCount) - : base(allocator, bytesPerBlock, bytesPerRow) + : base(allocator, bytesPerBlock, bytesPerRow, width) { this.tmpBuffer = allocator.Allocate((int)bytesPerBlock); this.rowsPerBlock = rowsPerBlock; - this.width = width; this.channelCount = channelCount; } @@ -76,11 +79,11 @@ internal class Pxr24Compression : ExrBaseDecompressor for (int c = 0; c < this.channelCount; c++) { int offsetT1 = lastIn; - lastIn += this.width; + lastIn += this.Width; int offsetT2 = lastIn; - lastIn += this.width; + lastIn += this.Width; uint pixel = 0; - for (int x = 0; x < this.width; x++) + for (int x = 0; x < this.Width; x++) { uint t1 = uncompressed[offsetT1]; uint t2 = uncompressed[offsetT2]; diff --git a/src/ImageSharp/Formats/Exr/Compression/Decompressors/RunLengthExrCompression.cs b/src/ImageSharp/Formats/Exr/Compression/Decompressors/RunLengthExrCompression.cs index 489493d82f..29782ae03d 100644 --- a/src/ImageSharp/Formats/Exr/Compression/Decompressors/RunLengthExrCompression.cs +++ b/src/ImageSharp/Formats/Exr/Compression/Decompressors/RunLengthExrCompression.cs @@ -22,8 +22,9 @@ internal class RunLengthExrCompression : ExrBaseDecompressor /// The memory allocator. /// The bytes per pixel row block. /// The bytes per row. - public RunLengthExrCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow) - : base(allocator, bytesPerBlock, bytesPerRow) => this.tmpBuffer = allocator.Allocate((int)bytesPerBlock); + /// The witdh of one row in pixels. + public RunLengthExrCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, int width) + : base(allocator, bytesPerBlock, bytesPerRow, width) => this.tmpBuffer = allocator.Allocate((int)bytesPerBlock); /// public override void Decompress(BufferedReadStream stream, uint compressedBytes, Span buffer) diff --git a/src/ImageSharp/Formats/Exr/Compression/Decompressors/ZipExrCompression.cs b/src/ImageSharp/Formats/Exr/Compression/Decompressors/ZipExrCompression.cs index dafe3d8321..4333f53cb5 100644 --- a/src/ImageSharp/Formats/Exr/Compression/Decompressors/ZipExrCompression.cs +++ b/src/ImageSharp/Formats/Exr/Compression/Decompressors/ZipExrCompression.cs @@ -22,8 +22,9 @@ internal class ZipExrCompression : ExrBaseDecompressor /// The memory allocator. /// The bytes per pixel row block. /// The bytes per pixel row. - public ZipExrCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow) - : base(allocator, bytesPerBlock, bytesPerRow) => this.tmpBuffer = allocator.Allocate((int)bytesPerBlock); + /// The witdh of one row in pixels. + public ZipExrCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, int width) + : base(allocator, bytesPerBlock, bytesPerRow, width) => this.tmpBuffer = allocator.Allocate((int)bytesPerBlock); /// public override void Decompress(BufferedReadStream stream, uint compressedBytes, Span buffer) diff --git a/src/ImageSharp/Formats/Exr/Compression/ExrBaseCompression.cs b/src/ImageSharp/Formats/Exr/Compression/ExrBaseCompression.cs index b116dffc65..5912fcdecf 100644 --- a/src/ImageSharp/Formats/Exr/Compression/ExrBaseCompression.cs +++ b/src/ImageSharp/Formats/Exr/Compression/ExrBaseCompression.cs @@ -18,11 +18,13 @@ internal abstract class ExrBaseCompression : IDisposable /// The memory allocator. /// The bytes per block. /// The bytes per row. - protected ExrBaseCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow) + /// The number of pixels of a row. + protected ExrBaseCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, int width) { this.Allocator = allocator; this.BytesPerBlock = bytesPerBlock; this.BytesPerRow = bytesPerRow; + this.Width = width; } /// diff --git a/src/ImageSharp/Formats/Exr/Compression/ExrBaseDecompressor.cs b/src/ImageSharp/Formats/Exr/Compression/ExrBaseDecompressor.cs index efe3c7877f..000e6ecea8 100644 --- a/src/ImageSharp/Formats/Exr/Compression/ExrBaseDecompressor.cs +++ b/src/ImageSharp/Formats/Exr/Compression/ExrBaseDecompressor.cs @@ -17,8 +17,9 @@ internal abstract class ExrBaseDecompressor : ExrBaseCompression /// The memory allocator. /// The bytes per row block. /// The bytes per row. - protected ExrBaseDecompressor(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow) - : base(allocator, bytesPerBlock, bytesPerRow) + /// The number of pixels per row. + protected ExrBaseDecompressor(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, int width) + : base(allocator, bytesPerBlock, bytesPerRow, width) { } diff --git a/src/ImageSharp/Formats/Exr/Compression/ExrCompressorFactory.cs b/src/ImageSharp/Formats/Exr/Compression/ExrCompressorFactory.cs index b1b7d2e8e6..497bd492aa 100644 --- a/src/ImageSharp/Formats/Exr/Compression/ExrCompressorFactory.cs +++ b/src/ImageSharp/Formats/Exr/Compression/ExrCompressorFactory.cs @@ -21,6 +21,7 @@ internal static class ExrCompressorFactory /// The output stream. /// The bytes per block. /// The bytes per row. + /// The witdh of one row in pixels. /// The deflate compression level. /// A compressor for EXR image data. public static ExrBaseCompressor Create( @@ -29,11 +30,12 @@ internal static class ExrCompressorFactory Stream output, uint bytesPerBlock, uint bytesPerRow, + int width, DeflateCompressionLevel compressionLevel = DeflateCompressionLevel.DefaultCompression) => method switch { - ExrCompression.None => new NoneExrCompressor(output, allocator, bytesPerBlock, bytesPerRow), - ExrCompression.Zips => new ZipExrCompressor(output, allocator, bytesPerBlock, bytesPerRow, compressionLevel), - ExrCompression.Zip => new ZipExrCompressor(output, allocator, bytesPerBlock, bytesPerRow, compressionLevel), + ExrCompression.None => new NoneExrCompressor(output, allocator, bytesPerBlock, bytesPerRow, width), + ExrCompression.Zips => new ZipExrCompressor(output, allocator, bytesPerBlock, bytesPerRow, width, compressionLevel), + ExrCompression.Zip => new ZipExrCompressor(output, allocator, bytesPerBlock, bytesPerRow, width, compressionLevel), _ => throw ExrThrowHelper.NotSupportedCompressor(method.ToString()), }; } diff --git a/src/ImageSharp/Formats/Exr/Compression/ExrDecompressorFactory.cs b/src/ImageSharp/Formats/Exr/Compression/ExrDecompressorFactory.cs index bd8df9230b..8123284585 100644 --- a/src/ImageSharp/Formats/Exr/Compression/ExrDecompressorFactory.cs +++ b/src/ImageSharp/Formats/Exr/Compression/ExrDecompressorFactory.cs @@ -32,10 +32,10 @@ internal static class ExrDecompressorFactory uint rowsPerBlock, int channelCount) => method switch { - ExrCompression.None => new NoneExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow), - ExrCompression.Zips => new ZipExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow), - ExrCompression.Zip => new ZipExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow), - ExrCompression.RunLengthEncoded => new RunLengthExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow), + ExrCompression.None => new NoneExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow, width), + ExrCompression.Zips => new ZipExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow, width), + ExrCompression.Zip => new ZipExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow, width), + ExrCompression.RunLengthEncoded => new RunLengthExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow, width), ExrCompression.B44 => new B44ExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width, channelCount), ExrCompression.Pxr24 => new Pxr24Compression(memoryAllocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width, channelCount), _ => throw ExrThrowHelper.NotSupportedDecompressor(nameof(method)), diff --git a/src/ImageSharp/Formats/Exr/ExrBaseCompressor.cs b/src/ImageSharp/Formats/Exr/ExrBaseCompressor.cs index 1dcdec5be0..83887fd5f1 100644 --- a/src/ImageSharp/Formats/Exr/ExrBaseCompressor.cs +++ b/src/ImageSharp/Formats/Exr/ExrBaseCompressor.cs @@ -14,8 +14,9 @@ internal abstract class ExrBaseCompressor : ExrBaseCompression /// The memory allocator. /// Bytes per row block. /// Bytes per pixel row. - protected ExrBaseCompressor(Stream output, MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow) - : base(allocator, bytesPerBlock, bytesPerRow) + /// The number of pixels per row. + protected ExrBaseCompressor(Stream output, MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, int width) + : base(allocator, bytesPerBlock, bytesPerRow, width) => this.Output = output; /// diff --git a/src/ImageSharp/Formats/Exr/ExrEncoderCore.cs b/src/ImageSharp/Formats/Exr/ExrEncoderCore.cs index 04ca5e40c8..c6824c6aad 100644 --- a/src/ImageSharp/Formats/Exr/ExrEncoderCore.cs +++ b/src/ImageSharp/Formats/Exr/ExrEncoderCore.cs @@ -181,7 +181,7 @@ internal sealed class ExrEncoderCore Span blueBuffer = rgbBuffer.GetSpan().Slice(width * 2, width); Span alphaBuffer = rgbBuffer.GetSpan().Slice(width * 3, width); - using ExrBaseCompressor compressor = ExrCompressorFactory.Create(compression, this.memoryAllocator, stream, bytesPerBlock, bytesPerRow); + using ExrBaseCompressor compressor = ExrCompressorFactory.Create(compression, this.memoryAllocator, stream, bytesPerBlock, bytesPerRow, width); ulong[] rowOffsets = new ulong[height]; for (uint y = 0; y < height; y += rowsPerBlock) @@ -273,7 +273,7 @@ internal sealed class ExrEncoderCore Span blueBuffer = rgbBuffer.GetSpan().Slice(width * 2, width); Span alphaBuffer = rgbBuffer.GetSpan().Slice(width * 3, width); - using ExrBaseCompressor compressor = ExrCompressorFactory.Create(compression, this.memoryAllocator, stream, bytesPerBlock, bytesPerRow); + using ExrBaseCompressor compressor = ExrCompressorFactory.Create(compression, this.memoryAllocator, stream, bytesPerBlock, bytesPerRow, width); Rgba128 rgb = default; ulong[] rowOffsets = new ulong[height];