From 2bf2e9563853127f1d2f55f2e62ef671741f4924 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sun, 26 Apr 2026 15:12:55 +0200 Subject: [PATCH] Move rowsPerBlock to base compression class --- .../Compressors/NoneExrCompressor.cs | 5 +++-- .../Compressors/ZipExrCompressor.cs | 5 +++-- .../Decompressors/B44ExrCompression.cs | 19 ++++++++----------- .../Decompressors/NoneExrCompression.cs | 5 +++-- .../Decompressors/Pxr24Compression.cs | 9 ++------- .../Decompressors/RunLengthExrCompression.cs | 4 ++-- .../Decompressors/ZipExrCompression.cs | 7 +++---- .../Exr/Compression/ExrBaseCompression.cs | 9 ++++++++- .../Exr/Compression/ExrBaseDecompressor.cs | 5 +++-- .../Exr/Compression/ExrCompressorFactory.cs | 8 +++++--- .../Exr/Compression/ExrDecompressorFactory.cs | 9 +++++---- .../Formats/Exr/ExrBaseCompressor.cs | 5 +++-- src/ImageSharp/Formats/Exr/ExrEncoderCore.cs | 4 ++-- 13 files changed, 50 insertions(+), 44 deletions(-) diff --git a/src/ImageSharp/Formats/Exr/Compression/Compressors/NoneExrCompressor.cs b/src/ImageSharp/Formats/Exr/Compression/Compressors/NoneExrCompressor.cs index c1240667e7..8aca0da65e 100644 --- a/src/ImageSharp/Formats/Exr/Compression/Compressors/NoneExrCompressor.cs +++ b/src/ImageSharp/Formats/Exr/Compression/Compressors/NoneExrCompressor.cs @@ -17,9 +17,10 @@ internal class NoneExrCompressor : ExrBaseCompressor /// The memory allocator. /// Bytes per row block. /// Bytes per pixel row. + /// The pixel rows per block. /// 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) + public NoneExrCompressor(Stream output, MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, uint rowsPerBlock, int width) + : base(output, allocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width) { } diff --git a/src/ImageSharp/Formats/Exr/Compression/Compressors/ZipExrCompressor.cs b/src/ImageSharp/Formats/Exr/Compression/Compressors/ZipExrCompressor.cs index bf5f078585..01248cc395 100644 --- a/src/ImageSharp/Formats/Exr/Compression/Compressors/ZipExrCompressor.cs +++ b/src/ImageSharp/Formats/Exr/Compression/Compressors/ZipExrCompressor.cs @@ -24,10 +24,11 @@ internal class ZipExrCompressor : ExrBaseCompressor /// The memory allocator. /// The bytes per block. /// The bytes per row. + /// The pixel rows per block. /// The witdh of one row in pixels. /// The compression level for deflate compression. - public ZipExrCompressor(Stream output, MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, int width, DeflateCompressionLevel compressionLevel) - : base(output, allocator, bytesPerBlock, bytesPerRow, width) + public ZipExrCompressor(Stream output, MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, uint rowsPerBlock, int width, DeflateCompressionLevel compressionLevel) + : base(output, allocator, bytesPerBlock, bytesPerRow, rowsPerBlock, 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 64774537fa..06df7b6a25 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 uint rowsPerBlock; - private readonly int channelCount; private readonly byte[] scratch = new byte[14]; @@ -29,13 +27,12 @@ internal class B44ExrCompression : ExrBaseDecompressor /// The memory allocator. /// The bytes per pixel row block. /// The bytes per row. - /// The rows per block. + /// The pixel rows per block. /// 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, width) + : base(allocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width) { - this.rowsPerBlock = rowsPerBlock; this.channelCount = channelCount; this.tmpBuffer = allocator.Allocate((int)(width * rowsPerBlock * channelCount)); } @@ -49,7 +46,7 @@ internal class B44ExrCompression : ExrBaseDecompressor int bytesLeft = (int)compressedBytes; for (int i = 0; i < this.channelCount && bytesLeft > 0; i++) { - for (int y = 0; y < this.rowsPerBlock; y += 4) + for (int y = 0; y < this.RowsPerBlock; y += 4) { Span row0 = decompressed.Slice(outputOffset, this.Width); outputOffset += this.Width; @@ -88,7 +85,7 @@ internal class B44ExrCompression : ExrBaseDecompressor } int n = x + 3 < this.Width ? 4 : this.Width - x; - if (y + 3 < this.rowsPerBlock) + if (y + 3 < this.RowsPerBlock) { this.s.AsSpan(0, n).CopyTo(row0[rowOffset..]); this.s.AsSpan(4, n).CopyTo(row1[rowOffset..]); @@ -98,12 +95,12 @@ internal class B44ExrCompression : ExrBaseDecompressor else { this.s.AsSpan(0, n).CopyTo(row0[rowOffset..]); - if (y + 1 < this.rowsPerBlock) + if (y + 1 < this.RowsPerBlock) { this.s.AsSpan(4, n).CopyTo(row1[rowOffset..]); } - if (y + 2 < this.rowsPerBlock) + if (y + 2 < this.RowsPerBlock) { this.s.AsSpan(8, n).CopyTo(row2[rowOffset..]); } @@ -122,8 +119,8 @@ 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); - for (int y = 0; y < this.rowsPerBlock; y++) + int blockSize = (int)(this.Width * this.RowsPerBlock); + for (int y = 0; y < this.RowsPerBlock; y++) { for (int i = 0; i < this.channelCount; i++) { diff --git a/src/ImageSharp/Formats/Exr/Compression/Decompressors/NoneExrCompression.cs b/src/ImageSharp/Formats/Exr/Compression/Decompressors/NoneExrCompression.cs index 1b045bdeb7..19edb31afe 100644 --- a/src/ImageSharp/Formats/Exr/Compression/Decompressors/NoneExrCompression.cs +++ b/src/ImageSharp/Formats/Exr/Compression/Decompressors/NoneExrCompression.cs @@ -17,9 +17,10 @@ internal class NoneExrCompression : ExrBaseDecompressor /// The memory allocator. /// The bytes per pixel row block. /// The bytes per pixel row. + /// The pixel rows per block. /// The number of pixels per row. - public NoneExrCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, int width) - : base(allocator, bytesPerBlock, bytesPerRow, width) + public NoneExrCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, uint rowsPerBlock, int width) + : base(allocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width) { } diff --git a/src/ImageSharp/Formats/Exr/Compression/Decompressors/Pxr24Compression.cs b/src/ImageSharp/Formats/Exr/Compression/Decompressors/Pxr24Compression.cs index 115f455f04..f45b660e7d 100644 --- a/src/ImageSharp/Formats/Exr/Compression/Decompressors/Pxr24Compression.cs +++ b/src/ImageSharp/Formats/Exr/Compression/Decompressors/Pxr24Compression.cs @@ -2,9 +2,7 @@ // Licensed under the Six Labors Split License. using System.Buffers; -using System.IO.Compression; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Compression.Zlib; using SixLabors.ImageSharp.Formats.Exr.Constants; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; @@ -18,8 +16,6 @@ internal class Pxr24Compression : ExrBaseDecompressor { private readonly IMemoryOwner tmpBuffer; - private readonly uint rowsPerBlock; - private readonly int channelCount; private readonly ExrPixelType pixelType; @@ -35,10 +31,9 @@ internal class Pxr24Compression : ExrBaseDecompressor /// The number of channels for a pixel. /// The pixel type. public Pxr24Compression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, uint rowsPerBlock, int width, int channelCount, ExrPixelType pixelType) - : base(allocator, bytesPerBlock, bytesPerRow, width) + : base(allocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width) { this.tmpBuffer = allocator.Allocate((int)bytesPerBlock); - this.rowsPerBlock = rowsPerBlock; this.channelCount = channelCount; this.pixelType = pixelType; } @@ -56,7 +51,7 @@ internal class Pxr24Compression : ExrBaseDecompressor int lastIn = 0; int outputOffset = 0; - for (int y = 0; y < this.rowsPerBlock; y++) + for (int y = 0; y < this.RowsPerBlock; y++) { for (int c = 0; c < this.channelCount; c++) { diff --git a/src/ImageSharp/Formats/Exr/Compression/Decompressors/RunLengthExrCompression.cs b/src/ImageSharp/Formats/Exr/Compression/Decompressors/RunLengthExrCompression.cs index 29782ae03d..bb3903deb8 100644 --- a/src/ImageSharp/Formats/Exr/Compression/Decompressors/RunLengthExrCompression.cs +++ b/src/ImageSharp/Formats/Exr/Compression/Decompressors/RunLengthExrCompression.cs @@ -23,8 +23,8 @@ internal class RunLengthExrCompression : ExrBaseDecompressor /// The bytes per pixel row block. /// The bytes per row. /// 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 RunLengthExrCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, uint rowsPerBlock, int width) + : base(allocator, bytesPerBlock, bytesPerRow, rowsPerBlock, 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 51f8ab4c38..8bab76f402 100644 --- a/src/ImageSharp/Formats/Exr/Compression/Decompressors/ZipExrCompression.cs +++ b/src/ImageSharp/Formats/Exr/Compression/Decompressors/ZipExrCompression.cs @@ -2,8 +2,6 @@ // Licensed under the Six Labors Split License. using System.Buffers; -using System.IO.Compression; -using SixLabors.ImageSharp.Compression.Zlib; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; @@ -22,9 +20,10 @@ internal class ZipExrCompression : ExrBaseDecompressor /// 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. - public ZipExrCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, int width) - : base(allocator, bytesPerBlock, bytesPerRow, width) => this.tmpBuffer = allocator.Allocate((int)bytesPerBlock); + public ZipExrCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, uint rowsPerBlock, int width) + : base(allocator, bytesPerBlock, bytesPerRow, rowsPerBlock, 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 5912fcdecf..72d5be980b 100644 --- a/src/ImageSharp/Formats/Exr/Compression/ExrBaseCompression.cs +++ b/src/ImageSharp/Formats/Exr/Compression/ExrBaseCompression.cs @@ -18,12 +18,14 @@ internal abstract class ExrBaseCompression : IDisposable /// The memory allocator. /// The bytes per block. /// The bytes per row. + /// The number of pixel rows per block. /// The number of pixels of a row. - protected ExrBaseCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, int width) + protected ExrBaseCompression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, uint rowsPerBlock, int width) { this.Allocator = allocator; this.BytesPerBlock = bytesPerBlock; this.BytesPerRow = bytesPerRow; + this.RowsPerBlock = rowsPerBlock; this.Width = width; } @@ -47,6 +49,11 @@ internal abstract class ExrBaseCompression : IDisposable /// public uint BytesPerBlock { get; } + /// + /// Gets the number of pixel rows per block. + /// + public uint RowsPerBlock { get; } + /// /// Gets the image width. /// diff --git a/src/ImageSharp/Formats/Exr/Compression/ExrBaseDecompressor.cs b/src/ImageSharp/Formats/Exr/Compression/ExrBaseDecompressor.cs index b958982cec..5dfbdf148f 100644 --- a/src/ImageSharp/Formats/Exr/Compression/ExrBaseDecompressor.cs +++ b/src/ImageSharp/Formats/Exr/Compression/ExrBaseDecompressor.cs @@ -19,9 +19,10 @@ internal abstract class ExrBaseDecompressor : ExrBaseCompression /// The memory allocator. /// The bytes per row block. /// The bytes per row. + /// The pixel rows per block. /// The number of pixels per row. - protected ExrBaseDecompressor(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, int width) - : base(allocator, bytesPerBlock, bytesPerRow, width) + protected ExrBaseDecompressor(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, uint rowsPerBlock, int width) + : base(allocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width) { } diff --git a/src/ImageSharp/Formats/Exr/Compression/ExrCompressorFactory.cs b/src/ImageSharp/Formats/Exr/Compression/ExrCompressorFactory.cs index 497bd492aa..0a7d4157f2 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 pixel rows per block. /// The witdh of one row in pixels. /// The deflate compression level. /// A compressor for EXR image data. @@ -30,12 +31,13 @@ internal static class ExrCompressorFactory Stream output, uint bytesPerBlock, uint bytesPerRow, + uint rowsPerBlock, int width, DeflateCompressionLevel compressionLevel = DeflateCompressionLevel.DefaultCompression) => method switch { - 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), + ExrCompression.None => new NoneExrCompressor(output, allocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width), + ExrCompression.Zips => new ZipExrCompressor(output, allocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width, compressionLevel), + ExrCompression.Zip => new ZipExrCompressor(output, allocator, bytesPerBlock, bytesPerRow, rowsPerBlock, 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 6f63a932b7..353d1af117 100644 --- a/src/ImageSharp/Formats/Exr/Compression/ExrDecompressorFactory.cs +++ b/src/ImageSharp/Formats/Exr/Compression/ExrDecompressorFactory.cs @@ -22,6 +22,7 @@ internal static class ExrDecompressorFactory /// The bytes per row. /// The rows per block. /// The number of image channels. + /// The pixel type. /// Decompressor for EXR image data. public static ExrBaseDecompressor Create( ExrCompression method, @@ -33,10 +34,10 @@ internal static class ExrDecompressorFactory int channelCount, ExrPixelType pixelType) => method switch { - 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.None => new NoneExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width), + ExrCompression.Zips => new ZipExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width), + ExrCompression.Zip => new ZipExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width), + ExrCompression.RunLengthEncoded => new RunLengthExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width), ExrCompression.B44 => new B44ExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width, channelCount), ExrCompression.Pxr24 => new Pxr24Compression(memoryAllocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width, channelCount, pixelType), _ => throw ExrThrowHelper.NotSupportedDecompressor(nameof(method)), diff --git a/src/ImageSharp/Formats/Exr/ExrBaseCompressor.cs b/src/ImageSharp/Formats/Exr/ExrBaseCompressor.cs index 83887fd5f1..9e3fe8ec65 100644 --- a/src/ImageSharp/Formats/Exr/ExrBaseCompressor.cs +++ b/src/ImageSharp/Formats/Exr/ExrBaseCompressor.cs @@ -14,9 +14,10 @@ internal abstract class ExrBaseCompressor : ExrBaseCompression /// The memory allocator. /// Bytes per row block. /// Bytes per pixel row. + /// The pixel rows per block. /// The number of pixels per row. - protected ExrBaseCompressor(Stream output, MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, int width) - : base(allocator, bytesPerBlock, bytesPerRow, width) + protected ExrBaseCompressor(Stream output, MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, uint rowsPerBlock, int width) + : base(allocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width) => this.Output = output; /// diff --git a/src/ImageSharp/Formats/Exr/ExrEncoderCore.cs b/src/ImageSharp/Formats/Exr/ExrEncoderCore.cs index c6824c6aad..e2750d8972 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, width); + using ExrBaseCompressor compressor = ExrCompressorFactory.Create(compression, this.memoryAllocator, stream, bytesPerBlock, bytesPerRow, rowsPerBlock, 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, width); + using ExrBaseCompressor compressor = ExrCompressorFactory.Create(compression, this.memoryAllocator, stream, bytesPerBlock, bytesPerRow, rowsPerBlock, width); Rgba128 rgb = default; ulong[] rowOffsets = new ulong[height];