// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Buffers.Binary;
using System.Text;
namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
{
///
/// Provides methods to read ICC data types
///
internal sealed partial class IccDataReader
{
///
/// Reads an ushort
///
/// the value
public ushort ReadUInt16()
{
return BinaryPrimitives.ReadUInt16BigEndian(this.data.AsSpan(this.AddIndex(2), 2));
}
///
/// Reads a short
///
/// the value
public short ReadInt16()
{
return BinaryPrimitives.ReadInt16BigEndian(this.data.AsSpan(this.AddIndex(2), 2));
}
///
/// Reads an uint
///
/// the value
public uint ReadUInt32()
{
return BinaryPrimitives.ReadUInt32BigEndian(this.data.AsSpan(this.AddIndex(4), 4));
}
///
/// Reads an int
///
/// the value
public int ReadInt32()
{
return BinaryPrimitives.ReadInt32BigEndian(this.data.AsSpan(this.AddIndex(4), 4));
}
///
/// Reads an ulong
///
/// the value
public ulong ReadUInt64()
{
return BinaryPrimitives.ReadUInt64BigEndian(this.data.AsSpan(this.AddIndex(8), 8));
}
///
/// Reads a long
///
/// the value
public long ReadInt64()
{
return BinaryPrimitives.ReadInt64BigEndian(this.data.AsSpan(this.AddIndex(8), 8));
}
///
/// Reads a float.
///
/// the value
public unsafe float ReadSingle()
{
int intValue = this.ReadInt32();
return *((float*)&intValue);
}
///
/// Reads a double
///
/// the value
public unsafe double ReadDouble()
{
long intValue = this.ReadInt64();
return *((double*)&intValue);
}
///
/// Reads an ASCII encoded string.
///
/// number of bytes to read
/// The value as a string
public string ReadAsciiString(int length)
{
if (length == 0)
{
return string.Empty;
}
Guard.MustBeGreaterThan(length, 0, nameof(length));
string value = AsciiEncoding.GetString(this.data, this.AddIndex(length), length);
// remove data after (potential) null terminator
int pos = value.IndexOf('\0');
if (pos >= 0)
{
value = value.Substring(0, pos);
}
return value;
}
///
/// Reads an UTF-16 big-endian encoded string.
///
/// number of bytes to read
/// The value as a string
public string ReadUnicodeString(int length)
{
if (length == 0)
{
return string.Empty;
}
Guard.MustBeGreaterThan(length, 0, nameof(length));
return Encoding.BigEndianUnicode.GetString(this.data, this.AddIndex(length), length);
}
///
/// Reads a signed 32bit number with 1 sign bit, 15 value bits and 16 fractional bits.
///
/// The number as double
public float ReadFix16() => this.ReadInt32() / 65536f;
///
/// Reads an unsigned 32bit number with 16 value bits and 16 fractional bits.
///
/// The number as double
public float ReadUFix16() => this.ReadUInt32() / 65536f;
///
/// Reads an unsigned 16bit number with 1 value bit and 15 fractional bits.
///
/// The number as double
public float ReadU1Fix15() => this.ReadUInt16() / 32768f;
///
/// Reads an unsigned 16bit number with 8 value bits and 8 fractional bits.
///
/// The number as double
public float ReadUFix8()
{
return this.ReadUInt16() / 256f;
}
///
/// Reads a number of bytes and advances the index.
///
/// The number of bytes to read
/// The read bytes
public byte[] ReadBytes(int count)
{
byte[] bytes = new byte[count];
Buffer.BlockCopy(this.data, this.AddIndex(count), bytes, 0, count);
return bytes;
}
}
}