diff --git a/src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs b/src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs
index c1c151611a..07fc688d50 100644
--- a/src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs
+++ b/src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs
@@ -37,6 +37,20 @@ namespace SixLabors.ImageSharp.Formats.Png.Chunks
///
public byte UnitSpecifier { get; }
+ ///
+ /// Parses the PhysicalChunkData from the given buffer.
+ ///
+ /// The data buffer.
+ /// The parsed PhysicalChunkData.
+ public static PhysicalChunkData Parse(ReadOnlySpan data)
+ {
+ uint hResolution = BinaryPrimitives.ReadUInt32BigEndian(data.Slice(0, 4));
+ uint vResolution = BinaryPrimitives.ReadUInt32BigEndian(data.Slice(4, 4));
+ byte unit = data[8];
+
+ return new PhysicalChunkData(hResolution, vResolution, unit);
+ }
+
///
/// Constructs the PngPhysicalChunkData from the provided metadata.
/// If the resolution units are not in meters, they are automatically convereted.
@@ -76,7 +90,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Chunks
break;
}
- return new PngPhysicalChunkData(x, y, unitSpecifier);
+ return new PhysicalChunkData(x, y, unitSpecifier);
}
///
diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index 8344d7b544..8401f4e98f 100644
--- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
@@ -8,6 +8,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Formats.Png.Chunks;
using SixLabors.ImageSharp.Formats.Png.Filters;
using SixLabors.ImageSharp.Formats.Png.Zlib;
using SixLabors.ImageSharp.Memory;
@@ -376,26 +377,14 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The data containing physical data.
private void ReadPhysicalChunk(ImageMetaData metadata, ReadOnlySpan data)
{
- // The pHYs chunk specifies the intended pixel size or aspect ratio for display of the image. It contains:
- // Pixels per unit, X axis: 4 bytes (unsigned integer)
- // Pixels per unit, Y axis: 4 bytes (unsigned integer)
- // Unit specifier: 1 byte
- //
- // The following values are legal for the unit specifier:
- // 0: unit is unknown
- // 1: unit is the meter
- //
- // When the unit specifier is 0, the pHYs chunk defines pixel aspect ratio only; the actual size of the pixels remains unspecified.
- int hResolution = BinaryPrimitives.ReadInt32BigEndian(data.Slice(0, 4));
- int vResolution = BinaryPrimitives.ReadInt32BigEndian(data.Slice(4, 4));
- byte unit = data[8];
-
- metadata.ResolutionUnits = unit == byte.MinValue
+ var physicalChunk = PhysicalChunkData.Parse(data);
+
+ metadata.ResolutionUnits = physicalChunk.UnitSpecifier == byte.MinValue
? PixelResolutionUnit.AspectRatio
: PixelResolutionUnit.PixelsPerMeter;
- metadata.HorizontalResolution = hResolution;
- metadata.VerticalResolution = vResolution;
+ metadata.HorizontalResolution = physicalChunk.XAxisPixelsPerUnit;
+ metadata.VerticalResolution = physicalChunk.YAxisPixelsPerUnit;
}
///
diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
index a86d8173cb..a46d83707e 100644
--- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
@@ -9,6 +9,7 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Formats.Png.Chunks;
using SixLabors.ImageSharp.Formats.Png.Filters;
using SixLabors.ImageSharp.Formats.Png.Zlib;
using SixLabors.ImageSharp.Memory;