mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
7 changed files with 223 additions and 181 deletions
@ -0,0 +1,34 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
#if !NETCOREAPP2_1
|
|||
using System; |
|||
using System.Text; |
|||
|
|||
namespace SixLabors.ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Encoder"/> type.
|
|||
/// </summary>
|
|||
internal static unsafe class EncoderExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets a string from the provided buffer data.
|
|||
/// </summary>
|
|||
/// <param name="encoding">The encoding.</param>
|
|||
/// <param name="buffer">The buffer.</param>
|
|||
/// <returns>The string.</returns>
|
|||
public static string GetString(this Encoding encoding, ReadOnlySpan<byte> buffer) |
|||
{ |
|||
#if NETSTANDARD1_1
|
|||
return encoding.GetString(buffer.ToArray()); |
|||
#else
|
|||
fixed (byte* bytes = buffer) |
|||
{ |
|||
return encoding.GetString(bytes, buffer.Length); |
|||
} |
|||
#endif
|
|||
} |
|||
} |
|||
} |
|||
#endif
|
|||
@ -0,0 +1,107 @@ |
|||
using System; |
|||
using System.Buffers.Binary; |
|||
using SixLabors.ImageSharp.Common.Helpers; |
|||
using SixLabors.ImageSharp.MetaData; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Png.Chunks |
|||
{ |
|||
/// <summary>
|
|||
/// The pHYs chunk specifies the intended pixel size or aspect ratio for display of the image.
|
|||
/// </summary>
|
|||
internal readonly struct PhysicalChunkData |
|||
{ |
|||
public const int Size = 9; |
|||
|
|||
public PhysicalChunkData(uint x, uint y, byte unitSpecifier) |
|||
{ |
|||
this.XAxisPixelsPerUnit = x; |
|||
this.YAxisPixelsPerUnit = y; |
|||
this.UnitSpecifier = unitSpecifier; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of pixels per unit on the X axis.
|
|||
/// </summary>
|
|||
public uint XAxisPixelsPerUnit { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of pixels per unit on the Y axis.
|
|||
/// </summary>
|
|||
public uint YAxisPixelsPerUnit { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets 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.
|
|||
/// </summary>
|
|||
public byte UnitSpecifier { get; } |
|||
|
|||
/// <summary>
|
|||
/// Parses the PhysicalChunkData from the given buffer.
|
|||
/// </summary>
|
|||
/// <param name="data">The data buffer.</param>
|
|||
/// <returns>The parsed PhysicalChunkData.</returns>
|
|||
public static PhysicalChunkData Parse(ReadOnlySpan<byte> 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); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Constructs the PngPhysicalChunkData from the provided metadata.
|
|||
/// If the resolution units are not in meters, they are automatically convereted.
|
|||
/// </summary>
|
|||
/// <param name="meta">The metadata.</param>
|
|||
/// <returns>The constructed PngPhysicalChunkData instance.</returns>
|
|||
public static PhysicalChunkData FromMetadata(ImageMetaData meta) |
|||
{ |
|||
byte unitSpecifier = 0; |
|||
uint x; |
|||
uint y; |
|||
|
|||
switch (meta.ResolutionUnits) |
|||
{ |
|||
case PixelResolutionUnit.AspectRatio: |
|||
unitSpecifier = 0; // Unspecified
|
|||
x = (uint)Math.Round(meta.HorizontalResolution); |
|||
y = (uint)Math.Round(meta.VerticalResolution); |
|||
break; |
|||
|
|||
case PixelResolutionUnit.PixelsPerInch: |
|||
unitSpecifier = 1; // Per meter
|
|||
x = (uint)Math.Round(UnitConverter.InchToMeter(meta.HorizontalResolution)); |
|||
y = (uint)Math.Round(UnitConverter.InchToMeter(meta.VerticalResolution)); |
|||
break; |
|||
|
|||
case PixelResolutionUnit.PixelsPerCentimeter: |
|||
unitSpecifier = 1; // Per meter
|
|||
x = (uint)Math.Round(UnitConverter.CmToMeter(meta.HorizontalResolution)); |
|||
y = (uint)Math.Round(UnitConverter.CmToMeter(meta.VerticalResolution)); |
|||
break; |
|||
|
|||
default: |
|||
unitSpecifier = 1; // Per meter
|
|||
x = (uint)Math.Round(meta.HorizontalResolution); |
|||
y = (uint)Math.Round(meta.VerticalResolution); |
|||
break; |
|||
} |
|||
|
|||
return new PhysicalChunkData(x, y, unitSpecifier); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Writes the data to the given buffer.
|
|||
/// </summary>
|
|||
/// <param name="buffer">The buffer.</param>
|
|||
public void WriteTo(Span<byte> buffer) |
|||
{ |
|||
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(0, 4), this.XAxisPixelsPerUnit); |
|||
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(4, 4), this.YAxisPixelsPerUnit); |
|||
buffer[8] = this.UnitSpecifier; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue