diff --git a/src/ImageSharp/Formats/Exr/Compression/Decompressors/Pxr24Compression.cs b/src/ImageSharp/Formats/Exr/Compression/Decompressors/Pxr24Compression.cs
index d720c190f9..d2fdcfcd16 100644
--- a/src/ImageSharp/Formats/Exr/Compression/Decompressors/Pxr24Compression.cs
+++ b/src/ImageSharp/Formats/Exr/Compression/Decompressors/Pxr24Compression.cs
@@ -5,6 +5,7 @@ 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;
@@ -21,6 +22,8 @@ internal class Pxr24Compression : ExrBaseDecompressor
private readonly int channelCount;
+ private readonly ExrPixelType pixelType;
+
///
/// Initializes a new instance of the class.
///
@@ -30,12 +33,14 @@ internal class Pxr24Compression : ExrBaseDecompressor
/// 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)
+ /// The pixel type.
+ public Pxr24Compression(MemoryAllocator allocator, uint bytesPerBlock, uint bytesPerRow, uint rowsPerBlock, int width, int channelCount, ExrPixelType pixelType)
: base(allocator, bytesPerBlock, bytesPerRow, width)
{
this.tmpBuffer = allocator.Allocate((int)bytesPerBlock);
this.rowsPerBlock = rowsPerBlock;
this.channelCount = channelCount;
+ this.pixelType = pixelType;
}
///
@@ -78,23 +83,94 @@ internal class Pxr24Compression : ExrBaseDecompressor
{
for (int c = 0; c < this.channelCount; c++)
{
- int offsetT1 = lastIn;
- lastIn += this.Width;
- int offsetT2 = lastIn;
- lastIn += this.Width;
- uint pixel = 0;
- for (int x = 0; x < this.Width; x++)
+ switch (this.pixelType)
{
- uint t1 = uncompressed[offsetT1];
- uint t2 = uncompressed[offsetT2];
- uint diff = (t1 << 8) | t2;
+ case ExrPixelType.UnsignedInt:
+ {
+ int offsetT0 = lastIn;
+ lastIn += this.Width;
+ int offsetT1 = lastIn;
+ lastIn += this.Width;
+ int offsetT2 = lastIn;
+ lastIn += this.Width;
+ int offsetT3 = lastIn;
+ lastIn += this.Width;
+
+ uint pixel = 0;
+ for (int x = 0; x < this.Width; x++)
+ {
+ uint t0 = uncompressed[offsetT0];
+ uint t1 = uncompressed[offsetT1];
+ uint t2 = uncompressed[offsetT2];
+ uint t3 = uncompressed[offsetT3];
+ uint diff = (t0 << 24) | (t1 << 16) | (t2 << 8) | t3;
+
+ pixel += diff;
+ outputBuffer[outputOffset] = (ushort)pixel;
+
+ offsetT0++;
+ offsetT1++;
+ offsetT2++;
+ offsetT3++;
+ outputOffset++;
+ }
+
+ break;
+ }
+
+ case ExrPixelType.Half:
+ {
+ int offsetT0 = lastIn;
+ lastIn += this.Width;
+ int offsetT1 = lastIn;
+ lastIn += this.Width;
+
+ uint pixel = 0;
+ for (int x = 0; x < this.Width; x++)
+ {
+ uint t0 = uncompressed[offsetT0];
+ uint t1 = uncompressed[offsetT1];
+ uint diff = (t0 << 8) | t1;
+
+ pixel += diff;
+ outputBuffer[outputOffset] = (ushort)pixel;
+
+ offsetT0++;
+ offsetT1++;
+ outputOffset++;
+ }
+
+ break;
+ }
+
+ case ExrPixelType.Float:
+ {
+ int offsetT0 = lastIn;
+ lastIn += this.Width;
+ int offsetT1 = lastIn;
+ lastIn += this.Width;
+ int offsetT2 = lastIn;
+ lastIn += this.Width;
+
+ uint pixel = 0;
+ for (int x = 0; x < this.Width; x++)
+ {
+ uint t0 = uncompressed[offsetT0];
+ uint t1 = uncompressed[offsetT1];
+ uint t2 = uncompressed[offsetT2];
+ uint diff = (t0 << 24) | (t1 << 16) | (t2 << 8);
+
+ pixel += diff;
+ outputBuffer[outputOffset] = (ushort)pixel;
- pixel += diff;
- outputBuffer[outputOffset] = (ushort)pixel;
+ offsetT0++;
+ offsetT1++;
+ offsetT2++;
+ outputOffset++;
+ }
- offsetT1++;
- offsetT2++;
- outputOffset++;
+ break;
+ }
}
}
}
diff --git a/src/ImageSharp/Formats/Exr/Compression/ExrDecompressorFactory.cs b/src/ImageSharp/Formats/Exr/Compression/ExrDecompressorFactory.cs
index 8123284585..6f63a932b7 100644
--- a/src/ImageSharp/Formats/Exr/Compression/ExrDecompressorFactory.cs
+++ b/src/ImageSharp/Formats/Exr/Compression/ExrDecompressorFactory.cs
@@ -30,14 +30,15 @@ internal static class ExrDecompressorFactory
uint bytesPerBlock,
uint bytesPerRow,
uint rowsPerBlock,
- int channelCount) => method switch
+ 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.B44 => new B44ExrCompression(memoryAllocator, bytesPerBlock, bytesPerRow, rowsPerBlock, width, channelCount),
- ExrCompression.Pxr24 => new Pxr24Compression(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/ExrDecoderCore.cs b/src/ImageSharp/Formats/Exr/ExrDecoderCore.cs
index ddfbcdc186..2e60f3a5b9 100644
--- a/src/ImageSharp/Formats/Exr/ExrDecoderCore.cs
+++ b/src/ImageSharp/Formats/Exr/ExrDecoderCore.cs
@@ -154,7 +154,15 @@ internal sealed class ExrDecoderCore : ImageDecoderCore
Span bluePixelData = rowBuffer.GetSpan().Slice(width * 2, width);
Span alphaPixelData = rowBuffer.GetSpan().Slice(width * 3, width);
- using ExrBaseDecompressor decompressor = ExrDecompressorFactory.Create(this.Compression, this.memoryAllocator, width, bytesPerBlock, bytesPerRow, rowsPerBlock, channelCount);
+ using ExrBaseDecompressor decompressor = ExrDecompressorFactory.Create(
+ this.Compression,
+ this.memoryAllocator,
+ width,
+ bytesPerBlock,
+ bytesPerRow,
+ rowsPerBlock,
+ channelCount,
+ this.PixelType);
int decodedRows = 0;
while (decodedRows < height)
@@ -219,7 +227,15 @@ internal sealed class ExrDecoderCore : ImageDecoderCore
Span bluePixelData = rowBuffer.GetSpan().Slice(width * 2, width);
Span alphaPixelData = rowBuffer.GetSpan().Slice(width * 3, width);
- using ExrBaseDecompressor decompressor = ExrDecompressorFactory.Create(this.Compression, this.memoryAllocator, width, bytesPerBlock, bytesPerRow, rowsPerBlock, channelCount);
+ using ExrBaseDecompressor decompressor = ExrDecompressorFactory.Create(
+ this.Compression,
+ this.memoryAllocator,
+ width,
+ bytesPerBlock,
+ bytesPerRow,
+ rowsPerBlock,
+ channelCount,
+ this.PixelType);
int decodedRows = 0;
while (decodedRows < height)