From 0aeaaf77596cbf7a902524319bccbfc90b5f25ae Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Wed, 1 Apr 2026 12:46:01 +0200 Subject: [PATCH] Move ReadSingle() to ExrDecoderCore --- src/ImageSharp/Formats/Exr/ExrDecoderCore.cs | 47 ++++++++++++++++--- .../Pbm/BufferedReadStreamExtensions.cs | 1 - src/ImageSharp/IO/BufferedReadStream.cs | 25 ---------- 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/ImageSharp/Formats/Exr/ExrDecoderCore.cs b/src/ImageSharp/Formats/Exr/ExrDecoderCore.cs index d69cd78e2e..1cf0e27304 100644 --- a/src/ImageSharp/Formats/Exr/ExrDecoderCore.cs +++ b/src/ImageSharp/Formats/Exr/ExrDecoderCore.cs @@ -516,14 +516,14 @@ internal sealed class ExrDecoderCore : ImageDecoderCore lineOrder = (ExrLineOrder)stream.ReadByte(); break; case ExrConstants.AttributeNames.PixelAspectRatio: - aspectRatio = stream.ReadSingle(this.buffer); + aspectRatio = this.ReadSingle(stream); break; case ExrConstants.AttributeNames.ScreenWindowCenter: - screenWindowCenterX = stream.ReadSingle(this.buffer); - screenWindowCenterY = stream.ReadSingle(this.buffer); + screenWindowCenterX = this.ReadSingle(stream); + screenWindowCenterY = this.ReadSingle(stream); break; case ExrConstants.AttributeNames.ScreenWindowWidth: - screenWindowWidth = stream.ReadSingle(this.buffer); + screenWindowWidth = this.ReadSingle(stream); break; case ExrConstants.AttributeNames.Tiles: tileXSize = this.ReadUnsignedInteger(stream); @@ -738,39 +738,72 @@ internal sealed class ExrDecoderCore : ImageDecoderCore return false; } + /// + /// Reads a unsigned long value from the stream. + /// + /// The stream to read the data from. + /// The unsigned long value. private ulong ReadUnsignedLong(BufferedReadStream stream) { int bytesRead = stream.Read(this.buffer, 0, 8); if (bytesRead != 8) { - ExrThrowHelper.ThrowInvalidImageContentException("Could not read enough data from the stream!"); + ExrThrowHelper.ThrowInvalidImageContentException("Not enough data to read a unsigned long from the stream!"); } return BinaryPrimitives.ReadUInt64LittleEndian(this.buffer); } + /// + /// Reads a unsigned integer value from the stream. + /// + /// The stream to read the data from. + /// The integer value. private uint ReadUnsignedInteger(BufferedReadStream stream) { int bytesRead = stream.Read(this.buffer, 0, 4); if (bytesRead != 4) { - ExrThrowHelper.ThrowInvalidImageContentException("Could not read enough data from the stream!"); + ExrThrowHelper.ThrowInvalidImageContentException("Not enough data to read a unsigned int from the stream!"); } return BinaryPrimitives.ReadUInt32LittleEndian(this.buffer); } + /// + /// Reads a signed integer value from the stream. + /// + /// The stream to read the data from. + /// The integer value. private int ReadSignedInteger(BufferedReadStream stream) { int bytesRead = stream.Read(this.buffer, 0, 4); if (bytesRead != 4) { - ExrThrowHelper.ThrowInvalidImageContentException("Could not read enough data from the stream!"); + ExrThrowHelper.ThrowInvalidImageContentException("Not enough data to read a signed int from the stream!"); } return BinaryPrimitives.ReadInt32LittleEndian(this.buffer); } + /// + /// Reads a float value from the stream. + /// + /// The stream to read the data from. + /// The float value. + private float ReadSingle(BufferedReadStream stream) + { + int bytesRead = stream.Read(this.buffer, 0, 4); + if (bytesRead != 4) + { + ExrThrowHelper.ThrowInvalidImageContentException("Not enough data to read a float value from the stream!"); + } + + int intValue = BinaryPrimitives.ReadInt32BigEndian(this.buffer); + + return Unsafe.As(ref intValue); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TPixel ColorScaleTo32Bit(uint r, uint g, uint b, uint a) where TPixel : unmanaged, IPixel diff --git a/src/ImageSharp/Formats/Pbm/BufferedReadStreamExtensions.cs b/src/ImageSharp/Formats/Pbm/BufferedReadStreamExtensions.cs index 3d5dde437a..3b0e41a02d 100644 --- a/src/ImageSharp/Formats/Pbm/BufferedReadStreamExtensions.cs +++ b/src/ImageSharp/Formats/Pbm/BufferedReadStreamExtensions.cs @@ -2,7 +2,6 @@ // Licensed under the Six Labors Split License. using SixLabors.ImageSharp.IO; -using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Formats.Pbm; diff --git a/src/ImageSharp/IO/BufferedReadStream.cs b/src/ImageSharp/IO/BufferedReadStream.cs index 87a4d05bcd..0372f677fc 100644 --- a/src/ImageSharp/IO/BufferedReadStream.cs +++ b/src/ImageSharp/IO/BufferedReadStream.cs @@ -167,31 +167,6 @@ internal sealed class BufferedReadStream : Stream } } - /// - /// Reads a float value. - /// - /// The value. - public float ReadSingle(byte[] data) - { - int offset = 0; - int bytesToRead = 4; - while (bytesToRead > 0) - { - int bytesRead = this.Read(data, offset, bytesToRead); - if (bytesRead == 0) - { - throw new ImageFormatException("Not enough data to read a float value from the stream"); - } - - bytesToRead -= bytesRead; - offset += bytesRead; - } - - int intValue = BinaryPrimitives.ReadInt32BigEndian(data); - - return Unsafe.As(ref intValue); - } - /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int Read(byte[] buffer, int offset, int count)