mirror of https://github.com/SixLabors/ImageSharp
80 changed files with 9566 additions and 18 deletions
@ -0,0 +1,40 @@ |
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// A segment of a curve
|
|||
/// </summary>
|
|||
internal abstract class IccCurveSegment : IEquatable<IccCurveSegment> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccCurveSegment"/> class.
|
|||
/// </summary>
|
|||
/// <param name="signature">The signature of this segment</param>
|
|||
protected IccCurveSegment(IccCurveSegmentSignature signature) |
|||
{ |
|||
this.Signature = signature; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the signature of this segment
|
|||
/// </summary>
|
|||
public IccCurveSegmentSignature Signature { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public virtual bool Equals(IccCurveSegment other) |
|||
{ |
|||
if (other == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return this.Signature == other.Signature; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,84 @@ |
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// A formula based curve segment
|
|||
/// </summary>
|
|||
internal sealed class IccFormulaCurveElement : IccCurveSegment |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccFormulaCurveElement"/> class.
|
|||
/// </summary>
|
|||
/// <param name="type">The type of this segment (0-2)</param>
|
|||
/// <param name="gamma">Gamma segment parameter</param>
|
|||
/// <param name="a">A segment parameter</param>
|
|||
/// <param name="b">B segment parameter</param>
|
|||
/// <param name="c">C segment parameter</param>
|
|||
/// <param name="d">D segment parameter</param>
|
|||
/// <param name="e">E segment parameter</param>
|
|||
public IccFormulaCurveElement(ushort type, double gamma, double a, double b, double c, double d, double e) |
|||
: base(IccCurveSegmentSignature.FormulaCurve) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(type, 0, 2, nameof(type)); |
|||
|
|||
this.Type = type; |
|||
this.Gamma = gamma; |
|||
this.A = a; |
|||
this.B = b; |
|||
this.C = c; |
|||
this.D = d; |
|||
this.E = e; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the type of this curve
|
|||
/// </summary>
|
|||
public ushort Type { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the gamma curve parameter
|
|||
/// </summary>
|
|||
public double Gamma { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the A curve parameter
|
|||
/// </summary>
|
|||
public double A { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the B curve parameter
|
|||
/// </summary>
|
|||
public double B { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the C curve parameter
|
|||
/// </summary>
|
|||
public double C { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the D curve parameter
|
|||
/// </summary>
|
|||
public double D { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the E curve parameter
|
|||
/// </summary>
|
|||
public double E { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccCurveSegment other) |
|||
{ |
|||
if (base.Equals(other) && other is IccFormulaCurveElement segment) |
|||
{ |
|||
return this.Type == segment.Type |
|||
&& this.Gamma == segment.Gamma |
|||
&& this.A == segment.A |
|||
&& this.B == segment.B |
|||
&& this.C == segment.C |
|||
&& this.D == segment.D |
|||
&& this.E == segment.E; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// A one dimensional curve
|
|||
/// </summary>
|
|||
internal sealed class IccOneDimensionalCurve : IEquatable<IccOneDimensionalCurve> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccOneDimensionalCurve"/> class.
|
|||
/// </summary>
|
|||
/// <param name="breakPoints">The break points of this curve</param>
|
|||
/// <param name="segments">The segments of this curve</param>
|
|||
public IccOneDimensionalCurve(float[] breakPoints, IccCurveSegment[] segments) |
|||
{ |
|||
Guard.NotNull(breakPoints, nameof(breakPoints)); |
|||
Guard.NotNull(segments, nameof(segments)); |
|||
|
|||
bool isWrongSize = breakPoints.Length != segments.Length - 1; |
|||
Guard.IsTrue(isWrongSize, $"{nameof(breakPoints)},{nameof(segments)}", "Number of BreakPoints must be one less than number of Segments"); |
|||
|
|||
this.BreakPoints = breakPoints; |
|||
this.Segments = segments; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the breakpoints that separate two curve segments
|
|||
/// </summary>
|
|||
public float[] BreakPoints { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets an array of curve segments
|
|||
/// </summary>
|
|||
public IccCurveSegment[] Segments { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public bool Equals(IccOneDimensionalCurve other) |
|||
{ |
|||
if (other == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return this.BreakPoints.SequenceEqual(other.BreakPoints) |
|||
&& this.Segments.SequenceEqual(other.Segments); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,147 @@ |
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// A parametric curve
|
|||
/// </summary>
|
|||
internal sealed class IccParametricCurve : IEquatable<IccParametricCurve> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccParametricCurve"/> class.
|
|||
/// </summary>
|
|||
/// <param name="g">G curve parameter</param>
|
|||
public IccParametricCurve(double g) |
|||
: this(0, g, 0, 0, 0, 0, 0, 0) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccParametricCurve"/> class.
|
|||
/// </summary>
|
|||
/// <param name="g">G curve parameter</param>
|
|||
/// <param name="a">A curve parameter</param>
|
|||
/// <param name="b">B curve parameter</param>
|
|||
public IccParametricCurve(double g, double a, double b) |
|||
: this(1, g, a, b, 0, 0, 0, 0) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccParametricCurve"/> class.
|
|||
/// </summary>
|
|||
/// <param name="g">G curve parameter</param>
|
|||
/// <param name="a">A curve parameter</param>
|
|||
/// <param name="b">B curve parameter</param>
|
|||
/// <param name="c">C curve parameter</param>
|
|||
public IccParametricCurve(double g, double a, double b, double c) |
|||
: this(2, g, a, b, c, 0, 0, 0) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccParametricCurve"/> class.
|
|||
/// </summary>
|
|||
/// <param name="g">G curve parameter</param>
|
|||
/// <param name="a">A curve parameter</param>
|
|||
/// <param name="b">B curve parameter</param>
|
|||
/// <param name="c">C curve parameter</param>
|
|||
/// <param name="d">D curve parameter</param>
|
|||
public IccParametricCurve(double g, double a, double b, double c, double d) |
|||
: this(3, g, a, b, c, d, 0, 0) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccParametricCurve"/> class.
|
|||
/// </summary>
|
|||
/// <param name="g">G curve parameter</param>
|
|||
/// <param name="a">A curve parameter</param>
|
|||
/// <param name="b">B curve parameter</param>
|
|||
/// <param name="c">C curve parameter</param>
|
|||
/// <param name="d">D curve parameter</param>
|
|||
/// <param name="e">E curve parameter</param>
|
|||
/// <param name="f">F curve parameter</param>
|
|||
public IccParametricCurve(double g, double a, double b, double c, double d, double e, double f) |
|||
: this(4, g, a, b, c, d, e, f) |
|||
{ |
|||
} |
|||
|
|||
private IccParametricCurve(ushort type, double g, double a, double b, double c, double d, double e, double f) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(type, 0, 4, nameof(type)); |
|||
|
|||
this.Type = type; |
|||
this.G = g; |
|||
this.A = a; |
|||
this.B = b; |
|||
this.C = c; |
|||
this.D = d; |
|||
this.E = e; |
|||
this.F = f; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the type of this curve
|
|||
/// </summary>
|
|||
public ushort Type { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the G curve parameter
|
|||
/// </summary>
|
|||
public double G { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the A curve parameter
|
|||
/// </summary>
|
|||
public double A { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the B curve parameter
|
|||
/// </summary>
|
|||
public double B { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the C curve parameter
|
|||
/// </summary>
|
|||
public double C { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the D curve parameter
|
|||
/// </summary>
|
|||
public double D { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the E curve parameter
|
|||
/// </summary>
|
|||
public double E { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the F curve parameter
|
|||
/// </summary>
|
|||
public double F { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(IccParametricCurve other) |
|||
{ |
|||
if (other == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return this.Type == other.Type |
|||
&& this.G == other.G |
|||
&& this.A == other.A |
|||
&& this.B == other.B |
|||
&& this.C == other.C |
|||
&& this.D == other.D |
|||
&& this.E == other.E |
|||
&& this.F == other.F; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,82 @@ |
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// A response curve
|
|||
/// </summary>
|
|||
internal sealed class IccResponseCurve : IEquatable<IccResponseCurve> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccResponseCurve"/> class.
|
|||
/// </summary>
|
|||
/// <param name="curveType">The type of this curve</param>
|
|||
/// <param name="xyzValues">The XYZ values</param>
|
|||
/// <param name="responseArrays">The response arrays</param>
|
|||
public IccResponseCurve(IccCurveMeasurementEncodings curveType, Vector3[] xyzValues, IccResponseNumber[][] responseArrays) |
|||
{ |
|||
Guard.NotNull(xyzValues, nameof(xyzValues)); |
|||
Guard.NotNull(responseArrays, nameof(responseArrays)); |
|||
|
|||
Guard.IsTrue(xyzValues.Length != responseArrays.Length, $"{nameof(xyzValues)},{nameof(responseArrays)}", "Arrays must have same length"); |
|||
Guard.MustBeBetweenOrEqualTo(xyzValues.Length, 1, 15, nameof(xyzValues)); |
|||
|
|||
this.CurveType = curveType; |
|||
this.XyzValues = xyzValues; |
|||
this.ResponseArrays = responseArrays; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the type of this curve
|
|||
/// </summary>
|
|||
public IccCurveMeasurementEncodings CurveType { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the XYZ values
|
|||
/// </summary>
|
|||
public Vector3[] XyzValues { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the response arrays
|
|||
/// </summary>
|
|||
public IccResponseNumber[][] ResponseArrays { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(IccResponseCurve other) |
|||
{ |
|||
if (other == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return this.CurveType == other.CurveType |
|||
&& this.XyzValues.SequenceEqual(other.XyzValues) |
|||
&& this.EqualsResponseArray(other); |
|||
} |
|||
|
|||
private bool EqualsResponseArray(IccResponseCurve other) |
|||
{ |
|||
if (this.ResponseArrays.Length != other.ResponseArrays.Length) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
for (int i = 0; i < this.ResponseArrays.Length; i++) |
|||
{ |
|||
if (!this.ResponseArrays[i].SequenceEqual(other.ResponseArrays[i])) |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// A sampled curve segment
|
|||
/// </summary>
|
|||
internal sealed class IccSampledCurveElement : IccCurveSegment |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccSampledCurveElement"/> class.
|
|||
/// </summary>
|
|||
/// <param name="curveEntries">The curve values of this segment</param>
|
|||
public IccSampledCurveElement(float[] curveEntries) |
|||
: base(IccCurveSegmentSignature.SampledCurve) |
|||
{ |
|||
Guard.NotNull(curveEntries, nameof(curveEntries)); |
|||
Guard.IsTrue(curveEntries.Length < 1, nameof(curveEntries), "There must be at least one value"); |
|||
|
|||
this.CurveEntries = curveEntries; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the curve values of this segment
|
|||
/// </summary>
|
|||
public float[] CurveEntries { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccCurveSegment other) |
|||
{ |
|||
if (base.Equals(other) && other is IccSampledCurveElement segment) |
|||
{ |
|||
return this.CurveEntries.SequenceEqual(segment.CurveEntries); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
// <copyright file="IccClutDataType.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Color lookup table data type
|
|||
/// </summary>
|
|||
internal enum IccClutDataType |
|||
{ |
|||
/// <summary>
|
|||
/// 32bit floating point
|
|||
/// </summary>
|
|||
Float, |
|||
|
|||
/// <summary>
|
|||
/// 8bit unsigned integer (byte)
|
|||
/// </summary>
|
|||
UInt8, |
|||
|
|||
/// <summary>
|
|||
/// 16bit unsigned integer (ushort)
|
|||
/// </summary>
|
|||
UInt16, |
|||
} |
|||
} |
|||
@ -0,0 +1,138 @@ |
|||
// <copyright file="IccColorSpaceType.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Color Space Type
|
|||
/// </summary>
|
|||
internal enum IccColorSpaceType : uint |
|||
{ |
|||
/// <summary>
|
|||
/// CIE XYZ
|
|||
/// </summary>
|
|||
CieXyz = 0x58595A20, // XYZ
|
|||
|
|||
/// <summary>
|
|||
/// CIE Lab
|
|||
/// </summary>
|
|||
CieLab = 0x4C616220, // Lab
|
|||
|
|||
/// <summary>
|
|||
/// CIE Luv
|
|||
/// </summary>
|
|||
CieLuv = 0x4C757620, // Luv
|
|||
|
|||
/// <summary>
|
|||
/// YCbCr
|
|||
/// </summary>
|
|||
YCbCr = 0x59436272, // YCbr
|
|||
|
|||
/// <summary>
|
|||
/// CIE Yxy
|
|||
/// </summary>
|
|||
CieYxy = 0x59787920, // Yxy
|
|||
|
|||
/// <summary>
|
|||
/// RGB
|
|||
/// </summary>
|
|||
Rgb = 0x52474220, // RGB
|
|||
|
|||
/// <summary>
|
|||
/// Gray
|
|||
/// </summary>
|
|||
Gray = 0x47524159, // GRAY
|
|||
|
|||
/// <summary>
|
|||
/// HSV
|
|||
/// </summary>
|
|||
Hsv = 0x48535620, // HSV
|
|||
|
|||
/// <summary>
|
|||
/// HLS
|
|||
/// </summary>
|
|||
Hls = 0x484C5320, // HLS
|
|||
|
|||
/// <summary>
|
|||
/// CMYK
|
|||
/// </summary>
|
|||
Cmyk = 0x434D594B, // CMYK
|
|||
|
|||
/// <summary>
|
|||
/// CMY
|
|||
/// </summary>
|
|||
Cmy = 0x434D5920, // CMY
|
|||
|
|||
/// <summary>
|
|||
/// Generic 2 channel color
|
|||
/// </summary>
|
|||
Color2 = 0x32434C52, // 2CLR
|
|||
|
|||
/// <summary>
|
|||
/// Generic 3 channel color
|
|||
/// </summary>
|
|||
Color3 = 0x33434C52, // 3CLR
|
|||
|
|||
/// <summary>
|
|||
/// Generic 4 channel color
|
|||
/// </summary>
|
|||
Color4 = 0x34434C52, // 4CLR
|
|||
|
|||
/// <summary>
|
|||
/// Generic 5 channel color
|
|||
/// </summary>
|
|||
Color5 = 0x35434C52, // 5CLR
|
|||
|
|||
/// <summary>
|
|||
/// Generic 6 channel color
|
|||
/// </summary>
|
|||
Color6 = 0x36434C52, // 6CLR
|
|||
|
|||
/// <summary>
|
|||
/// Generic 7 channel color
|
|||
/// </summary>
|
|||
Color7 = 0x37434C52, // 7CLR
|
|||
|
|||
/// <summary>
|
|||
/// Generic 8 channel color
|
|||
/// </summary>
|
|||
Color8 = 0x38434C52, // 8CLR
|
|||
|
|||
/// <summary>
|
|||
/// Generic 9 channel color
|
|||
/// </summary>
|
|||
Color9 = 0x39434C52, // 9CLR
|
|||
|
|||
/// <summary>
|
|||
/// Generic 10 channel color
|
|||
/// </summary>
|
|||
Color10 = 0x41434C52, // ACLR
|
|||
|
|||
/// <summary>
|
|||
/// Generic 11 channel color
|
|||
/// </summary>
|
|||
Color11 = 0x42434C52, // BCLR
|
|||
|
|||
/// <summary>
|
|||
/// Generic 12 channel color
|
|||
/// </summary>
|
|||
Color12 = 0x43434C52, // CCLR
|
|||
|
|||
/// <summary>
|
|||
/// Generic 13 channel color
|
|||
/// </summary>
|
|||
Color13 = 0x44434C52, // DCLR
|
|||
|
|||
/// <summary>
|
|||
/// Generic 14 channel color
|
|||
/// </summary>
|
|||
Color14 = 0x45434C52, // ECLR
|
|||
|
|||
/// <summary>
|
|||
/// Generic 15 channel color
|
|||
/// </summary>
|
|||
Color15 = 0x46434C52, // FCLR
|
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
// <copyright file="IccColorantEncoding.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Colorant Encoding
|
|||
/// </summary>
|
|||
internal enum IccColorantEncoding : ushort |
|||
{ |
|||
/// <summary>
|
|||
/// Unknown colorant encoding
|
|||
/// </summary>
|
|||
Unknown = 0x0000, |
|||
|
|||
/// <summary>
|
|||
/// ITU-R BT.709-2 colorant encoding
|
|||
/// </summary>
|
|||
ITU_R_BT_709_2 = 0x0001, |
|||
|
|||
/// <summary>
|
|||
/// SMPTE RP145 colorant encoding
|
|||
/// </summary>
|
|||
SMPTE_RP145 = 0x0002, |
|||
|
|||
/// <summary>
|
|||
/// EBU Tech.3213-E colorant encoding
|
|||
/// </summary>
|
|||
EBU_Tech_3213_E = 0x0003, |
|||
|
|||
/// <summary>
|
|||
/// P22 colorant encoding
|
|||
/// </summary>
|
|||
P22 = 0x0004, |
|||
} |
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
// <copyright file="IccCurveMeasurementEncodings.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Curve Measurement Encodings
|
|||
/// </summary>
|
|||
internal enum IccCurveMeasurementEncodings : uint |
|||
{ |
|||
/// <summary>
|
|||
/// ISO 5-3 densitometer response. This is the accepted standard for
|
|||
/// reflection densitometers for measuring photographic color prints
|
|||
/// </summary>
|
|||
StatusA = 0x53746141, // StaA
|
|||
|
|||
/// <summary>
|
|||
/// ISO 5-3 densitometer response which is the accepted standard in
|
|||
/// Europe for color reflection densitometers
|
|||
/// </summary>
|
|||
StatusE = 0x53746145, // StaE
|
|||
|
|||
/// <summary>
|
|||
/// ISO 5-3 densitometer response commonly referred to as narrow band
|
|||
/// or interference-type response.
|
|||
/// </summary>
|
|||
StatusI = 0x53746149, // StaI
|
|||
|
|||
/// <summary>
|
|||
/// ISO 5-3 wide band color reflection densitometer response which is
|
|||
/// the accepted standard in the United States for color reflection densitometers
|
|||
/// </summary>
|
|||
StatusT = 0x53746154, // StaT
|
|||
|
|||
/// <summary>
|
|||
/// ISO 5-3 densitometer response for measuring color negatives
|
|||
/// </summary>
|
|||
StatusM = 0x5374614D, // StaM
|
|||
|
|||
/// <summary>
|
|||
/// DIN 16536-2 densitometer response, with no polarizing filter
|
|||
/// </summary>
|
|||
DinE = 0x434E2020, // DN
|
|||
|
|||
/// <summary>
|
|||
/// DIN 16536-2 densitometer response, with polarizing filter
|
|||
/// </summary>
|
|||
DinE_pol = 0x434E2050, // DNP
|
|||
|
|||
/// <summary>
|
|||
/// DIN 16536-2 narrow band densitometer response, with no polarizing filter
|
|||
/// </summary>
|
|||
DinI = 0x434E4E20, // DNN
|
|||
|
|||
/// <summary>
|
|||
/// DIN 16536-2 narrow band densitometer response, with polarizing filter
|
|||
/// </summary>
|
|||
DinI_pol = 0x434E4E50, // DNNP
|
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
// <copyright file="IccCurveSegmentSignature.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Curve Segment Signature
|
|||
/// </summary>
|
|||
internal enum IccCurveSegmentSignature : uint |
|||
{ |
|||
/// <summary>
|
|||
/// Curve defined by a formula
|
|||
/// </summary>
|
|||
FormulaCurve = 0x70617266, // parf
|
|||
|
|||
/// <summary>
|
|||
/// Curve defined by multiple segments
|
|||
/// </summary>
|
|||
SampledCurve = 0x73616D66, // samf
|
|||
} |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
// <copyright file="IccDeviceAttribute.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// Device attributes. Can be combined with a logical OR
|
|||
/// </summary>
|
|||
[Flags] |
|||
internal enum IccDeviceAttribute : long |
|||
{ |
|||
/// <summary>
|
|||
/// Opacity transparent
|
|||
/// </summary>
|
|||
OpacityTransparent = 1 << 31, |
|||
|
|||
/// <summary>
|
|||
/// Opacity reflective
|
|||
/// </summary>
|
|||
OpacityReflective = 0, |
|||
|
|||
/// <summary>
|
|||
/// Reflectivity matte
|
|||
/// </summary>
|
|||
ReflectivityMatte = 1 << 30, |
|||
|
|||
/// <summary>
|
|||
/// Reflectivity glossy
|
|||
/// </summary>
|
|||
ReflectivityGlossy = 0, |
|||
|
|||
/// <summary>
|
|||
/// Polarity negative
|
|||
/// </summary>
|
|||
PolarityNegative = 1 << 29, |
|||
|
|||
/// <summary>
|
|||
/// Polarity positive
|
|||
/// </summary>
|
|||
PolarityPositive = 0, |
|||
|
|||
/// <summary>
|
|||
/// Chroma black and white
|
|||
/// </summary>
|
|||
ChromaBlackWhite = 1 << 28, |
|||
|
|||
/// <summary>
|
|||
/// Chroma color
|
|||
/// </summary>
|
|||
ChromaColor = 0, |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
// <copyright file="IccMeasurementGeometry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Measurement Geometry
|
|||
/// </summary>
|
|||
internal enum IccMeasurementGeometry : uint |
|||
{ |
|||
/// <summary>
|
|||
/// Unknown geometry
|
|||
/// </summary>
|
|||
Unknown = 0, |
|||
|
|||
/// <summary>
|
|||
/// Geometry of 0°:45° or 45°:0°
|
|||
/// </summary>
|
|||
MG_0_45_45_0 = 1, |
|||
|
|||
/// <summary>
|
|||
/// Geometry of 0°:d or d:0°
|
|||
/// </summary>
|
|||
MG_0d_d0 = 2, |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
// <copyright file="IccMultiProcessElementSignature.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Multi process element signature
|
|||
/// </summary>
|
|||
internal enum IccMultiProcessElementSignature : uint |
|||
{ |
|||
/// <summary>
|
|||
/// Set of curves
|
|||
/// </summary>
|
|||
CurveSet = 0x6D666C74, // cvst
|
|||
|
|||
/// <summary>
|
|||
/// Matrix transformation
|
|||
/// </summary>
|
|||
Matrix = 0x6D617466, // matf
|
|||
|
|||
/// <summary>
|
|||
/// Color lookup table
|
|||
/// </summary>
|
|||
Clut = 0x636C7574, // clut
|
|||
|
|||
/// <summary>
|
|||
/// Reserved for future expansion. Do not use!
|
|||
/// </summary>
|
|||
BAcs = 0x62414353, // bACS
|
|||
|
|||
/// <summary>
|
|||
/// Reserved for future expansion. Do not use!
|
|||
/// </summary>
|
|||
EAcs = 0x65414353, // eACS
|
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
// <copyright file="IccPrimaryPlatformType.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Enumerates the primary platform/operating system framework for which the profile was created
|
|||
/// </summary>
|
|||
internal enum IccPrimaryPlatformType : uint |
|||
{ |
|||
/// <summary>
|
|||
/// No platform identified
|
|||
/// </summary>
|
|||
NotIdentified = 0x00000000, |
|||
|
|||
/// <summary>
|
|||
/// Apple Computer, Inc.
|
|||
/// </summary>
|
|||
AppleComputerInc = 0x4150504C, // APPL
|
|||
|
|||
/// <summary>
|
|||
/// Microsoft Corporation
|
|||
/// </summary>
|
|||
MicrosoftCorporation = 0x4D534654, // MSFT
|
|||
|
|||
/// <summary>
|
|||
/// Silicon Graphics, Inc.
|
|||
/// </summary>
|
|||
SiliconGraphicsInc = 0x53474920, // SGI
|
|||
|
|||
/// <summary>
|
|||
/// Sun Microsystems, Inc.
|
|||
/// </summary>
|
|||
SunMicrosystemsInc = 0x53554E57, // SUNW
|
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
// <copyright file="IccProfileClass.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Profile Class Name
|
|||
/// </summary>
|
|||
internal enum IccProfileClass : uint |
|||
{ |
|||
InputDevice = 0x73636E72, // scnr
|
|||
DisplayDevice = 0x6D6E7472, // mntr
|
|||
OutputDevice = 0x70727472, // prtr
|
|||
DeviceLink = 0x6C696E6B, // link
|
|||
ColorSpace = 0x73706163, // spac
|
|||
Abstract = 0x61627374, // abst
|
|||
NamedColor = 0x6E6D636C, // nmcl
|
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// <copyright file="IccProfileConversionMethod.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Profile Conversion Method
|
|||
/// </summary>
|
|||
internal enum IccProfileConversionMethod |
|||
{ |
|||
Invalid, |
|||
D0, |
|||
D1, |
|||
D2, |
|||
D3, |
|||
A0, |
|||
A1, |
|||
A2, |
|||
ColorTRC, |
|||
GrayTRC, |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
// <copyright file="IccProfileFlag.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// Profile flags. Can be combined with a logical OR
|
|||
/// </summary>
|
|||
[Flags] |
|||
internal enum IccProfileFlag : int |
|||
{ |
|||
/// <summary>
|
|||
/// Profile is embedded within another file
|
|||
/// </summary>
|
|||
Embedded = 1 << 31, |
|||
|
|||
/// <summary>
|
|||
/// Profile cannot be used independently of the embedded colour data
|
|||
/// </summary>
|
|||
Independent = 1 << 30, |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
// <copyright file="IccRenderingIntent.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Rendering intent
|
|||
/// </summary>
|
|||
internal enum IccRenderingIntent : uint |
|||
{ |
|||
Perceptual = 0, |
|||
MediaRelativeColorimetric = 1, |
|||
Saturation = 2, |
|||
AbsoluteColorimetric = 3, |
|||
} |
|||
} |
|||
@ -0,0 +1,82 @@ |
|||
// <copyright file="IccSignatureName.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Signature Name
|
|||
/// </summary>
|
|||
internal enum IccSignatureName : uint |
|||
{ |
|||
/// <summary>
|
|||
/// Unknown signature
|
|||
/// </summary>
|
|||
Unknown = 0, |
|||
|
|||
SceneColorimetryEstimates = 0x73636F65, // scoe
|
|||
|
|||
SceneAppearanceEstimates = 0x73617065, // sape
|
|||
|
|||
FocalPlaneColorimetryEstimates = 0x66706365, // fpce
|
|||
|
|||
ReflectionHardcopyOriginalColorimetry = 0x72686F63, // rhoc
|
|||
|
|||
ReflectionPrintOutputColorimetry = 0x72706F63, // rpoc
|
|||
|
|||
PerceptualReferenceMediumGamut = 0x70726D67, // prmg
|
|||
|
|||
FilmScanner = 0x6673636E, // fscn
|
|||
|
|||
DigitalCamera = 0x6463616D, // dcam
|
|||
|
|||
ReflectiveScanner = 0x7273636E, // rscn
|
|||
|
|||
InkJetPrinter = 0x696A6574, // ijet
|
|||
|
|||
ThermalWaxPrinter = 0x74776178, // twax
|
|||
|
|||
ElectrophotographicPrinter = 0x6570686F, // epho
|
|||
|
|||
ElectrostaticPrinter = 0x65737461, // esta
|
|||
|
|||
DyeSublimationPrinter = 0x64737562, // dsub
|
|||
|
|||
PhotographicPaperPrinter = 0x7270686F, // rpho
|
|||
|
|||
FilmWriter = 0x6670726E, // fprn
|
|||
|
|||
VideoMonitor = 0x7669646D, // vidm
|
|||
|
|||
VideoCamera = 0x76696463, // vidc
|
|||
|
|||
ProjectionTelevision = 0x706A7476, // pjtv
|
|||
|
|||
CathodeRayTubeDisplay = 0x43525420, // CRT
|
|||
|
|||
PassiveMatrixDisplay = 0x504D4420, // PMD
|
|||
|
|||
ActiveMatrixDisplay = 0x414D4420, // AMD
|
|||
|
|||
PhotoCD = 0x4B504344, // KPCD
|
|||
|
|||
PhotographicImageSetter = 0x696D6773, // imgs
|
|||
|
|||
Gravure = 0x67726176, // grav
|
|||
|
|||
OffsetLithography = 0x6F666673, // offs
|
|||
|
|||
Silkscreen = 0x73696C6B, // silk
|
|||
|
|||
Flexography = 0x666C6578, // flex
|
|||
|
|||
MotionPictureFilmScanner = 0x6D706673, // mpfs
|
|||
|
|||
MotionPictureFilmRecorder = 0x6D706672, // mpfr
|
|||
|
|||
DigitalMotionPictureCamera = 0x646D7063, // dmpc
|
|||
|
|||
DigitalCinemaProjector = 0x64636A70, // dcpj
|
|||
} |
|||
} |
|||
@ -0,0 +1,58 @@ |
|||
// <copyright file="IccStandardIlluminant.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Standard Illuminant
|
|||
/// </summary>
|
|||
internal enum IccStandardIlluminant : uint |
|||
{ |
|||
/// <summary>
|
|||
/// Unknown illuminant
|
|||
/// </summary>
|
|||
Unknown = 0, |
|||
|
|||
/// <summary>
|
|||
/// D50 illuminant
|
|||
/// </summary>
|
|||
D50 = 1, |
|||
|
|||
/// <summary>
|
|||
/// D65 illuminant
|
|||
/// </summary>
|
|||
D65 = 2, |
|||
|
|||
/// <summary>
|
|||
/// D93 illuminant
|
|||
/// </summary>
|
|||
D93 = 3, |
|||
|
|||
/// <summary>
|
|||
/// F2 illuminant
|
|||
/// </summary>
|
|||
F2 = 4, |
|||
|
|||
/// <summary>
|
|||
/// D55 illuminant
|
|||
/// </summary>
|
|||
D55 = 5, |
|||
|
|||
/// <summary>
|
|||
/// A illuminant
|
|||
/// </summary>
|
|||
A = 6, |
|||
|
|||
/// <summary>
|
|||
/// D50 illuminant
|
|||
/// </summary>
|
|||
EquiPowerE = 7, |
|||
|
|||
/// <summary>
|
|||
/// F8 illuminant
|
|||
/// </summary>
|
|||
F8 = 8, |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
// <copyright file="IccStandardObserver.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Standard Observer
|
|||
/// </summary>
|
|||
internal enum IccStandardObserver : uint |
|||
{ |
|||
/// <summary>
|
|||
/// Unknown observer
|
|||
/// </summary>
|
|||
Unkown = 0, |
|||
|
|||
/// <summary>
|
|||
/// CIE 1931 observer
|
|||
/// </summary>
|
|||
CIE1931Observer = 1, |
|||
|
|||
/// <summary>
|
|||
/// CIE 1964 observer
|
|||
/// </summary>
|
|||
CIE1964Observer = 2, |
|||
} |
|||
} |
|||
@ -0,0 +1,112 @@ |
|||
// <copyright file="IccTypeSignature.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Type Signature
|
|||
/// </summary>
|
|||
internal enum IccTypeSignature : uint |
|||
{ |
|||
/// <summary>
|
|||
/// Unknown type signature
|
|||
/// </summary>
|
|||
Unknown, |
|||
|
|||
Chromaticity = 0x6368726D, |
|||
|
|||
ColorantOrder = 0x636c726f, |
|||
|
|||
ColorantTable = 0x636c7274, |
|||
|
|||
Curve = 0x63757276, |
|||
|
|||
Data = 0x64617461, |
|||
|
|||
/// <summary>
|
|||
/// Date and time defined by 6 unsigned 16bit integers (year, month, day, hour, minute, second)
|
|||
/// </summary>
|
|||
DateTime = 0x6474696D, |
|||
|
|||
/// <summary>
|
|||
/// Lookup table with 16bit unsigned integers (ushort)
|
|||
/// </summary>
|
|||
Lut16 = 0x6D667432, |
|||
|
|||
/// <summary>
|
|||
/// Lookup table with 8bit unsigned integers (byte)
|
|||
/// </summary>
|
|||
Lut8 = 0x6D667431, |
|||
|
|||
LutAToB = 0x6D414220, |
|||
|
|||
LutBToA = 0x6D424120, |
|||
|
|||
Measurement = 0x6D656173, |
|||
|
|||
/// <summary>
|
|||
/// Unicode text in one or more languages
|
|||
/// </summary>
|
|||
MultiLocalizedUnicode = 0x6D6C7563, |
|||
|
|||
MultiProcessElements = 0x6D706574, |
|||
|
|||
NamedColor2 = 0x6E636C32, |
|||
|
|||
ParametricCurve = 0x70617261, |
|||
|
|||
ProfileSequenceDesc = 0x70736571, |
|||
|
|||
ProfileSequenceIdentifier = 0x70736964, |
|||
|
|||
ResponseCurveSet16 = 0x72637332, |
|||
|
|||
/// <summary>
|
|||
/// Array of signed floating point numbers with 1 sign bit, 15 value bits and 16 fractional bits
|
|||
/// </summary>
|
|||
S15Fixed16Array = 0x73663332, |
|||
|
|||
Signature = 0x73696720, |
|||
|
|||
/// <summary>
|
|||
/// Simple ASCII text
|
|||
/// </summary>
|
|||
Text = 0x74657874, |
|||
|
|||
/// <summary>
|
|||
/// Array of unsigned floating point numbers with 16 value bits and 16 fractional bits
|
|||
/// </summary>
|
|||
U16Fixed16Array = 0x75663332, |
|||
|
|||
/// <summary>
|
|||
/// Array of unsigned 16bit integers (ushort)
|
|||
/// </summary>
|
|||
UInt16Array = 0x75693136, |
|||
|
|||
/// <summary>
|
|||
/// Array of unsigned 32bit integers (uint)
|
|||
/// </summary>
|
|||
UInt32Array = 0x75693332, |
|||
|
|||
/// <summary>
|
|||
/// Array of unsigned 64bit integers (ulong)
|
|||
/// </summary>
|
|||
UInt64Array = 0x75693634, |
|||
|
|||
/// <summary>
|
|||
/// Array of unsigned 8bit integers (byte)
|
|||
/// </summary>
|
|||
UInt8Array = 0x75693038, |
|||
|
|||
ViewingConditions = 0x76696577, |
|||
|
|||
/// <summary>
|
|||
/// 3 floating point values describing a XYZ color value
|
|||
/// </summary>
|
|||
Xyz = 0x58595A20, |
|||
|
|||
TextDescription = 0x64657363, |
|||
} |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
// <copyright file="InvalidIccProfileException.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// Represents an error that happened while reading or writing a corrupt/invalid ICC profile
|
|||
/// </summary>
|
|||
public class InvalidIccProfileException : Exception |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="InvalidIccProfileException"/> class.
|
|||
/// </summary>
|
|||
public InvalidIccProfileException() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="InvalidIccProfileException"/> class.
|
|||
/// </summary>
|
|||
/// <param name="message">The message that describes the error</param>
|
|||
public InvalidIccProfileException(string message) |
|||
: base(message) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="InvalidIccProfileException"/> class.
|
|||
/// </summary>
|
|||
/// <param name="message">The message that describes the error</param>
|
|||
/// <param name="inner">The exception that is the cause of the current exception, or a null reference
|
|||
/// (Nothing in Visual Basic) if no inner exception is specified</param>
|
|||
public InvalidIccProfileException(string message, Exception inner) |
|||
: base(message, inner) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,107 @@ |
|||
// <copyright file="IccProfile.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Collections.Generic; |
|||
#if !NETSTANDARD1_1
|
|||
using System; |
|||
using System.Security.Cryptography; |
|||
#endif
|
|||
|
|||
/// <summary>
|
|||
/// Represents an ICC profile
|
|||
/// </summary>
|
|||
internal class IccProfile |
|||
{ |
|||
/// <summary>
|
|||
/// The byte array to read the ICC profile from
|
|||
/// </summary>
|
|||
private readonly byte[] data; |
|||
|
|||
/// <summary>
|
|||
/// The backing file for the <see cref="Entries"/> property
|
|||
/// </summary>
|
|||
private readonly List<IccTagDataEntry> entries; |
|||
|
|||
/// <summary>
|
|||
/// ICC profile header
|
|||
/// </summary>
|
|||
private readonly IccProfileHeader header; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccProfile"/> class.
|
|||
/// </summary>
|
|||
public IccProfile() |
|||
{ |
|||
this.data = null; |
|||
this.entries = new List<IccTagDataEntry>(); |
|||
this.header = new IccProfileHeader(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccProfile"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The raw ICC profile data</param>
|
|||
public IccProfile(byte[] data) |
|||
{ |
|||
Guard.NotNull(data, nameof(data)); |
|||
|
|||
this.data = data; |
|||
IccReader reader = new IccReader(); |
|||
this.header = reader.ReadHeader(data); |
|||
this.entries = new List<IccTagDataEntry>(reader.ReadTagData(data)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the profile header
|
|||
/// </summary>
|
|||
public IccProfileHeader Header |
|||
{ |
|||
get { return this.header; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the actual profile data
|
|||
/// </summary>
|
|||
public List<IccTagDataEntry> Entries |
|||
{ |
|||
get { return this.entries; } |
|||
} |
|||
|
|||
#if !NETSTANDARD1_1
|
|||
|
|||
/// <summary>
|
|||
/// Calculates the MD5 hash value of an ICC profile header
|
|||
/// </summary>
|
|||
/// <param name="data">The data of which to calculate the hash value</param>
|
|||
/// <returns>The calculated hash</returns>
|
|||
public static IccProfileId CalculateHash(byte[] data) |
|||
{ |
|||
Guard.NotNull(data, nameof(data)); |
|||
Guard.IsTrue(data.Length < 128, nameof(data), "Data length must be at least 128 to be a valid profile header"); |
|||
|
|||
byte[] header = new byte[128]; |
|||
Buffer.BlockCopy(data, 0, header, 0, 128); |
|||
|
|||
using (MD5 md5 = MD5.Create()) |
|||
{ |
|||
// Zero out some values
|
|||
Array.Clear(header, 44, 4); // Profile flags
|
|||
Array.Clear(header, 64, 4); // Rendering Intent
|
|||
Array.Clear(header, 84, 16); // Profile ID
|
|||
|
|||
// Calculate hash
|
|||
byte[] hash = md5.ComputeHash(data); |
|||
|
|||
// Read values from hash
|
|||
IccDataReader reader = new IccDataReader(hash); |
|||
return reader.ReadProfileId(); |
|||
} |
|||
} |
|||
|
|||
#endif
|
|||
} |
|||
} |
|||
@ -0,0 +1,103 @@ |
|||
// <copyright file="IccProfileHeader.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// Contains all values of an ICC profile header
|
|||
/// </summary>
|
|||
internal sealed class IccProfileHeader |
|||
{ |
|||
/// <summary>
|
|||
/// Gets or sets the profile size in bytes (will be ignored when writing a profile)
|
|||
/// </summary>
|
|||
public uint Size { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the preferred CMM (Color Management Module) type
|
|||
/// </summary>
|
|||
public string CmmType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the profiles version number
|
|||
/// </summary>
|
|||
public Version Version { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the type of the profile
|
|||
/// </summary>
|
|||
public IccProfileClass Class { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the data colorspace
|
|||
/// </summary>
|
|||
public IccColorSpaceType DataColorSpace { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the profile connection space
|
|||
/// </summary>
|
|||
public IccColorSpaceType ProfileConnectionSpace { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the date and time this profile was created
|
|||
/// </summary>
|
|||
public DateTime CreationDate { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the file signature. Should always be "acsp".
|
|||
/// Value will be ignored when writing a profile.
|
|||
/// </summary>
|
|||
public string FileSignature { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the primary platform this profile as created for
|
|||
/// </summary>
|
|||
public IccPrimaryPlatformType PrimaryPlatformSignature { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the profile flags to indicate various options for the CMM
|
|||
/// such as distributed processing and caching options
|
|||
/// </summary>
|
|||
public IccProfileFlag Flags { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the device manufacturer of the device for which this profile is created
|
|||
/// </summary>
|
|||
public uint DeviceManufacturer { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the model of the device for which this profile is created
|
|||
/// </summary>
|
|||
public uint DeviceModel { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the device attributes unique to the particular device setup such as media type
|
|||
/// </summary>
|
|||
public IccDeviceAttribute DeviceAttributes { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the rendering Intent
|
|||
/// </summary>
|
|||
public IccRenderingIntent RenderingIntent { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets The normalized XYZ values of the illuminant of the PCS
|
|||
/// </summary>
|
|||
public Vector3 PcsIlluminant { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets Profile creator signature
|
|||
/// </summary>
|
|||
public string CreatorSignature { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the profile ID (hash)
|
|||
/// </summary>
|
|||
public IccProfileId Id { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,113 @@ |
|||
// <copyright file="IccReader.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Reads and parses ICC data from a byte array
|
|||
/// </summary>
|
|||
internal sealed class IccReader |
|||
{ |
|||
/// <summary>
|
|||
/// Reads an ICC profile
|
|||
/// </summary>
|
|||
/// <param name="data">The raw ICC data</param>
|
|||
/// <returns>The read ICC profile</returns>
|
|||
public IccProfile Read(byte[] data) |
|||
{ |
|||
Guard.IsTrue(data.Length < 128, nameof(data), "Data length must be at least 128 to be a valid ICC profile"); |
|||
|
|||
IccDataReader reader = new IccDataReader(data); |
|||
IccProfileHeader header = this.ReadHeader(reader); |
|||
IccTagDataEntry[] tagDate = this.ReadTagData(reader); |
|||
|
|||
return new IccProfile(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Reads an ICC profile header
|
|||
/// </summary>
|
|||
/// <param name="data">The raw ICC data</param>
|
|||
/// <returns>The read ICC profile header</returns>
|
|||
public IccProfileHeader ReadHeader(byte[] data) |
|||
{ |
|||
Guard.IsTrue(data.Length < 128, nameof(data), "Data length must be at least 128 to be a valid profile header"); |
|||
|
|||
IccDataReader reader = new IccDataReader(data); |
|||
return this.ReadHeader(reader); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Reads the ICC profile tag data
|
|||
/// </summary>
|
|||
/// <param name="data">The raw ICC data</param>
|
|||
/// <returns>The read ICC profile tag data</returns>
|
|||
public IccTagDataEntry[] ReadTagData(byte[] data) |
|||
{ |
|||
Guard.IsTrue(data.Length < 128, nameof(data), "Data length must be at least 128 to be a valid ICC profile"); |
|||
|
|||
IccDataReader reader = new IccDataReader(data); |
|||
return this.ReadTagData(reader); |
|||
} |
|||
|
|||
private IccProfileHeader ReadHeader(IccDataReader reader) |
|||
{ |
|||
reader.SetIndex(0); |
|||
|
|||
return new IccProfileHeader |
|||
{ |
|||
Size = reader.ReadUInt32(), |
|||
CmmType = reader.ReadASCIIString(4), |
|||
Version = reader.ReadVersionNumber(), |
|||
Class = (IccProfileClass)reader.ReadUInt32(), |
|||
DataColorSpace = (IccColorSpaceType)reader.ReadUInt32(), |
|||
ProfileConnectionSpace = (IccColorSpaceType)reader.ReadUInt32(), |
|||
CreationDate = reader.ReadDateTime(), |
|||
FileSignature = reader.ReadASCIIString(4), |
|||
PrimaryPlatformSignature = (IccPrimaryPlatformType)reader.ReadUInt32(), |
|||
Flags = (IccProfileFlag)reader.ReadDirect32(), |
|||
DeviceManufacturer = reader.ReadUInt32(), |
|||
DeviceModel = reader.ReadUInt32(), |
|||
DeviceAttributes = (IccDeviceAttribute)reader.ReadDirect64(), |
|||
RenderingIntent = (IccRenderingIntent)reader.ReadUInt32(), |
|||
PcsIlluminant = reader.ReadXyzNumber(), |
|||
CreatorSignature = reader.ReadASCIIString(4), |
|||
Id = reader.ReadProfileId(), |
|||
}; |
|||
} |
|||
|
|||
private IccTagDataEntry[] ReadTagData(IccDataReader reader) |
|||
{ |
|||
IccTagTableEntry[] tagTable = this.ReadTagTable(reader); |
|||
IccTagDataEntry[] entries = new IccTagDataEntry[tagTable.Length]; |
|||
for (int i = 0; i < tagTable.Length; i++) |
|||
{ |
|||
IccTagDataEntry entry = reader.ReadTagDataEntry(tagTable[i]); |
|||
entry.TagSignature = tagTable[i].Signature; |
|||
entries[i] = entry; |
|||
} |
|||
|
|||
return entries; |
|||
} |
|||
|
|||
private IccTagTableEntry[] ReadTagTable(IccDataReader reader) |
|||
{ |
|||
reader.SetIndex(128); // An ICC header is 128 bytes long
|
|||
|
|||
uint tagCount = reader.ReadUInt32(); |
|||
IccTagTableEntry[] table = new IccTagTableEntry[tagCount]; |
|||
|
|||
for (int i = 0; i < tagCount; i++) |
|||
{ |
|||
uint tagSignature = reader.ReadUInt32(); |
|||
uint tagOffset = reader.ReadUInt32(); |
|||
uint tagSize = reader.ReadUInt32(); |
|||
table[i] = new IccTagTableEntry((IccProfileTag)tagSignature, tagOffset, tagSize); |
|||
} |
|||
|
|||
return table; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
// <copyright file="IccTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// The data of an ICC tag entry
|
|||
/// </summary>
|
|||
internal abstract class IccTagDataEntry : IEquatable<IccTagDataEntry> |
|||
{ |
|||
private IccProfileTag tagSignature = IccProfileTag.Unknown; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccTagDataEntry"/> class.
|
|||
/// TagSignature will be <see cref="IccProfileTag.Unknown"/>
|
|||
/// </summary>
|
|||
/// <param name="signature">Type Signature</param>
|
|||
protected IccTagDataEntry(IccTypeSignature signature) |
|||
: this(signature, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="signature">Type Signature</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
protected IccTagDataEntry(IccTypeSignature signature, IccProfileTag tagSignature) |
|||
{ |
|||
this.Signature = signature; |
|||
this.tagSignature = tagSignature; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the type Signature
|
|||
/// </summary>
|
|||
public IccTypeSignature Signature { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the tag Signature
|
|||
/// </summary>
|
|||
public IccProfileTag TagSignature |
|||
{ |
|||
get { return this.tagSignature; } |
|||
set { this.tagSignature = value; } |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public virtual bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (other == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return this.Signature == other.Signature; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,106 @@ |
|||
// <copyright file="IccWriter.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// Contains methods for writing ICC profiles.
|
|||
/// </summary>
|
|||
internal sealed class IccWriter |
|||
{ |
|||
/// <summary>
|
|||
/// Writes the ICC profile into a byte array
|
|||
/// </summary>
|
|||
/// <param name="profile">The ICC profile to write</param>
|
|||
/// <returns>The ICC profile as a byte array</returns>
|
|||
public byte[] Write(IccProfile profile) |
|||
{ |
|||
IccDataWriter writer = new IccDataWriter(); |
|||
IccTagTableEntry[] tagTable = this.WriteTagData(writer, profile.Entries); |
|||
this.WriteTagTable(writer, tagTable); |
|||
this.WriteHeader(writer, profile.Header); |
|||
return writer.GetData(); |
|||
} |
|||
|
|||
private void WriteHeader(IccDataWriter writer, IccProfileHeader header) |
|||
{ |
|||
writer.SetIndex(0); |
|||
|
|||
writer.WriteUInt32(writer.Length + 128); |
|||
writer.WriteASCIIString(header.CmmType, 4, ' '); |
|||
writer.WriteVersionNumber(header.Version); |
|||
writer.WriteUInt32((uint)header.Class); |
|||
writer.WriteUInt32((uint)header.DataColorSpace); |
|||
writer.WriteUInt32((uint)header.ProfileConnectionSpace); |
|||
writer.WriteDateTime(header.CreationDate); |
|||
writer.WriteASCIIString("acsp"); |
|||
writer.WriteUInt32((uint)header.PrimaryPlatformSignature); |
|||
writer.WriteDirect32((int)header.Flags); |
|||
writer.WriteUInt32(header.DeviceManufacturer); |
|||
writer.WriteUInt32(header.DeviceModel); |
|||
writer.WriteDirect64((long)header.DeviceAttributes); |
|||
writer.WriteUInt32((uint)header.RenderingIntent); |
|||
writer.WriteXYZNumber(header.PcsIlluminant); |
|||
writer.WriteASCIIString(header.CreatorSignature, 4, ' '); |
|||
|
|||
#if !NETSTANDARD1_1
|
|||
IccProfileId id = IccProfile.CalculateHash(writer.GetData()); |
|||
writer.WriteProfileId(id); |
|||
#else
|
|||
writer.WriteProfileId(IccProfileId.Zero); |
|||
#endif
|
|||
} |
|||
|
|||
private void WriteTagTable(IccDataWriter writer, IccTagTableEntry[] table) |
|||
{ |
|||
// 128 = size of ICC header
|
|||
writer.SetIndex(128); |
|||
|
|||
writer.WriteUInt32((uint)table.Length); |
|||
foreach (IccTagTableEntry entry in table) |
|||
{ |
|||
writer.WriteUInt32((uint)entry.Signature); |
|||
writer.WriteUInt32(entry.Offset); |
|||
writer.WriteUInt32(entry.DataSize); |
|||
} |
|||
} |
|||
|
|||
private IccTagTableEntry[] WriteTagData(IccDataWriter writer, List<IccTagDataEntry> entries) |
|||
{ |
|||
List<IccTagDataEntry> inData = new List<IccTagDataEntry>(entries); |
|||
List<IccTagDataEntry[]> dupData = new List<IccTagDataEntry[]>(); |
|||
|
|||
// Filter out duplicate entries. They only need to be defined once but can be used multiple times
|
|||
while (inData.Count > 0) |
|||
{ |
|||
IccTagDataEntry[] items = inData.Where(t => inData[0].Equals(t)).ToArray(); |
|||
dupData.Add(items); |
|||
foreach (IccTagDataEntry item in items) |
|||
{ |
|||
inData.Remove(item); |
|||
} |
|||
} |
|||
|
|||
List<IccTagTableEntry> table = new List<IccTagTableEntry>(); |
|||
|
|||
// (Header size) + (entry count) + (nr of entries) * (size of table entry)
|
|||
writer.SetIndex(128 + 4 + (entries.Count * 12)); |
|||
|
|||
foreach (IccTagDataEntry[] entry in dupData) |
|||
{ |
|||
writer.WriteTagDataEntry(entry[0], out IccTagTableEntry tentry); |
|||
foreach (IccTagDataEntry item in entry) |
|||
{ |
|||
table.Add(new IccTagTableEntry(item.TagSignature, tentry.Offset, tentry.DataSize)); |
|||
} |
|||
} |
|||
|
|||
return table.ToArray(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
// <copyright file="IccBAcsProcessElement.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// A placeholder <see cref="IccMultiProcessElement"/> (might be used for future ICC versions)
|
|||
/// </summary>
|
|||
internal sealed class IccBAcsProcessElement : IccMultiProcessElement |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccBAcsProcessElement"/> class.
|
|||
/// </summary>
|
|||
/// <param name="inChannelCount">Number of input channels</param>
|
|||
/// <param name="outChannelCount">Number of output channels</param>
|
|||
public IccBAcsProcessElement(int inChannelCount, int outChannelCount) |
|||
: base(IccMultiProcessElementSignature.BAcs, inChannelCount, outChannelCount) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
// <copyright file="IccClutProcessElement.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// A CLUT (color lookup table) element to process data
|
|||
/// </summary>
|
|||
internal sealed class IccClutProcessElement : IccMultiProcessElement |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccClutProcessElement"/> class.
|
|||
/// </summary>
|
|||
/// <param name="clutValue">The color lookup table of this element</param>
|
|||
public IccClutProcessElement(IccClut clutValue) |
|||
: base(IccMultiProcessElementSignature.Clut, clutValue?.InputChannelCount ?? 1, clutValue?.OutputChannelCount ?? 1) |
|||
{ |
|||
Guard.NotNull(clutValue, nameof(clutValue)); |
|||
this.ClutValue = clutValue; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the color lookup table of this element
|
|||
/// </summary>
|
|||
public IccClut ClutValue { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccMultiProcessElement other) |
|||
{ |
|||
if (base.Equals(other) && other is IccClutProcessElement element) |
|||
{ |
|||
return this.ClutValue.Equals(element.ClutValue); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
// <copyright file="IccCurveSetProcessElement.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// A set of curves to process data
|
|||
/// </summary>
|
|||
internal sealed class IccCurveSetProcessElement : IccMultiProcessElement |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccCurveSetProcessElement"/> class.
|
|||
/// </summary>
|
|||
/// <param name="curves">An array with one dimensional curves</param>
|
|||
public IccCurveSetProcessElement(IccOneDimensionalCurve[] curves) |
|||
: base(IccMultiProcessElementSignature.CurveSet, curves?.Length ?? 1, curves?.Length ?? 1) |
|||
{ |
|||
Guard.NotNull(curves, nameof(curves)); |
|||
this.Curves = curves; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets an array of one dimensional curves
|
|||
/// </summary>
|
|||
public IccOneDimensionalCurve[] Curves { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccMultiProcessElement other) |
|||
{ |
|||
if (base.Equals(other) && other is IccCurveSetProcessElement element) |
|||
{ |
|||
return this.Curves.SequenceEqual(element.Curves); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
// <copyright file="IccEAcsProcessElement.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// A placeholder <see cref="IccMultiProcessElement"/> (might be used for future ICC versions)
|
|||
/// </summary>
|
|||
internal sealed class IccEAcsProcessElement : IccMultiProcessElement |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccEAcsProcessElement"/> class.
|
|||
/// </summary>
|
|||
/// <param name="inChannelCount">Number of input channels</param>
|
|||
/// <param name="outChannelCount">Number of output channels</param>
|
|||
public IccEAcsProcessElement(int inChannelCount, int outChannelCount) |
|||
: base(IccMultiProcessElementSignature.EAcs, inChannelCount, outChannelCount) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,71 @@ |
|||
// <copyright file="IccMatrixProcessElement.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// A matrix element to process data
|
|||
/// </summary>
|
|||
internal sealed class IccMatrixProcessElement : IccMultiProcessElement |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccMatrixProcessElement"/> class.
|
|||
/// </summary>
|
|||
/// <param name="matrixIxO">Two dimensional matrix with size of Input-Channels x Output-Channels</param>
|
|||
/// <param name="matrixOx1">One dimensional matrix with size of Output-Channels x 1</param>
|
|||
public IccMatrixProcessElement(float[,] matrixIxO, float[] matrixOx1) |
|||
: base(IccMultiProcessElementSignature.Matrix, matrixIxO?.GetLength(0) ?? 1, matrixIxO?.GetLength(1) ?? 1) |
|||
{ |
|||
Guard.NotNull(matrixIxO, nameof(matrixIxO)); |
|||
Guard.NotNull(matrixOx1, nameof(matrixOx1)); |
|||
|
|||
bool wrongMatrixSize = matrixIxO.GetLength(1) != matrixOx1.Length; |
|||
Guard.IsTrue(wrongMatrixSize, $"{nameof(matrixIxO)},{nameof(matrixIxO)}", "Output channel length must match"); |
|||
|
|||
this.MatrixIxO = matrixIxO; |
|||
this.MatrixOx1 = matrixOx1; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the two dimensional matrix with size of Input-Channels x Output-Channels
|
|||
/// </summary>
|
|||
public Fast2DArray<float> MatrixIxO { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the one dimensional matrix with size of Output-Channels x 1
|
|||
/// </summary>
|
|||
public float[] MatrixOx1 { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccMultiProcessElement other) |
|||
{ |
|||
if (base.Equals(other) && other is IccMatrixProcessElement element) |
|||
{ |
|||
return this.EqualsMatrix(element) |
|||
&& this.MatrixOx1.SequenceEqual(element.MatrixOx1); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
private bool EqualsMatrix(IccMatrixProcessElement element) |
|||
{ |
|||
for (int x = 0; x < this.MatrixIxO.Width; x++) |
|||
{ |
|||
for (int y = 0; y < this.MatrixIxO.Height; y++) |
|||
{ |
|||
if (this.MatrixIxO[x, y] != element.MatrixIxO[x, y]) |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,64 @@ |
|||
// <copyright file="IccMultiProcessElement.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// An element to process data
|
|||
/// </summary>
|
|||
internal abstract class IccMultiProcessElement : IEquatable<IccMultiProcessElement> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccMultiProcessElement"/> class.
|
|||
/// </summary>
|
|||
/// <param name="signature">The signature of this element</param>
|
|||
/// <param name="inChannelCount">Number of input channels</param>
|
|||
/// <param name="outChannelCount">Number of output channels</param>
|
|||
protected IccMultiProcessElement(IccMultiProcessElementSignature signature, int inChannelCount, int outChannelCount) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(inChannelCount, 1, 15, nameof(inChannelCount)); |
|||
Guard.MustBeBetweenOrEqualTo(outChannelCount, 1, 15, nameof(outChannelCount)); |
|||
|
|||
this.Signature = signature; |
|||
this.InputChannelCount = inChannelCount; |
|||
this.OutputChannelCount = outChannelCount; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the signature of this element
|
|||
/// </summary>
|
|||
public IccMultiProcessElementSignature Signature { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of input channels
|
|||
/// </summary>
|
|||
public int InputChannelCount { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of output channels
|
|||
/// </summary>
|
|||
public int OutputChannelCount { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public virtual bool Equals(IccMultiProcessElement other) |
|||
{ |
|||
if (other == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return this.Signature == other.Signature |
|||
&& this.InputChannelCount == other.InputChannelCount |
|||
&& this.OutputChannelCount == other.OutputChannelCount; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,136 @@ |
|||
// <copyright file="IccChromaticityTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// The chromaticity tag type provides basic chromaticity data
|
|||
/// and type of phosphors or colorants of a monitor to applications and utilities.
|
|||
/// </summary>
|
|||
internal sealed class IccChromaticityTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccChromaticityTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="colorantType">Colorant Type</param>
|
|||
public IccChromaticityTagDataEntry(IccColorantEncoding colorantType) |
|||
: this(colorantType, GetColorantArray(colorantType), IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccChromaticityTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="channelValues">Values per channel</param>
|
|||
public IccChromaticityTagDataEntry(double[][] channelValues) |
|||
: this(IccColorantEncoding.Unknown, channelValues, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccChromaticityTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="colorantType">Colorant Type</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccChromaticityTagDataEntry(IccColorantEncoding colorantType, IccProfileTag tagSignature) |
|||
: this(colorantType, GetColorantArray(colorantType), tagSignature) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccChromaticityTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="channelValues">Values per channel</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccChromaticityTagDataEntry(double[][] channelValues, IccProfileTag tagSignature) |
|||
: this(IccColorantEncoding.Unknown, channelValues, tagSignature) |
|||
{ |
|||
} |
|||
|
|||
private IccChromaticityTagDataEntry(IccColorantEncoding colorantType, double[][] channelValues, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.Chromaticity, tagSignature) |
|||
{ |
|||
Guard.NotNull(channelValues, nameof(channelValues)); |
|||
Guard.MustBeBetweenOrEqualTo(channelValues.Length, 1, 15, nameof(channelValues)); |
|||
|
|||
this.ColorantType = colorantType; |
|||
this.ChannelValues = channelValues; |
|||
|
|||
int channelLength = channelValues[0].Length; |
|||
bool channelsNotSame = channelValues.Any(t => t == null || t.Length != channelLength); |
|||
Guard.IsTrue(channelsNotSame, nameof(channelValues), "The number of values per channel is not the same for all channels"); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of channels
|
|||
/// </summary>
|
|||
public int ChannelCount |
|||
{ |
|||
get { return this.ChannelValues.Length; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the colorant type
|
|||
/// </summary>
|
|||
public IccColorantEncoding ColorantType { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the values per channel
|
|||
/// </summary>
|
|||
public double[][] ChannelValues { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccChromaticityTagDataEntry entry) |
|||
{ |
|||
return this.ColorantType == entry.ColorantType |
|||
&& this.ChannelValues.SequenceEqual(entry.ChannelValues); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
private static double[][] GetColorantArray(IccColorantEncoding colorantType) |
|||
{ |
|||
switch (colorantType) |
|||
{ |
|||
case IccColorantEncoding.EBU_Tech_3213_E: |
|||
return new double[][] |
|||
{ |
|||
new double[] { 0.640, 0.330 }, |
|||
new double[] { 0.290, 0.600 }, |
|||
new double[] { 0.150, 0.060 }, |
|||
}; |
|||
case IccColorantEncoding.ITU_R_BT_709_2: |
|||
return new double[][] |
|||
{ |
|||
new double[] { 0.640, 0.330 }, |
|||
new double[] { 0.300, 0.600 }, |
|||
new double[] { 0.150, 0.060 }, |
|||
}; |
|||
case IccColorantEncoding.P22: |
|||
return new double[][] |
|||
{ |
|||
new double[] { 0.625, 0.340 }, |
|||
new double[] { 0.280, 0.605 }, |
|||
new double[] { 0.155, 0.070 }, |
|||
}; |
|||
case IccColorantEncoding.SMPTE_RP145: |
|||
return new double[][] |
|||
{ |
|||
new double[] { 0.630, 0.340 }, |
|||
new double[] { 0.310, 0.595 }, |
|||
new double[] { 0.155, 0.070 }, |
|||
}; |
|||
default: |
|||
throw new ArgumentException("Unrecognized colorant encoding"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
// <copyright file="IccColorantOrderTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// This tag specifies the laydown order in which colorants
|
|||
/// will be printed on an n-colorant device.
|
|||
/// </summary>
|
|||
internal sealed class IccColorantOrderTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccColorantOrderTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="colorantNumber">Colorant order numbers</param>
|
|||
public IccColorantOrderTagDataEntry(byte[] colorantNumber) |
|||
: this(colorantNumber, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccColorantOrderTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="colorantNumber">Colorant order numbers</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccColorantOrderTagDataEntry(byte[] colorantNumber, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.ColorantOrder, tagSignature) |
|||
{ |
|||
Guard.NotNull(colorantNumber, nameof(colorantNumber)); |
|||
Guard.MustBeBetweenOrEqualTo(colorantNumber.Length, 1, 15, nameof(colorantNumber)); |
|||
|
|||
this.ColorantNumber = colorantNumber; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the colorant order numbers
|
|||
/// </summary>
|
|||
public byte[] ColorantNumber { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccColorantOrderTagDataEntry entry) |
|||
{ |
|||
return this.ColorantNumber.SequenceEqual(entry.ColorantNumber); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
// <copyright file="IccColorantTableTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// The purpose of this tag is to identify the colorants used in
|
|||
/// the profile by a unique name and set of PCSXYZ or PCSLAB values
|
|||
/// to give the colorant an unambiguous value.
|
|||
/// </summary>
|
|||
internal sealed class IccColorantTableTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccColorantTableTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="colorantData">Colorant Data</param>
|
|||
public IccColorantTableTagDataEntry(IccColorantTableEntry[] colorantData) |
|||
: this(colorantData, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccColorantTableTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="colorantData">Colorant Data</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccColorantTableTagDataEntry(IccColorantTableEntry[] colorantData, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.ColorantTable, tagSignature) |
|||
{ |
|||
Guard.NotNull(colorantData, nameof(colorantData)); |
|||
Guard.MustBeBetweenOrEqualTo(colorantData.Length, 1, 15, nameof(colorantData)); |
|||
|
|||
this.ColorantData = colorantData; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the colorant data
|
|||
/// </summary>
|
|||
public IccColorantTableEntry[] ColorantData { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccColorantTableTagDataEntry entry) |
|||
{ |
|||
return this.ColorantData.SequenceEqual(entry.ColorantData); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,122 @@ |
|||
// <copyright file="IccCurveTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// The type contains a one-dimensional table of double values.
|
|||
/// </summary>
|
|||
internal sealed class IccCurveTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccCurveTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
public IccCurveTagDataEntry() |
|||
: this(new float[0], IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccCurveTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="gamma">Gamma value</param>
|
|||
public IccCurveTagDataEntry(float gamma) |
|||
: this(new float[] { gamma }, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccCurveTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="curveData">Curve Data</param>
|
|||
public IccCurveTagDataEntry(float[] curveData) |
|||
: this(curveData, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccCurveTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccCurveTagDataEntry(IccProfileTag tagSignature) |
|||
: this(new float[0], tagSignature) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccCurveTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="gamma">Gamma value</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccCurveTagDataEntry(float gamma, IccProfileTag tagSignature) |
|||
: this(new float[] { gamma }, tagSignature) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccCurveTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="curveData">Curve Data</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccCurveTagDataEntry(float[] curveData, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.Curve, tagSignature) |
|||
{ |
|||
this.CurveData = curveData ?? new float[0]; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the curve data
|
|||
/// </summary>
|
|||
public float[] CurveData { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the gamma value.
|
|||
/// Only valid if <see cref="IsGamma"/> is true
|
|||
/// </summary>
|
|||
public float Gamma |
|||
{ |
|||
get |
|||
{ |
|||
if (this.IsGamma) |
|||
{ |
|||
return this.CurveData[0]; |
|||
} |
|||
else |
|||
{ |
|||
return 0; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether the curve maps input directly to output
|
|||
/// </summary>
|
|||
public bool IsIdentityResponse |
|||
{ |
|||
get { return this.CurveData.Length == 0; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether the curve is a gamma curve
|
|||
/// </summary>
|
|||
public bool IsGamma |
|||
{ |
|||
get { return this.CurveData.Length == 1; } |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccCurveTagDataEntry entry) |
|||
{ |
|||
return this.CurveData.SequenceEqual(entry.CurveData); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,92 @@ |
|||
// <copyright file="IccDataTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
using System.Text; |
|||
|
|||
/// <summary>
|
|||
/// The dataType is a simple data structure that contains
|
|||
/// either 7-bit ASCII or binary data, i.e. textType data or transparent bytes.
|
|||
/// </summary>
|
|||
internal sealed class IccDataTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccDataTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The raw data</param>
|
|||
public IccDataTagDataEntry(byte[] data) |
|||
: this(data, false, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccDataTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The raw data</param>
|
|||
/// <param name="isAscii">True if the given data is 7bit ASCII encoded text</param>
|
|||
public IccDataTagDataEntry(byte[] data, bool isAscii) |
|||
: this(data, isAscii, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccDataTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The raw data</param>
|
|||
/// <param name="isAscii">True if the given data is 7bit ASCII encoded text</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccDataTagDataEntry(byte[] data, bool isAscii, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.Data, tagSignature) |
|||
{ |
|||
Guard.NotNull(data, nameof(data)); |
|||
this.Data = data; |
|||
this.IsAscii = isAscii; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the raw Data
|
|||
/// </summary>
|
|||
public byte[] Data { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether the <see cref="Data"/> represents 7bit ASCII encoded text
|
|||
/// </summary>
|
|||
public bool IsAscii { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the <see cref="Data"/> decoded as 7bit ASCII.
|
|||
/// If <see cref="IsAscii"/> is false, returns null
|
|||
/// </summary>
|
|||
public string AsciiString |
|||
{ |
|||
get |
|||
{ |
|||
if (this.IsAscii) |
|||
{ |
|||
// Encoding.ASCII is missing in netstandard1.1, use UTF8 instead because it's compatible with ASCII
|
|||
return Encoding.UTF8.GetString(this.Data, 0, this.Data.Length); |
|||
} |
|||
else |
|||
{ |
|||
return null; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccDataTagDataEntry entry) |
|||
{ |
|||
return this.IsAscii == entry.IsAscii |
|||
&& this.Data.SequenceEqual(entry.Data); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
// <copyright file="IccDateTimeTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// This type is a representation of the time and date.
|
|||
/// </summary>
|
|||
internal sealed class IccDateTimeTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccDateTimeTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="value">The DateTime value</param>
|
|||
public IccDateTimeTagDataEntry(DateTime value) |
|||
: this(value, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccDateTimeTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="value">The DateTime value</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccDateTimeTagDataEntry(DateTime value, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.DateTime, tagSignature) |
|||
{ |
|||
this.Value = value; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the date and time value
|
|||
/// </summary>
|
|||
public DateTime Value { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccDateTimeTagDataEntry entry) |
|||
{ |
|||
return this.Value == entry.Value; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
// <copyright file="IccFix16ArrayTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// This type represents an array of doubles (from 32bit fixed point values).
|
|||
/// </summary>
|
|||
internal sealed class IccFix16ArrayTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccFix16ArrayTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The array data</param>
|
|||
public IccFix16ArrayTagDataEntry(float[] data) |
|||
: this(data, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccFix16ArrayTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The array data</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccFix16ArrayTagDataEntry(float[] data, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.S15Fixed16Array, tagSignature) |
|||
{ |
|||
Guard.NotNull(data, nameof(data)); |
|||
this.Data = data; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the array data
|
|||
/// </summary>
|
|||
public float[] Data { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccFix16ArrayTagDataEntry entry) |
|||
{ |
|||
return this.Data.SequenceEqual(entry.Data); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,153 @@ |
|||
// <copyright file="IccLut16TagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// This structure represents a color transform using tables
|
|||
/// with 16-bit precision.
|
|||
/// </summary>
|
|||
internal sealed class IccLut16TagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLut16TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="inputValues">Input LUT</param>
|
|||
/// <param name="clutValues">CLUT</param>
|
|||
/// <param name="outputValues">Output LUT</param>
|
|||
public IccLut16TagDataEntry(IccLut[] inputValues, IccClut clutValues, IccLut[] outputValues) |
|||
: this(null, inputValues, clutValues, outputValues, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLut16TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="inputValues">Input LUT</param>
|
|||
/// <param name="clutValues">CLUT</param>
|
|||
/// <param name="outputValues">Output LUT</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccLut16TagDataEntry(IccLut[] inputValues, IccClut clutValues, IccLut[] outputValues, IccProfileTag tagSignature) |
|||
: this(null, inputValues, clutValues, outputValues, tagSignature) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLut16TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="matrix">Conversion matrix (must be 3x3)</param>
|
|||
/// <param name="inputValues">Input LUT</param>
|
|||
/// <param name="clutValues">CLUT</param>
|
|||
/// <param name="outputValues">Output LUT</param>
|
|||
public IccLut16TagDataEntry(float[,] matrix, IccLut[] inputValues, IccClut clutValues, IccLut[] outputValues) |
|||
: this(matrix, inputValues, clutValues, outputValues, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLut16TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="matrix">Conversion matrix (must be 3x3)</param>
|
|||
/// <param name="inputValues">Input LUT</param>
|
|||
/// <param name="clutValues">CLUT</param>
|
|||
/// <param name="outputValues">Output LUT</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccLut16TagDataEntry(float[,] matrix, IccLut[] inputValues, IccClut clutValues, IccLut[] outputValues, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.Lut16, tagSignature) |
|||
{ |
|||
Guard.NotNull(inputValues, nameof(inputValues)); |
|||
Guard.NotNull(clutValues, nameof(clutValues)); |
|||
Guard.NotNull(outputValues, nameof(outputValues)); |
|||
|
|||
if (matrix != null) |
|||
{ |
|||
bool isNot3By3 = matrix.GetLength(0) != 3 || matrix.GetLength(1) != 3; |
|||
Guard.IsTrue(isNot3By3, nameof(matrix), "Matrix must have a size of three by three"); |
|||
} |
|||
|
|||
Guard.IsTrue(this.InputChannelCount != clutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size"); |
|||
Guard.IsTrue(this.OutputChannelCount != clutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size"); |
|||
|
|||
this.Matrix = this.CreateMatrix(matrix); |
|||
this.InputValues = inputValues; |
|||
this.ClutValues = clutValues; |
|||
this.OutputValues = outputValues; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of input channels
|
|||
/// </summary>
|
|||
public int InputChannelCount |
|||
{ |
|||
get { return this.InputValues.Length; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of output channels
|
|||
/// </summary>
|
|||
public int OutputChannelCount |
|||
{ |
|||
get { return this.OutputValues.Length; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the conversion matrix
|
|||
/// </summary>
|
|||
public Matrix4x4 Matrix { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the input lookup table
|
|||
/// </summary>
|
|||
public IccLut[] InputValues { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the color lookup table
|
|||
/// </summary>
|
|||
public IccClut ClutValues { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the output lookup table
|
|||
/// </summary>
|
|||
public IccLut[] OutputValues { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccLut16TagDataEntry entry) |
|||
{ |
|||
return this.ClutValues == entry.ClutValues |
|||
&& this.Matrix == entry.Matrix |
|||
&& this.InputValues.SequenceEqual(entry.InputValues) |
|||
&& this.OutputValues.SequenceEqual(entry.OutputValues); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
private Matrix4x4 CreateMatrix(float[,] matrix) |
|||
{ |
|||
return new Matrix4x4( |
|||
matrix[0, 0], |
|||
matrix[0, 1], |
|||
matrix[0, 2], |
|||
0, |
|||
matrix[1, 0], |
|||
matrix[1, 1], |
|||
matrix[1, 2], |
|||
0, |
|||
matrix[2, 0], |
|||
matrix[2, 1], |
|||
matrix[2, 2], |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
1); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,156 @@ |
|||
// <copyright file="IccLut8TagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// This structure represents a color transform using tables
|
|||
/// with 8-bit precision.
|
|||
/// </summary>
|
|||
internal sealed class IccLut8TagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLut8TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="inputValues">Input LUT</param>
|
|||
/// <param name="clutValues">CLUT</param>
|
|||
/// <param name="outputValues">Output LUT</param>
|
|||
public IccLut8TagDataEntry(IccLut[] inputValues, IccClut clutValues, IccLut[] outputValues) |
|||
: this(null, inputValues, clutValues, outputValues, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLut8TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="inputValues">Input LUT</param>
|
|||
/// <param name="clutValues">CLUT</param>
|
|||
/// <param name="outputValues">Output LUT</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccLut8TagDataEntry(IccLut[] inputValues, IccClut clutValues, IccLut[] outputValues, IccProfileTag tagSignature) |
|||
: this(null, inputValues, clutValues, outputValues, tagSignature) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLut8TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="matrix">Conversion matrix (must be 3x3)</param>
|
|||
/// <param name="inputValues">Input LUT</param>
|
|||
/// <param name="clutValues">CLUT</param>
|
|||
/// <param name="outputValues">Output LUT</param>
|
|||
public IccLut8TagDataEntry(float[,] matrix, IccLut[] inputValues, IccClut clutValues, IccLut[] outputValues) |
|||
: this(matrix, inputValues, clutValues, outputValues, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLut8TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="matrix">Conversion matrix (must be 3x3)</param>
|
|||
/// <param name="inputValues">Input LUT</param>
|
|||
/// <param name="clutValues">CLUT</param>
|
|||
/// <param name="outputValues">Output LUT</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccLut8TagDataEntry(float[,] matrix, IccLut[] inputValues, IccClut clutValues, IccLut[] outputValues, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.Lut8, tagSignature) |
|||
{ |
|||
Guard.NotNull(inputValues, nameof(inputValues)); |
|||
Guard.NotNull(clutValues, nameof(clutValues)); |
|||
Guard.NotNull(outputValues, nameof(outputValues)); |
|||
|
|||
if (matrix != null) |
|||
{ |
|||
bool isNot3By3 = matrix.GetLength(0) != 3 || matrix.GetLength(1) != 3; |
|||
Guard.IsTrue(isNot3By3, nameof(matrix), "Matrix must have a size of three by three"); |
|||
} |
|||
|
|||
Guard.IsTrue(this.InputChannelCount != clutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size"); |
|||
Guard.IsTrue(this.OutputChannelCount != clutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size"); |
|||
|
|||
Guard.IsTrue(inputValues.Any(t => t.Values.Length != 256), nameof(inputValues), "Input lookup table has to have a length of 256"); |
|||
Guard.IsTrue(outputValues.Any(t => t.Values.Length != 256), nameof(outputValues), "Output lookup table has to have a length of 256"); |
|||
|
|||
this.Matrix = this.CreateMatrix(matrix); |
|||
this.InputValues = inputValues; |
|||
this.ClutValues = clutValues; |
|||
this.OutputValues = outputValues; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of input channels
|
|||
/// </summary>
|
|||
public int InputChannelCount |
|||
{ |
|||
get { return this.InputValues.Length; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of output channels
|
|||
/// </summary>
|
|||
public int OutputChannelCount |
|||
{ |
|||
get { return this.OutputValues.Length; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the conversion matrix
|
|||
/// </summary>
|
|||
public Matrix4x4 Matrix { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the input lookup table
|
|||
/// </summary>
|
|||
public IccLut[] InputValues { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the color lookup table
|
|||
/// </summary>
|
|||
public IccClut ClutValues { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the output lookup table
|
|||
/// </summary>
|
|||
public IccLut[] OutputValues { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccLut16TagDataEntry entry) |
|||
{ |
|||
return this.ClutValues == entry.ClutValues |
|||
&& this.Matrix == entry.Matrix |
|||
&& this.InputValues.SequenceEqual(entry.InputValues) |
|||
&& this.OutputValues.SequenceEqual(entry.OutputValues); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
private Matrix4x4 CreateMatrix(float[,] matrix) |
|||
{ |
|||
return new Matrix4x4( |
|||
matrix[0, 0], |
|||
matrix[0, 1], |
|||
matrix[0, 2], |
|||
0, |
|||
matrix[1, 0], |
|||
matrix[1, 1], |
|||
matrix[1, 2], |
|||
0, |
|||
matrix[2, 0], |
|||
matrix[2, 1], |
|||
matrix[2, 2], |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
1); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,274 @@ |
|||
// <copyright file="IccLutAToBTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// This structure represents a color transform.
|
|||
/// </summary>
|
|||
internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLutAToBTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="curveA">A Curve</param>
|
|||
/// <param name="clutValues">CLUT</param>
|
|||
/// <param name="curveM">M Curve</param>
|
|||
/// <param name="matrix3x3">Two dimensional conversion matrix (3x3)</param>
|
|||
/// <param name="matrix3x1">One dimensional conversion matrix (3x1)</param>
|
|||
/// <param name="curveB">B Curve</param>
|
|||
public IccLutAToBTagDataEntry( |
|||
IccTagDataEntry[] curveB, |
|||
float[,] matrix3x3, |
|||
float[] matrix3x1, |
|||
IccTagDataEntry[] curveM, |
|||
IccClut clutValues, |
|||
IccTagDataEntry[] curveA) |
|||
: this(curveB, matrix3x3, matrix3x1, curveM, clutValues, curveA, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLutAToBTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="curveA">A Curve</param>
|
|||
/// <param name="clutValues">CLUT</param>
|
|||
/// <param name="curveM">M Curve</param>
|
|||
/// <param name="matrix3x3">Two dimensional conversion matrix (3x3)</param>
|
|||
/// <param name="matrix3x1">One dimensional conversion matrix (3x1)</param>
|
|||
/// <param name="curveB">B Curve</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccLutAToBTagDataEntry( |
|||
IccTagDataEntry[] curveB, |
|||
float[,] matrix3x3, |
|||
float[] matrix3x1, |
|||
IccTagDataEntry[] curveM, |
|||
IccClut clutValues, |
|||
IccTagDataEntry[] curveA, |
|||
IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.LutAToB, tagSignature) |
|||
{ |
|||
this.VerifyMatrix(matrix3x3, matrix3x1); |
|||
this.VerifyCurve(curveA, nameof(curveA)); |
|||
this.VerifyCurve(curveB, nameof(curveB)); |
|||
this.VerifyCurve(curveM, nameof(curveM)); |
|||
|
|||
this.Matrix3x3 = this.CreateMatrix3x3(matrix3x3); |
|||
this.Matrix3x1 = this.CreateMatrix3x1(matrix3x1); |
|||
this.CurveA = curveA; |
|||
this.CurveB = curveB; |
|||
this.CurveM = curveM; |
|||
this.ClutValues = clutValues; |
|||
|
|||
if (this.IsAClutMMatrixB()) |
|||
{ |
|||
Guard.IsTrue(this.CurveB.Length != 3, nameof(this.CurveB), $"{nameof(this.CurveB)} must have a length of three"); |
|||
Guard.IsTrue(this.CurveM.Length != 3, nameof(this.CurveM), $"{nameof(this.CurveM)} must have a length of three"); |
|||
Guard.MustBeBetweenOrEqualTo(this.CurveA.Length, 1, 15, nameof(this.CurveA)); |
|||
|
|||
this.InputChannelCount = curveA.Length; |
|||
this.OutputChannelCount = 3; |
|||
|
|||
Guard.IsTrue(this.InputChannelCount != clutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size"); |
|||
Guard.IsTrue(this.OutputChannelCount != clutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size"); |
|||
} |
|||
else if (this.IsMMatrixB()) |
|||
{ |
|||
Guard.IsTrue(this.CurveB.Length != 3, nameof(this.CurveB), $"{nameof(this.CurveB)} must have a length of three"); |
|||
Guard.IsTrue(this.CurveM.Length != 3, nameof(this.CurveM), $"{nameof(this.CurveM)} must have a length of three"); |
|||
|
|||
this.InputChannelCount = this.OutputChannelCount = 3; |
|||
} |
|||
else if (this.IsAClutB()) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(this.CurveA.Length, 1, 15, nameof(this.CurveA)); |
|||
Guard.MustBeBetweenOrEqualTo(this.CurveB.Length, 1, 15, nameof(this.CurveB)); |
|||
|
|||
this.InputChannelCount = curveA.Length; |
|||
this.OutputChannelCount = curveB.Length; |
|||
|
|||
Guard.IsTrue(this.InputChannelCount != clutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size"); |
|||
Guard.IsTrue(this.OutputChannelCount != clutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size"); |
|||
} |
|||
else if (this.IsB()) |
|||
{ |
|||
this.InputChannelCount = this.OutputChannelCount = this.CurveB.Length; |
|||
} |
|||
else |
|||
{ |
|||
throw new ArgumentException("Invalid combination of values given"); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of input channels
|
|||
/// </summary>
|
|||
public int InputChannelCount { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of output channels
|
|||
/// </summary>
|
|||
public int OutputChannelCount { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the two dimensional conversion matrix (3x3)
|
|||
/// </summary>
|
|||
public Matrix4x4? Matrix3x3 { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the one dimensional conversion matrix (3x1)
|
|||
/// </summary>
|
|||
public Vector3? Matrix3x1 { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the color lookup table
|
|||
/// </summary>
|
|||
public IccClut ClutValues { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the B Curve
|
|||
/// </summary>
|
|||
public IccTagDataEntry[] CurveB { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the M Curve
|
|||
/// </summary>
|
|||
public IccTagDataEntry[] CurveM { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the A Curve
|
|||
/// </summary>
|
|||
public IccTagDataEntry[] CurveA { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccLutAToBTagDataEntry entry) |
|||
{ |
|||
return this.InputChannelCount == entry.InputChannelCount |
|||
&& this.OutputChannelCount == entry.OutputChannelCount |
|||
&& this.Matrix3x1 == entry.Matrix3x1 |
|||
&& this.Matrix3x3 == entry.Matrix3x3 |
|||
&& this.ClutValues == entry.ClutValues |
|||
&& this.EqualsCurve(this.CurveA, entry.CurveA) |
|||
&& this.EqualsCurve(this.CurveB, entry.CurveB) |
|||
&& this.EqualsCurve(this.CurveM, entry.CurveM); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
private bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCurves) |
|||
{ |
|||
bool thisNull = thisCurves == null; |
|||
bool entryNull = entryCurves == null; |
|||
|
|||
if (thisNull && entryNull) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
if (entryNull) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return thisCurves.SequenceEqual(entryCurves); |
|||
} |
|||
|
|||
private bool IsAClutMMatrixB() |
|||
{ |
|||
return this.CurveB != null |
|||
&& this.Matrix3x3 != null |
|||
&& this.Matrix3x1 != null |
|||
&& this.CurveM != null |
|||
&& this.ClutValues != null |
|||
&& this.CurveA != null; |
|||
} |
|||
|
|||
private bool IsMMatrixB() |
|||
{ |
|||
return this.CurveB != null |
|||
&& this.Matrix3x3 != null |
|||
&& this.Matrix3x1 != null |
|||
&& this.CurveM != null; |
|||
} |
|||
|
|||
private bool IsAClutB() |
|||
{ |
|||
return this.CurveB != null |
|||
&& this.ClutValues != null |
|||
&& this.CurveA != null; |
|||
} |
|||
|
|||
private bool IsB() |
|||
{ |
|||
return this.CurveB != null; |
|||
} |
|||
|
|||
private void VerifyCurve(IccTagDataEntry[] curves, string name) |
|||
{ |
|||
if (curves != null) |
|||
{ |
|||
bool isNotCurve = curves.Any(t => !(t is IccParametricCurveTagDataEntry) && !(t is IccCurveTagDataEntry)); |
|||
Guard.IsTrue(isNotCurve, nameof(name), $"{nameof(name)} must be of type {nameof(IccParametricCurveTagDataEntry)} or {nameof(IccCurveTagDataEntry)}"); |
|||
} |
|||
} |
|||
|
|||
private void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) |
|||
{ |
|||
if (matrix3x1 != null) |
|||
{ |
|||
Guard.IsTrue(matrix3x1.Length != 3, nameof(matrix3x1), "Matrix must have a size of three"); |
|||
} |
|||
|
|||
if (matrix3x3 != null) |
|||
{ |
|||
bool isNot3By3 = matrix3x3.GetLength(0) != 3 || matrix3x3.GetLength(1) != 3; |
|||
Guard.IsTrue(isNot3By3, nameof(matrix3x3), "Matrix must have a size of three by three"); |
|||
} |
|||
} |
|||
|
|||
private Vector3? CreateMatrix3x1(float[] matrix) |
|||
{ |
|||
if (matrix == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return new Vector3(matrix[0], matrix[1], matrix[2]); |
|||
} |
|||
|
|||
private Matrix4x4? CreateMatrix3x3(float[,] matrix) |
|||
{ |
|||
if (matrix == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return new Matrix4x4( |
|||
matrix[0, 0], |
|||
matrix[0, 1], |
|||
matrix[0, 2], |
|||
0, |
|||
matrix[1, 0], |
|||
matrix[1, 1], |
|||
matrix[1, 2], |
|||
0, |
|||
matrix[2, 0], |
|||
matrix[2, 1], |
|||
matrix[2, 2], |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
1); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,274 @@ |
|||
// <copyright file="IccLutBToATagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// This structure represents a color transform.
|
|||
/// </summary>
|
|||
internal sealed class IccLutBToATagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLutBToATagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="curveA">A Curve</param>
|
|||
/// <param name="clutValues">CLUT</param>
|
|||
/// <param name="curveM">M Curve</param>
|
|||
/// <param name="matrix3x3">Two dimensional conversion matrix (3x3)</param>
|
|||
/// <param name="matrix3x1">One dimensional conversion matrix (3x1)</param>
|
|||
/// <param name="curveB">B Curve</param>
|
|||
public IccLutBToATagDataEntry( |
|||
IccTagDataEntry[] curveB, |
|||
float[,] matrix3x3, |
|||
float[] matrix3x1, |
|||
IccTagDataEntry[] curveM, |
|||
IccClut clutValues, |
|||
IccTagDataEntry[] curveA) |
|||
: this(curveB, matrix3x3, matrix3x1, curveM, clutValues, curveA, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLutBToATagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="curveA">A Curve</param>
|
|||
/// <param name="clutValues">CLUT</param>
|
|||
/// <param name="curveM">M Curve</param>
|
|||
/// <param name="matrix3x3">Two dimensional conversion matrix (3x3)</param>
|
|||
/// <param name="matrix3x1">One dimensional conversion matrix (3x1)</param>
|
|||
/// <param name="curveB">B Curve</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccLutBToATagDataEntry( |
|||
IccTagDataEntry[] curveB, |
|||
float[,] matrix3x3, |
|||
float[] matrix3x1, |
|||
IccTagDataEntry[] curveM, |
|||
IccClut clutValues, |
|||
IccTagDataEntry[] curveA, |
|||
IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.LutBToA, tagSignature) |
|||
{ |
|||
this.VerifyMatrix(matrix3x3, matrix3x1); |
|||
this.VerifyCurve(curveA, nameof(curveA)); |
|||
this.VerifyCurve(curveB, nameof(curveB)); |
|||
this.VerifyCurve(curveM, nameof(curveM)); |
|||
|
|||
this.Matrix3x3 = this.CreateMatrix3x3(matrix3x3); |
|||
this.Matrix3x1 = this.CreateMatrix3x1(matrix3x1); |
|||
this.CurveA = curveA; |
|||
this.CurveB = curveB; |
|||
this.CurveM = curveM; |
|||
this.ClutValues = clutValues; |
|||
|
|||
if (this.IsBMatrixMClutA()) |
|||
{ |
|||
Guard.IsTrue(this.CurveB.Length != 3, nameof(this.CurveB), $"{nameof(this.CurveB)} must have a length of three"); |
|||
Guard.IsTrue(this.CurveM.Length != 3, nameof(this.CurveM), $"{nameof(this.CurveM)} must have a length of three"); |
|||
Guard.MustBeBetweenOrEqualTo(this.CurveA.Length, 1, 15, nameof(this.CurveA)); |
|||
|
|||
this.InputChannelCount = 3; |
|||
this.OutputChannelCount = curveA.Length; |
|||
|
|||
Guard.IsTrue(this.InputChannelCount != clutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size"); |
|||
Guard.IsTrue(this.OutputChannelCount != clutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size"); |
|||
} |
|||
else if (this.IsBMatrixM()) |
|||
{ |
|||
Guard.IsTrue(this.CurveB.Length != 3, nameof(this.CurveB), $"{nameof(this.CurveB)} must have a length of three"); |
|||
Guard.IsTrue(this.CurveM.Length != 3, nameof(this.CurveM), $"{nameof(this.CurveM)} must have a length of three"); |
|||
|
|||
this.InputChannelCount = this.OutputChannelCount = 3; |
|||
} |
|||
else if (this.IsBClutA()) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(this.CurveA.Length, 1, 15, nameof(this.CurveA)); |
|||
Guard.MustBeBetweenOrEqualTo(this.CurveB.Length, 1, 15, nameof(this.CurveB)); |
|||
|
|||
this.InputChannelCount = curveB.Length; |
|||
this.OutputChannelCount = curveA.Length; |
|||
|
|||
Guard.IsTrue(this.InputChannelCount != clutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size"); |
|||
Guard.IsTrue(this.OutputChannelCount != clutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size"); |
|||
} |
|||
else if (this.IsB()) |
|||
{ |
|||
this.InputChannelCount = this.OutputChannelCount = this.CurveB.Length; |
|||
} |
|||
else |
|||
{ |
|||
throw new ArgumentException("Invalid combination of values given"); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of input channels
|
|||
/// </summary>
|
|||
public int InputChannelCount { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of output channels
|
|||
/// </summary>
|
|||
public int OutputChannelCount { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the two dimensional conversion matrix (3x3)
|
|||
/// </summary>
|
|||
public Matrix4x4? Matrix3x3 { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the one dimensional conversion matrix (3x1)
|
|||
/// </summary>
|
|||
public Vector3? Matrix3x1 { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the color lookup table
|
|||
/// </summary>
|
|||
public IccClut ClutValues { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the B Curve
|
|||
/// </summary>
|
|||
public IccTagDataEntry[] CurveB { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the M Curve
|
|||
/// </summary>
|
|||
public IccTagDataEntry[] CurveM { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the A Curve
|
|||
/// </summary>
|
|||
public IccTagDataEntry[] CurveA { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccLutBToATagDataEntry entry) |
|||
{ |
|||
return this.InputChannelCount == entry.InputChannelCount |
|||
&& this.OutputChannelCount == entry.OutputChannelCount |
|||
&& this.Matrix3x1 == entry.Matrix3x1 |
|||
&& this.Matrix3x3 == entry.Matrix3x3 |
|||
&& this.ClutValues == entry.ClutValues |
|||
&& this.EqualsCurve(this.CurveA, entry.CurveA) |
|||
&& this.EqualsCurve(this.CurveB, entry.CurveB) |
|||
&& this.EqualsCurve(this.CurveM, entry.CurveM); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
private bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCurves) |
|||
{ |
|||
bool thisNull = thisCurves == null; |
|||
bool entryNull = entryCurves == null; |
|||
|
|||
if (thisNull && entryNull) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
if (entryNull) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return thisCurves.SequenceEqual(entryCurves); |
|||
} |
|||
|
|||
private bool IsBMatrixMClutA() |
|||
{ |
|||
return this.CurveB != null |
|||
&& this.Matrix3x3 != null |
|||
&& this.Matrix3x1 != null |
|||
&& this.CurveM != null |
|||
&& this.ClutValues != null |
|||
&& this.CurveA != null; |
|||
} |
|||
|
|||
private bool IsBMatrixM() |
|||
{ |
|||
return this.CurveB != null |
|||
&& this.Matrix3x3 != null |
|||
&& this.Matrix3x1 != null |
|||
&& this.CurveM != null; |
|||
} |
|||
|
|||
private bool IsBClutA() |
|||
{ |
|||
return this.CurveB != null |
|||
&& this.ClutValues != null |
|||
&& this.CurveA != null; |
|||
} |
|||
|
|||
private bool IsB() |
|||
{ |
|||
return this.CurveB != null; |
|||
} |
|||
|
|||
private void VerifyCurve(IccTagDataEntry[] curves, string name) |
|||
{ |
|||
if (curves != null) |
|||
{ |
|||
bool isNotCurve = curves.Any(t => !(t is IccParametricCurveTagDataEntry) && !(t is IccCurveTagDataEntry)); |
|||
Guard.IsTrue(isNotCurve, nameof(name), $"{nameof(name)} must be of type {nameof(IccParametricCurveTagDataEntry)} or {nameof(IccCurveTagDataEntry)}"); |
|||
} |
|||
} |
|||
|
|||
private void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) |
|||
{ |
|||
if (matrix3x1 != null) |
|||
{ |
|||
Guard.IsTrue(matrix3x1.Length != 3, nameof(matrix3x1), "Matrix must have a size of three"); |
|||
} |
|||
|
|||
if (matrix3x3 != null) |
|||
{ |
|||
bool isNot3By3 = matrix3x3.GetLength(0) != 3 || matrix3x3.GetLength(1) != 3; |
|||
Guard.IsTrue(isNot3By3, nameof(matrix3x3), "Matrix must have a size of three by three"); |
|||
} |
|||
} |
|||
|
|||
private Vector3? CreateMatrix3x1(float[] matrix) |
|||
{ |
|||
if (matrix == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return new Vector3(matrix[0], matrix[1], matrix[2]); |
|||
} |
|||
|
|||
private Matrix4x4? CreateMatrix3x3(float[,] matrix) |
|||
{ |
|||
if (matrix == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return new Matrix4x4( |
|||
matrix[0, 0], |
|||
matrix[0, 1], |
|||
matrix[0, 2], |
|||
0, |
|||
matrix[1, 0], |
|||
matrix[1, 1], |
|||
matrix[1, 2], |
|||
0, |
|||
matrix[2, 0], |
|||
matrix[2, 1], |
|||
matrix[2, 2], |
|||
0, |
|||
0, |
|||
0, |
|||
0, |
|||
1); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,89 @@ |
|||
// <copyright file="IccMeasurementTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// The measurementType information refers only to the internal
|
|||
/// profile data and is meant to provide profile makers an alternative
|
|||
/// to the default measurement specifications.
|
|||
/// </summary>
|
|||
internal sealed class IccMeasurementTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccMeasurementTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="observer">Observer</param>
|
|||
/// <param name="xyzBacking">XYZ Backing values</param>
|
|||
/// <param name="geometry">Geometry</param>
|
|||
/// <param name="flare">Flare</param>
|
|||
/// <param name="illuminant">Illuminant</param>
|
|||
public IccMeasurementTagDataEntry(IccStandardObserver observer, Vector3 xyzBacking, IccMeasurementGeometry geometry, float flare, IccStandardIlluminant illuminant) |
|||
: this(observer, xyzBacking, geometry, flare, illuminant, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccMeasurementTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="observer">Observer</param>
|
|||
/// <param name="xyzBacking">XYZ Backing values</param>
|
|||
/// <param name="geometry">Geometry</param>
|
|||
/// <param name="flare">Flare</param>
|
|||
/// <param name="illuminant">Illuminant</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccMeasurementTagDataEntry(IccStandardObserver observer, Vector3 xyzBacking, IccMeasurementGeometry geometry, float flare, IccStandardIlluminant illuminant, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.Measurement, tagSignature) |
|||
{ |
|||
this.Observer = observer; |
|||
this.XyzBacking = xyzBacking; |
|||
this.Geometry = geometry; |
|||
this.Flare = flare; |
|||
this.Illuminant = illuminant; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the observer
|
|||
/// </summary>
|
|||
public IccStandardObserver Observer { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the XYZ Backing values
|
|||
/// </summary>
|
|||
public Vector3 XyzBacking { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the geometry
|
|||
/// </summary>
|
|||
public IccMeasurementGeometry Geometry { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the flare
|
|||
/// </summary>
|
|||
public float Flare { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the illuminant
|
|||
/// </summary>
|
|||
public IccStandardIlluminant Illuminant { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccMeasurementTagDataEntry entry) |
|||
{ |
|||
return this.Observer == entry.Observer |
|||
&& this.XyzBacking == entry.XyzBacking |
|||
&& this.Geometry == entry.Geometry |
|||
&& this.Flare == entry.Flare |
|||
&& this.Illuminant == entry.Illuminant; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
// <copyright file="IccMultiLocalizedUnicodeTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// This tag structure contains a set of records each referencing
|
|||
/// a multilingual string associated with a profile.
|
|||
/// </summary>
|
|||
internal sealed class IccMultiLocalizedUnicodeTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccMultiLocalizedUnicodeTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="texts">Localized Text</param>
|
|||
public IccMultiLocalizedUnicodeTagDataEntry(IccLocalizedString[] texts) |
|||
: this(texts, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccMultiLocalizedUnicodeTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="texts">Localized Text</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccMultiLocalizedUnicodeTagDataEntry(IccLocalizedString[] texts, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.MultiLocalizedUnicode, tagSignature) |
|||
{ |
|||
Guard.NotNull(texts, nameof(texts)); |
|||
this.Texts = texts; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the localized texts
|
|||
/// </summary>
|
|||
public IccLocalizedString[] Texts { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccMultiLocalizedUnicodeTagDataEntry entry) |
|||
{ |
|||
return this.Texts.SequenceEqual(entry.Texts); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,72 @@ |
|||
// <copyright file="IccMultiProcessElementsTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// This structure represents a color transform, containing
|
|||
/// a sequence of processing elements.
|
|||
/// </summary>
|
|||
internal sealed class IccMultiProcessElementsTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccMultiProcessElementsTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">Processing elements</param>
|
|||
public IccMultiProcessElementsTagDataEntry(IccMultiProcessElement[] data) |
|||
: this(data, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccMultiProcessElementsTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">Processing elements</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccMultiProcessElementsTagDataEntry(IccMultiProcessElement[] data, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.MultiProcessElements, tagSignature) |
|||
{ |
|||
Guard.NotNull(data, nameof(data)); |
|||
Guard.IsTrue(data.Length < 1, nameof(data), $"{nameof(data)} must have at least one element"); |
|||
|
|||
this.InputChannelCount = data[0].InputChannelCount; |
|||
this.OutputChannelCount = data[0].OutputChannelCount; |
|||
this.Data = data; |
|||
|
|||
bool channelsNotSame = data.Any(t => t.InputChannelCount != this.InputChannelCount || t.OutputChannelCount != this.OutputChannelCount); |
|||
Guard.IsTrue(channelsNotSame, nameof(data), "The number of input and output channels are not the same for all elements"); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of input channels
|
|||
/// </summary>
|
|||
public int InputChannelCount { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of output channels
|
|||
/// </summary>
|
|||
public int OutputChannelCount { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the processing elements
|
|||
/// </summary>
|
|||
public IccMultiProcessElement[] Data { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccMultiProcessElementsTagDataEntry entry) |
|||
{ |
|||
return this.InputChannelCount == entry.InputChannelCount |
|||
&& this.OutputChannelCount == entry.OutputChannelCount |
|||
&& this.Data.SequenceEqual(entry.Data); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,137 @@ |
|||
// <copyright file="IccNamedColor2TagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// The namedColor2Type is a count value and array of structures
|
|||
/// that provide color coordinates for color names.
|
|||
/// </summary>
|
|||
internal sealed class IccNamedColor2TagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccNamedColor2TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="colors">The named colors</param>
|
|||
public IccNamedColor2TagDataEntry(IccNamedColor[] colors) |
|||
: this(0, null, null, colors, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccNamedColor2TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="prefix">Prefix</param>
|
|||
/// <param name="suffix">Suffix</param>
|
|||
/// /// <param name="colors">The named colors</param>
|
|||
public IccNamedColor2TagDataEntry(string prefix, string suffix, IccNamedColor[] colors) |
|||
: this(0, prefix, suffix, colors, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccNamedColor2TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="vendorFlags">Vendor specific flags</param>
|
|||
/// <param name="prefix">Prefix</param>
|
|||
/// <param name="suffix">Suffix</param>
|
|||
/// <param name="colors">The named colors</param>
|
|||
public IccNamedColor2TagDataEntry(int vendorFlags, string prefix, string suffix, IccNamedColor[] colors) |
|||
: this(vendorFlags, prefix, suffix, colors, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccNamedColor2TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="colors">The named colors</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccNamedColor2TagDataEntry(IccNamedColor[] colors, IccProfileTag tagSignature) |
|||
: this(0, null, null, colors, tagSignature) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccNamedColor2TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="prefix">Prefix</param>
|
|||
/// <param name="suffix">Suffix</param>
|
|||
/// <param name="colors">The named colors</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccNamedColor2TagDataEntry(string prefix, string suffix, IccNamedColor[] colors, IccProfileTag tagSignature) |
|||
: this(0, prefix, suffix, colors, tagSignature) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccNamedColor2TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="vendorFlags">Vendor specific flags</param>
|
|||
/// <param name="prefix">Prefix</param>
|
|||
/// <param name="suffix">Suffix</param>
|
|||
/// <param name="colors">The named colors</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccNamedColor2TagDataEntry(int vendorFlags, string prefix, string suffix, IccNamedColor[] colors, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.NamedColor2, tagSignature) |
|||
{ |
|||
Guard.NotNull(colors, nameof(colors)); |
|||
|
|||
int coordinateCount = 0; |
|||
if (colors.Length > 0) |
|||
{ |
|||
coordinateCount = colors[0].DeviceCoordinates?.Length ?? 0; |
|||
Guard.IsTrue(colors.Any(t => (t.DeviceCoordinates?.Length ?? 0) != coordinateCount), nameof(colors), "Device coordinate count must be the same for all colors"); |
|||
} |
|||
|
|||
this.VendorFlags = vendorFlags; |
|||
this.CoordinateCount = coordinateCount; |
|||
this.Prefix = prefix; |
|||
this.Suffix = suffix; |
|||
this.Colors = colors; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of coordinates
|
|||
/// </summary>
|
|||
public int CoordinateCount { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the prefix
|
|||
/// </summary>
|
|||
public string Prefix { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the suffix
|
|||
/// </summary>
|
|||
public string Suffix { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the vendor specific flags
|
|||
/// </summary>
|
|||
public int VendorFlags { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the named colors
|
|||
/// </summary>
|
|||
public IccNamedColor[] Colors { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccNamedColor2TagDataEntry entry) |
|||
{ |
|||
return this.CoordinateCount == entry.CoordinateCount |
|||
&& this.Prefix == entry.Prefix |
|||
&& this.Suffix == entry.Suffix |
|||
&& this.VendorFlags == entry.VendorFlags |
|||
&& this.Colors.SequenceEqual(entry.Colors); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
// <copyright file="IccParametricCurveTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// The parametricCurveType describes a one-dimensional curve by
|
|||
/// specifying one of a predefined set of functions using the parameters.
|
|||
/// </summary>
|
|||
internal sealed class IccParametricCurveTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccParametricCurveTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="curve">The Curve</param>
|
|||
public IccParametricCurveTagDataEntry(IccParametricCurve curve) |
|||
: this(curve, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccParametricCurveTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="curve">The Curve</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccParametricCurveTagDataEntry(IccParametricCurve curve, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.ParametricCurve, tagSignature) |
|||
{ |
|||
this.Curve = curve; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the Curve
|
|||
/// </summary>
|
|||
public IccParametricCurve Curve { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccParametricCurveTagDataEntry entry) |
|||
{ |
|||
return this.Curve == entry.Curve; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
// <copyright file="IccProfileSequenceDescTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// This type is an array of structures, each of which contains information
|
|||
/// from the header fields and tags from the original profiles which were
|
|||
/// combined to create the final profile.
|
|||
/// </summary>
|
|||
internal sealed class IccProfileSequenceDescTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccProfileSequenceDescTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="descriptions">Profile Descriptions</param>
|
|||
public IccProfileSequenceDescTagDataEntry(IccProfileDescription[] descriptions) |
|||
: this(descriptions, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccProfileSequenceDescTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="descriptions">Profile Descriptions</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccProfileSequenceDescTagDataEntry(IccProfileDescription[] descriptions, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.ProfileSequenceDesc, tagSignature) |
|||
{ |
|||
Guard.NotNull(descriptions, nameof(descriptions)); |
|||
this.Descriptions = descriptions; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the profile descriptions
|
|||
/// </summary>
|
|||
public IccProfileDescription[] Descriptions { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccProfileSequenceDescTagDataEntry entry) |
|||
{ |
|||
return this.Descriptions.SequenceEqual(entry.Descriptions); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
// <copyright file="IccProfileSequenceIdentifierTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// This type is an array of structures, each of which contains information
|
|||
/// for identification of a profile used in a sequence.
|
|||
/// </summary>
|
|||
internal sealed class IccProfileSequenceIdentifierTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccProfileSequenceIdentifierTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">Profile Identifiers</param>
|
|||
public IccProfileSequenceIdentifierTagDataEntry(IccProfileSequenceIdentifier[] data) |
|||
: this(data, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccProfileSequenceIdentifierTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">Profile Identifiers</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccProfileSequenceIdentifierTagDataEntry(IccProfileSequenceIdentifier[] data, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.ProfileSequenceIdentifier, tagSignature) |
|||
{ |
|||
Guard.NotNull(data, nameof(data)); |
|||
this.Data = data; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the profile identifiers
|
|||
/// </summary>
|
|||
public IccProfileSequenceIdentifier[] Data { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccProfileSequenceIdentifierTagDataEntry entry) |
|||
{ |
|||
return this.Data.SequenceEqual(entry.Data); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,66 @@ |
|||
// <copyright file="IccResponseCurveSet16TagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// The purpose of this tag type is to provide a mechanism to relate physical
|
|||
/// colorant amounts with the normalized device codes produced by lut8Type, lut16Type,
|
|||
/// lutAToBType, lutBToAType or multiProcessElementsType tags so that corrections can
|
|||
/// be made for variation in the device without having to produce a new profile.
|
|||
/// </summary>
|
|||
internal sealed class IccResponseCurveSet16TagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccResponseCurveSet16TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="curves">The Curves</param>
|
|||
public IccResponseCurveSet16TagDataEntry(IccResponseCurve[] curves) |
|||
: this(curves, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccResponseCurveSet16TagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="curves">The Curves</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccResponseCurveSet16TagDataEntry(IccResponseCurve[] curves, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.ResponseCurveSet16, tagSignature) |
|||
{ |
|||
Guard.NotNull(curves, nameof(curves)); |
|||
Guard.IsTrue(curves.Length < 1, nameof(curves), $"{nameof(curves)} needs at least one element"); |
|||
|
|||
this.Curves = curves; |
|||
this.ChannelCount = (ushort)curves[0].ResponseArrays.Length; |
|||
|
|||
Guard.IsTrue(curves.Any(t => t.ResponseArrays.Length != this.ChannelCount), nameof(curves), "All curves need to have the same number of channels"); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of channels
|
|||
/// </summary>
|
|||
public ushort ChannelCount { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the curves
|
|||
/// </summary>
|
|||
public IccResponseCurve[] Curves { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccResponseCurveSet16TagDataEntry entry) |
|||
{ |
|||
return this.ChannelCount == entry.ChannelCount |
|||
&& this.Curves.SequenceEqual(entry.Curves); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
// <copyright file="IccSignatureTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Typically this type is used for registered tags that can
|
|||
/// be displayed on many development systems as a sequence of four characters.
|
|||
/// </summary>
|
|||
internal sealed class IccSignatureTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccSignatureTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="signatureData">The Signature</param>
|
|||
public IccSignatureTagDataEntry(string signatureData) |
|||
: this(signatureData, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccSignatureTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="signatureData">The Signature</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccSignatureTagDataEntry(string signatureData, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.Signature, tagSignature) |
|||
{ |
|||
Guard.NotNull(signatureData, nameof(signatureData)); |
|||
this.SignatureData = signatureData; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the Signature
|
|||
/// </summary>
|
|||
public string SignatureData { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccSignatureTagDataEntry entry) |
|||
{ |
|||
return this.SignatureData == entry.SignatureData; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,85 @@ |
|||
// <copyright file="IccTextDescriptionTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// The TextDescriptionType contains three types of text description.
|
|||
/// </summary>
|
|||
internal sealed class IccTextDescriptionTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccTextDescriptionTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="ascii">ASCII text</param>
|
|||
/// <param name="unicode">Unicode text</param>
|
|||
/// <param name="scriptCode">ScriptCode text</param>
|
|||
/// <param name="unicodeLanguageCode">Unicode Language-Code</param>
|
|||
/// <param name="scriptCodeCode">ScriptCode Code</param>
|
|||
public IccTextDescriptionTagDataEntry(string ascii, string unicode, string scriptCode, uint unicodeLanguageCode, ushort scriptCodeCode) |
|||
: this(ascii, unicode, scriptCode, unicodeLanguageCode, scriptCodeCode, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccTextDescriptionTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="ascii">ASCII text</param>
|
|||
/// <param name="unicode">Unicode text</param>
|
|||
/// <param name="scriptCode">ScriptCode text</param>
|
|||
/// <param name="unicodeLanguageCode">Unicode Language-Code</param>
|
|||
/// <param name="scriptCodeCode">ScriptCode Code</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccTextDescriptionTagDataEntry(string ascii, string unicode, string scriptCode, uint unicodeLanguageCode, ushort scriptCodeCode, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.TextDescription, tagSignature) |
|||
{ |
|||
this.Ascii = ascii; |
|||
this.Unicode = unicode; |
|||
this.ScriptCode = scriptCode; |
|||
this.UnicodeLanguageCode = unicodeLanguageCode; |
|||
this.ScriptCodeCode = scriptCodeCode; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the ASCII text
|
|||
/// </summary>
|
|||
public string Ascii { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the Unicode text
|
|||
/// </summary>
|
|||
public string Unicode { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the ScriptCode text
|
|||
/// </summary>
|
|||
public string ScriptCode { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the Unicode Language-Code
|
|||
/// </summary>
|
|||
public uint UnicodeLanguageCode { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the ScriptCode Code
|
|||
/// </summary>
|
|||
public ushort ScriptCodeCode { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccTextDescriptionTagDataEntry entry) |
|||
{ |
|||
return this.Ascii == entry.Ascii |
|||
&& this.Unicode == entry.Unicode |
|||
&& this.ScriptCode == entry.ScriptCode |
|||
&& this.UnicodeLanguageCode == entry.UnicodeLanguageCode |
|||
&& this.ScriptCodeCode == entry.ScriptCodeCode; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
// <copyright file="IccTextTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// This is a simple text structure that contains a text string.
|
|||
/// </summary>
|
|||
internal sealed class IccTextTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccTextTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="text">The Text</param>
|
|||
public IccTextTagDataEntry(string text) |
|||
: this(text, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccTextTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="text">The Text</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccTextTagDataEntry(string text, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.Text, tagSignature) |
|||
{ |
|||
Guard.NotNull(text, nameof(text)); |
|||
this.Text = text; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the Text
|
|||
/// </summary>
|
|||
public string Text { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccTextTagDataEntry entry) |
|||
{ |
|||
return this.Text == entry.Text; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
// <copyright file="IccUFix16ArrayTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// This type represents an array of doubles (from 32bit values).
|
|||
/// </summary>
|
|||
internal sealed class IccUFix16ArrayTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccUFix16ArrayTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The array data</param>
|
|||
public IccUFix16ArrayTagDataEntry(float[] data) |
|||
: this(data, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccUFix16ArrayTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The array data</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccUFix16ArrayTagDataEntry(float[] data, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.U16Fixed16Array, tagSignature) |
|||
{ |
|||
Guard.NotNull(data, nameof(data)); |
|||
this.Data = data; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the array data
|
|||
/// </summary>
|
|||
public float[] Data { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccUFix16ArrayTagDataEntry entry) |
|||
{ |
|||
return this.Data.SequenceEqual(entry.Data); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
// <copyright file="IccUInt16ArrayTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// This type represents an array of unsigned shorts.
|
|||
/// </summary>
|
|||
internal sealed class IccUInt16ArrayTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccUInt16ArrayTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The array data</param>
|
|||
public IccUInt16ArrayTagDataEntry(ushort[] data) |
|||
: this(data, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccUInt16ArrayTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The array data</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccUInt16ArrayTagDataEntry(ushort[] data, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.UInt16Array, tagSignature) |
|||
{ |
|||
Guard.NotNull(data, nameof(data)); |
|||
this.Data = data; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the array data
|
|||
/// </summary>
|
|||
public ushort[] Data { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccUInt16ArrayTagDataEntry entry) |
|||
{ |
|||
return this.Data.SequenceEqual(entry.Data); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
// <copyright file="IccUInt32ArrayTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// This type represents an array of unsigned 32bit integers.
|
|||
/// </summary>
|
|||
internal sealed class IccUInt32ArrayTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccUInt32ArrayTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The array data</param>
|
|||
public IccUInt32ArrayTagDataEntry(uint[] data) |
|||
: this(data, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccUInt32ArrayTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The array data</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccUInt32ArrayTagDataEntry(uint[] data, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.UInt32Array, tagSignature) |
|||
{ |
|||
Guard.NotNull(data, nameof(data)); |
|||
this.Data = data; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the array data
|
|||
/// </summary>
|
|||
public uint[] Data { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccUInt32ArrayTagDataEntry entry) |
|||
{ |
|||
return this.Data.SequenceEqual(entry.Data); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
// <copyright file="IccUInt64ArrayTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// This type represents an array of unsigned 64bit integers.
|
|||
/// </summary>
|
|||
internal sealed class IccUInt64ArrayTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccUInt64ArrayTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The array data</param>
|
|||
public IccUInt64ArrayTagDataEntry(ulong[] data) |
|||
: this(data, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccUInt64ArrayTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The array data</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccUInt64ArrayTagDataEntry(ulong[] data, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.UInt64Array, tagSignature) |
|||
{ |
|||
Guard.NotNull(data, nameof(data)); |
|||
this.Data = data; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the array data
|
|||
/// </summary>
|
|||
public ulong[] Data { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccUInt64ArrayTagDataEntry entry) |
|||
{ |
|||
return this.Data.SequenceEqual(entry.Data); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
// <copyright file="IccUInt8ArrayTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// This type represents an array of bytes.
|
|||
/// </summary>
|
|||
internal sealed class IccUInt8ArrayTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccUInt8ArrayTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The array data</param>
|
|||
public IccUInt8ArrayTagDataEntry(byte[] data) |
|||
: this(data, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccUInt8ArrayTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The array data</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccUInt8ArrayTagDataEntry(byte[] data, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.UInt8Array, tagSignature) |
|||
{ |
|||
Guard.NotNull(data, nameof(data)); |
|||
this.Data = data; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the array data
|
|||
/// </summary>
|
|||
public byte[] Data { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccUInt8ArrayTagDataEntry entry) |
|||
{ |
|||
return this.Data.SequenceEqual(entry.Data); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
// <copyright file="IccUnknownTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// This tag stores data of an unknown tag data entry
|
|||
/// </summary>
|
|||
internal sealed class IccUnknownTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccUnknownTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The raw data of the entry</param>
|
|||
public IccUnknownTagDataEntry(byte[] data) |
|||
: this(data, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccUnknownTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The raw data of the entry</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccUnknownTagDataEntry(byte[] data, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.Unknown, tagSignature) |
|||
{ |
|||
Guard.NotNull(data, nameof(data)); |
|||
this.Data = data; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the raw data of the entry
|
|||
/// </summary>
|
|||
public byte[] Data { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccUnknownTagDataEntry entry) |
|||
{ |
|||
return this.Data.SequenceEqual(entry.Data); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,69 @@ |
|||
// <copyright file="IccViewingConditionsTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// This type represents a set of viewing condition parameters.
|
|||
/// </summary>
|
|||
internal sealed class IccViewingConditionsTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccViewingConditionsTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="illuminantXyz">XYZ values of Illuminant</param>
|
|||
/// <param name="surroundXyz">XYZ values of Surrounding</param>
|
|||
/// <param name="illuminant">Illuminant</param>
|
|||
public IccViewingConditionsTagDataEntry(Vector3 illuminantXyz, Vector3 surroundXyz, IccStandardIlluminant illuminant) |
|||
: this(illuminantXyz, surroundXyz, illuminant, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccViewingConditionsTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="illuminantXyz">XYZ values of Illuminant</param>
|
|||
/// <param name="surroundXyz">XYZ values of Surrounding</param>
|
|||
/// <param name="illuminant">Illuminant</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccViewingConditionsTagDataEntry(Vector3 illuminantXyz, Vector3 surroundXyz, IccStandardIlluminant illuminant, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.ViewingConditions, tagSignature) |
|||
{ |
|||
this.IlluminantXyz = illuminantXyz; |
|||
this.SurroundXyz = surroundXyz; |
|||
this.Illuminant = illuminant; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the XYZ values of Illuminant
|
|||
/// </summary>
|
|||
public Vector3 IlluminantXyz { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the XYZ values of Surrounding
|
|||
/// </summary>
|
|||
public Vector3 SurroundXyz { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the illuminant
|
|||
/// </summary>
|
|||
public IccStandardIlluminant Illuminant { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccViewingConditionsTagDataEntry entry) |
|||
{ |
|||
return this.IlluminantXyz == entry.IlluminantXyz |
|||
&& this.SurroundXyz == entry.SurroundXyz |
|||
&& this.Illuminant == entry.Illuminant; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
// <copyright file="IccXyzTagDataEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// The XYZType contains an array of XYZ values.
|
|||
/// </summary>
|
|||
internal sealed class IccXyzTagDataEntry : IccTagDataEntry |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccXyzTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The XYZ numbers</param>
|
|||
public IccXyzTagDataEntry(Vector3[] data) |
|||
: this(data, IccProfileTag.Unknown) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccXyzTagDataEntry"/> class.
|
|||
/// </summary>
|
|||
/// <param name="data">The XYZ numbers</param>
|
|||
/// <param name="tagSignature">Tag Signature</param>
|
|||
public IccXyzTagDataEntry(Vector3[] data, IccProfileTag tagSignature) |
|||
: base(IccTypeSignature.Xyz, tagSignature) |
|||
{ |
|||
Guard.NotNull(data, nameof(data)); |
|||
this.Data = data; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the XYZ numbers
|
|||
/// </summary>
|
|||
public Vector3[] Data { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(IccTagDataEntry other) |
|||
{ |
|||
if (base.Equals(other) && other is IccXyzTagDataEntry entry) |
|||
{ |
|||
return this.Data.SequenceEqual(entry.Data); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,175 @@ |
|||
// <copyright file="IccClut.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// Color Lookup Table
|
|||
/// </summary>
|
|||
internal sealed class IccClut : IEquatable<IccClut> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccClut"/> class.
|
|||
/// </summary>
|
|||
/// <param name="values">The CLUT values</param>
|
|||
/// <param name="gridPointCount">The gridpoint count</param>
|
|||
/// <param name="type">The data type of this CLUT</param>
|
|||
public IccClut(float[][] values, byte[] gridPointCount, IccClutDataType type) |
|||
{ |
|||
Guard.NotNull(values, nameof(values)); |
|||
Guard.NotNull(gridPointCount, nameof(gridPointCount)); |
|||
|
|||
this.Values = values; |
|||
this.DataType = IccClutDataType.Float; |
|||
this.InputChannelCount = gridPointCount.Length; |
|||
this.OutputChannelCount = values[0].Length; |
|||
this.GridPointCount = gridPointCount; |
|||
this.CheckValues(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccClut"/> class.
|
|||
/// </summary>
|
|||
/// <param name="values">The CLUT values</param>
|
|||
/// <param name="gridPointCount">The gridpoint count</param>
|
|||
public IccClut(ushort[][] values, byte[] gridPointCount) |
|||
{ |
|||
Guard.NotNull(values, nameof(values)); |
|||
Guard.NotNull(gridPointCount, nameof(gridPointCount)); |
|||
|
|||
const float max = ushort.MaxValue; |
|||
|
|||
this.Values = new float[values.Length][]; |
|||
for (int i = 0; i < values.Length; i++) |
|||
{ |
|||
this.Values[i] = new float[values[i].Length]; |
|||
for (int j = 0; j < values[i].Length; j++) |
|||
{ |
|||
this.Values[i][j] = values[i][j] / max; |
|||
} |
|||
} |
|||
|
|||
this.DataType = IccClutDataType.UInt16; |
|||
this.InputChannelCount = gridPointCount.Length; |
|||
this.OutputChannelCount = values[0].Length; |
|||
this.GridPointCount = gridPointCount; |
|||
this.CheckValues(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccClut"/> class.
|
|||
/// </summary>
|
|||
/// <param name="values">The CLUT values</param>
|
|||
/// <param name="gridPointCount">The gridpoint count</param>
|
|||
public IccClut(byte[][] values, byte[] gridPointCount) |
|||
{ |
|||
Guard.NotNull(values, nameof(values)); |
|||
Guard.NotNull(gridPointCount, nameof(gridPointCount)); |
|||
|
|||
const float max = byte.MaxValue; |
|||
|
|||
this.Values = new float[values.Length][]; |
|||
for (int i = 0; i < values.Length; i++) |
|||
{ |
|||
this.Values[i] = new float[values[i].Length]; |
|||
for (int j = 0; j < values[i].Length; j++) |
|||
{ |
|||
this.Values[i][j] = values[i][j] / max; |
|||
} |
|||
} |
|||
|
|||
this.DataType = IccClutDataType.UInt8; |
|||
this.InputChannelCount = gridPointCount.Length; |
|||
this.OutputChannelCount = values[0].Length; |
|||
this.GridPointCount = gridPointCount; |
|||
this.CheckValues(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the values that make up this table
|
|||
/// </summary>
|
|||
public float[][] Values { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the CLUT data type (important when writing a profile)
|
|||
/// </summary>
|
|||
public IccClutDataType DataType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of input channels
|
|||
/// </summary>
|
|||
public int InputChannelCount { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of output channels
|
|||
/// </summary>
|
|||
public int OutputChannelCount { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of grid points per input channel
|
|||
/// </summary>
|
|||
public byte[] GridPointCount { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(IccClut other) |
|||
{ |
|||
if (other == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return this.DataType == other.DataType |
|||
&& this.InputChannelCount == other.InputChannelCount |
|||
&& this.OutputChannelCount == other.OutputChannelCount |
|||
&& this.GridPointCount.SequenceEqual(other.GridPointCount) |
|||
&& this.EqualsValuesArray(other); |
|||
} |
|||
|
|||
private bool EqualsValuesArray(IccClut other) |
|||
{ |
|||
if (this.Values.Length != other.Values.Length) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
for (int i = 0; i < this.Values.Length; i++) |
|||
{ |
|||
if (!this.Values[i].SequenceEqual(other.Values[i])) |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
private void CheckValues() |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(this.InputChannelCount, 1, 15, nameof(this.InputChannelCount)); |
|||
Guard.MustBeBetweenOrEqualTo(this.OutputChannelCount, 1, 15, nameof(this.OutputChannelCount)); |
|||
|
|||
bool isLengthDifferent = this.Values.Any(t => t.Length != this.OutputChannelCount); |
|||
Guard.IsTrue(isLengthDifferent, nameof(this.Values), "The number of output values varies"); |
|||
|
|||
int length = 0; |
|||
for (int i = 0; i < this.InputChannelCount; i++) |
|||
{ |
|||
length += (int)Math.Pow(this.GridPointCount[i], this.InputChannelCount); |
|||
} |
|||
|
|||
length /= this.InputChannelCount; |
|||
|
|||
Guard.IsTrue(this.Values.Length != length, nameof(this.Values), "Length of values array does not match the grid points"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,125 @@ |
|||
// <copyright file="IccColorantTableEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// Entry of ICC colorant table
|
|||
/// </summary>
|
|||
internal struct IccColorantTableEntry : IEquatable<IccColorantTableEntry> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccColorantTableEntry"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="name">Name of the colorant</param>
|
|||
public IccColorantTableEntry(string name) |
|||
: this(name, 0, 0, 0) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccColorantTableEntry"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="name">Name of the colorant</param>
|
|||
/// <param name="pcs1">First PCS value</param>
|
|||
/// <param name="pcs2">Second PCS value</param>
|
|||
/// <param name="pcs3">Third PCS value</param>
|
|||
public IccColorantTableEntry(string name, ushort pcs1, ushort pcs2, ushort pcs3) |
|||
{ |
|||
Guard.NotNull(name, nameof(name)); |
|||
|
|||
this.Name = name; |
|||
this.Pcs1 = pcs1; |
|||
this.Pcs2 = pcs2; |
|||
this.Pcs3 = pcs3; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the colorant name
|
|||
/// </summary>
|
|||
public string Name { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the first PCS value
|
|||
/// </summary>
|
|||
public ushort Pcs1 { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the second PCS value
|
|||
/// </summary>
|
|||
public ushort Pcs2 { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the third PCS value
|
|||
/// </summary>
|
|||
public ushort Pcs3 { get; } |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="IccColorantTableEntry"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="IccColorantTableEntry"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="IccColorantTableEntry"/> on the right side of the operand.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator ==(IccColorantTableEntry left, IccColorantTableEntry right) |
|||
{ |
|||
return left.Equals(right); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="IccColorantTableEntry"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="IccColorantTableEntry"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="IccColorantTableEntry"/> on the right side of the operand.</param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator !=(IccColorantTableEntry left, IccColorantTableEntry right) |
|||
{ |
|||
return !left.Equals(right); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object other) |
|||
{ |
|||
return (other is IccColorantTableEntry) && this.Equals((IccColorantTableEntry)other); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(IccColorantTableEntry other) |
|||
{ |
|||
return this.Name == other.Name |
|||
&& this.Pcs1 == other.Pcs1 |
|||
&& this.Pcs2 == other.Pcs2 |
|||
&& this.Pcs3 == other.Pcs3; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() |
|||
{ |
|||
unchecked |
|||
{ |
|||
int hashCode = this.Name.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ this.Pcs1.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ this.Pcs2.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ this.Pcs3.GetHashCode(); |
|||
return hashCode; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
{ |
|||
return $"{this.Name}: {this.Pcs1}; {this.Pcs2}; {this.Pcs3}"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,69 @@ |
|||
// <copyright file="IccLocalizedString.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
/// <summary>
|
|||
/// A string with a specific locale
|
|||
/// </summary>
|
|||
internal sealed class IccLocalizedString : IEquatable<IccLocalizedString> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLocalizedString"/> class.
|
|||
/// The culture will be <see cref="CultureInfo.CurrentCulture"/>
|
|||
/// </summary>
|
|||
/// <param name="text">The text value of this string</param>
|
|||
public IccLocalizedString(string text) |
|||
: this(CultureInfo.CurrentCulture, text) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLocalizedString"/> class.
|
|||
/// The culture will be <see cref="CultureInfo.CurrentCulture"/>
|
|||
/// </summary>
|
|||
/// <param name="culture">The culture of this string</param>
|
|||
/// <param name="text">The text value of this string</param>
|
|||
public IccLocalizedString(CultureInfo culture, string text) |
|||
{ |
|||
Guard.NotNull(culture, nameof(culture)); |
|||
Guard.NotNull(text, nameof(text)); |
|||
|
|||
this.Culture = culture; |
|||
this.Text = text; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the actual text value
|
|||
/// </summary>
|
|||
public string Text { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the culture of the text
|
|||
/// </summary>
|
|||
public CultureInfo Culture { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public bool Equals(IccLocalizedString other) |
|||
{ |
|||
if (ReferenceEquals(this, other)) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return this.Culture.Equals(other.Culture) |
|||
&& this.Text == other.Text; |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public override string ToString() |
|||
{ |
|||
return $"{this.Culture.Name}: {this.Text}"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
// <copyright file="IccLut.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// Lookup Table
|
|||
/// </summary>
|
|||
internal sealed class IccLut : IEquatable<IccLut> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLut"/> class.
|
|||
/// </summary>
|
|||
/// <param name="values">The LUT values</param>
|
|||
public IccLut(float[] values) |
|||
{ |
|||
Guard.NotNull(values, nameof(values)); |
|||
this.Values = values; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLut"/> class.
|
|||
/// </summary>
|
|||
/// <param name="values">The LUT values</param>
|
|||
public IccLut(ushort[] values) |
|||
{ |
|||
Guard.NotNull(values, nameof(values)); |
|||
|
|||
const float max = ushort.MaxValue; |
|||
|
|||
this.Values = new float[values.Length]; |
|||
for (int i = 0; i < values.Length; i++) |
|||
{ |
|||
this.Values[i] = values[i] / max; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccLut"/> class.
|
|||
/// </summary>
|
|||
/// <param name="values">The LUT values</param>
|
|||
public IccLut(byte[] values) |
|||
{ |
|||
Guard.NotNull(values, nameof(values)); |
|||
|
|||
const float max = byte.MaxValue; |
|||
|
|||
this.Values = new float[values.Length]; |
|||
for (int i = 0; i < values.Length; i++) |
|||
{ |
|||
this.Values[i] = values[i] / max; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the values that make up this table
|
|||
/// </summary>
|
|||
public float[] Values { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(IccLut other) |
|||
{ |
|||
if (other == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return this.Values.SequenceEqual(other.Values); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,110 @@ |
|||
// <copyright file="IccNamedColor.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// A specific color with a name
|
|||
/// </summary>
|
|||
internal struct IccNamedColor : IEquatable<IccNamedColor> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccNamedColor"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="name">Name of the color</param>
|
|||
/// <param name="pcsCoordinates">Coordinates of the color in the profiles PCS</param>
|
|||
/// <param name="deviceCoordinates">Coordinates of the color in the profiles Device-Space</param>
|
|||
public IccNamedColor(string name, ushort[] pcsCoordinates, ushort[] deviceCoordinates) |
|||
{ |
|||
Guard.NotNull(name, nameof(name)); |
|||
Guard.NotNull(pcsCoordinates, nameof(pcsCoordinates)); |
|||
Guard.IsTrue(pcsCoordinates.Length != 3, nameof(pcsCoordinates), "Must have a length of 3"); |
|||
|
|||
this.Name = name; |
|||
this.PcsCoordinates = pcsCoordinates; |
|||
this.DeviceCoordinates = deviceCoordinates; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the name of the color
|
|||
/// </summary>
|
|||
public string Name { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the coordinates of the color in the profiles PCS
|
|||
/// </summary>
|
|||
public ushort[] PcsCoordinates { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the coordinates of the color in the profiles Device-Space
|
|||
/// </summary>
|
|||
public ushort[] DeviceCoordinates { get; } |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="IccNamedColor"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="IccNamedColor"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="IccNamedColor"/> on the right side of the operand.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator ==(IccNamedColor left, IccNamedColor right) |
|||
{ |
|||
return left.Equals(right); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="IccNamedColor"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="IccNamedColor"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="IccNamedColor"/> on the right side of the operand.</param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator !=(IccNamedColor left, IccNamedColor right) |
|||
{ |
|||
return !left.Equals(right); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object other) |
|||
{ |
|||
return (other is IccNamedColor) && this.Equals((IccNamedColor)other); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(IccNamedColor other) |
|||
{ |
|||
return this.Name == other.Name |
|||
&& this.PcsCoordinates.SequenceEqual(other.PcsCoordinates) |
|||
&& this.DeviceCoordinates.SequenceEqual(other.DeviceCoordinates); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() |
|||
{ |
|||
unchecked |
|||
{ |
|||
int hashCode = this.Name.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ this.PcsCoordinates.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ this.DeviceCoordinates.GetHashCode(); |
|||
return hashCode; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
{ |
|||
return this.Name; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,91 @@ |
|||
// <copyright file="IccPositionNumber.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// Position of an object within an ICC profile
|
|||
/// </summary>
|
|||
internal struct IccPositionNumber : IEquatable<IccPositionNumber> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccPositionNumber"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="offset">Offset in bytes</param>
|
|||
/// <param name="size">Size in bytes</param>
|
|||
public IccPositionNumber(uint offset, uint size) |
|||
{ |
|||
this.Offset = offset; |
|||
this.Size = size; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the offset in bytes
|
|||
/// </summary>
|
|||
public uint Offset { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the size in bytes
|
|||
/// </summary>
|
|||
public uint Size { get; } |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="IccPositionNumber"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="IccPositionNumber"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="IccPositionNumber"/> on the right side of the operand.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator ==(IccPositionNumber left, IccPositionNumber right) |
|||
{ |
|||
return left.Equals(right); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="IccPositionNumber"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="IccPositionNumber"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="IccPositionNumber"/> on the right side of the operand.</param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator !=(IccPositionNumber left, IccPositionNumber right) |
|||
{ |
|||
return !left.Equals(right); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object other) |
|||
{ |
|||
return (other is IccPositionNumber) && this.Equals((IccPositionNumber)other); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(IccPositionNumber other) |
|||
{ |
|||
return this.Offset == other.Offset |
|||
&& this.Size == other.Size; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() |
|||
{ |
|||
return unchecked((int)(this.Offset ^ this.Size)); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
{ |
|||
return $"{this.Offset}; {this.Size}"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
// <copyright file="IccProfileDescription.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// ICC Profile description
|
|||
/// </summary>
|
|||
internal sealed class IccProfileDescription : IEquatable<IccProfileDescription> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccProfileDescription"/> class.
|
|||
/// </summary>
|
|||
/// <param name="deviceManufacturer">Device Manufacturer</param>
|
|||
/// <param name="deviceModel">Device Model</param>
|
|||
/// <param name="deviceAttributes">Device Attributes</param>
|
|||
/// <param name="technologyInformation">Technology Information</param>
|
|||
/// <param name="deviceManufacturerInfo">Device Manufacturer Info</param>
|
|||
/// <param name="deviceModelInfo">Device Model Info</param>
|
|||
public IccProfileDescription( |
|||
uint deviceManufacturer, |
|||
uint deviceModel, |
|||
IccDeviceAttribute deviceAttributes, |
|||
IccProfileTag technologyInformation, |
|||
IccLocalizedString[] deviceManufacturerInfo, |
|||
IccLocalizedString[] deviceModelInfo) |
|||
{ |
|||
Guard.NotNull(deviceManufacturerInfo, nameof(deviceManufacturerInfo)); |
|||
Guard.NotNull(deviceModelInfo, nameof(deviceModelInfo)); |
|||
|
|||
this.DeviceManufacturer = deviceManufacturer; |
|||
this.DeviceModel = deviceModel; |
|||
this.DeviceAttributes = deviceAttributes; |
|||
this.TechnologyInformation = technologyInformation; |
|||
this.DeviceManufacturerInfo = deviceManufacturerInfo; |
|||
this.DeviceModelInfo = deviceModelInfo; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the device manufacturer
|
|||
/// </summary>
|
|||
public uint DeviceManufacturer { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the device model
|
|||
/// </summary>
|
|||
public uint DeviceModel { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the device attributes
|
|||
/// </summary>
|
|||
public IccDeviceAttribute DeviceAttributes { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the technology information
|
|||
/// </summary>
|
|||
public IccProfileTag TechnologyInformation { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the device manufacturer info
|
|||
/// </summary>
|
|||
public IccLocalizedString[] DeviceManufacturerInfo { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the device model info
|
|||
/// </summary>
|
|||
public IccLocalizedString[] DeviceModelInfo { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public bool Equals(IccProfileDescription other) |
|||
{ |
|||
if (ReferenceEquals(this, other)) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return this.DeviceManufacturer == other.DeviceManufacturer |
|||
&& this.DeviceModel == other.DeviceModel |
|||
&& this.DeviceAttributes == other.DeviceAttributes |
|||
&& this.TechnologyInformation == other.TechnologyInformation |
|||
&& this.DeviceManufacturerInfo.SequenceEqual(other.DeviceManufacturerInfo) |
|||
&& this.DeviceModelInfo.SequenceEqual(other.DeviceModelInfo); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,138 @@ |
|||
// <copyright file="IccProfileId.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// ICC Profile ID
|
|||
/// </summary>
|
|||
internal struct IccProfileId : IEquatable<IccProfileId> |
|||
{ |
|||
/// <summary>
|
|||
/// A profile ID with all values set to zero
|
|||
/// </summary>
|
|||
public static readonly IccProfileId Zero = new IccProfileId(0, 0, 0, 0); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccProfileId"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="p1">Part 1 of the ID</param>
|
|||
/// <param name="p2">Part 2 of the ID</param>
|
|||
/// <param name="p3">Part 3 of the ID</param>
|
|||
/// <param name="p4">Part 4 of the ID</param>
|
|||
public IccProfileId(uint p1, uint p2, uint p3, uint p4) |
|||
{ |
|||
this.Part1 = p1; |
|||
this.Part2 = p2; |
|||
this.Part3 = p3; |
|||
this.Part4 = p4; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the first part of the ID
|
|||
/// </summary>
|
|||
public uint Part1 { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the second part of the ID
|
|||
/// </summary>
|
|||
public uint Part2 { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the third part of the ID
|
|||
/// </summary>
|
|||
public uint Part3 { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the fourth part of the ID
|
|||
/// </summary>
|
|||
public uint Part4 { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether the ID is set or just consists of zeros
|
|||
/// </summary>
|
|||
public bool IsSet |
|||
{ |
|||
get |
|||
{ |
|||
return this.Part1 != 0 |
|||
&& this.Part2 != 0 |
|||
&& this.Part3 != 0 |
|||
&& this.Part4 != 0; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="IccProfileId"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="IccProfileId"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="IccProfileId"/> on the right side of the operand.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator ==(IccProfileId left, IccProfileId right) |
|||
{ |
|||
return left.Equals(right); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="IccProfileId"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="IccProfileId"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="IccProfileId"/> on the right side of the operand.</param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator !=(IccProfileId left, IccProfileId right) |
|||
{ |
|||
return !left.Equals(right); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object other) |
|||
{ |
|||
return (other is IccProfileId) && this.Equals((IccProfileId)other); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(IccProfileId other) |
|||
{ |
|||
return this.Part1 == other.Part1 |
|||
&& this.Part2 == other.Part2 |
|||
&& this.Part3 == other.Part3 |
|||
&& this.Part4 == other.Part4; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() |
|||
{ |
|||
unchecked |
|||
{ |
|||
int hashCode = this.Part1.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ this.Part2.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ this.Part3.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ this.Part4.GetHashCode(); |
|||
return hashCode; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
{ |
|||
return $"{ToHex(this.Part1)}-{ToHex(this.Part2)}-{ToHex(this.Part3)}-{ToHex(this.Part4)}"; |
|||
} |
|||
|
|||
private static string ToHex(uint value) |
|||
{ |
|||
return value.ToString("X").PadLeft(8, '0'); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
// <copyright file="IccProfileSequenceIdentifier.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
|
|||
/// <summary>
|
|||
/// Description of a profile within a sequence
|
|||
/// </summary>
|
|||
internal sealed class IccProfileSequenceIdentifier : IEquatable<IccProfileSequenceIdentifier> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccProfileSequenceIdentifier"/> class.
|
|||
/// </summary>
|
|||
/// <param name="id">ID of the profile</param>
|
|||
/// <param name="description">Description of the profile</param>
|
|||
public IccProfileSequenceIdentifier(IccProfileId id, IccLocalizedString[] description) |
|||
{ |
|||
Guard.NotNull(description, nameof(description)); |
|||
|
|||
this.Id = id; |
|||
this.Description = description; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the ID of the profile
|
|||
/// </summary>
|
|||
public IccProfileId Id { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the description of the profile
|
|||
/// </summary>
|
|||
public IccLocalizedString[] Description { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public bool Equals(IccProfileSequenceIdentifier other) |
|||
{ |
|||
if (ReferenceEquals(this, other)) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return this.Id.Equals(other.Id) |
|||
&& this.Description.SequenceEqual(other.Description); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,96 @@ |
|||
// <copyright file="IccResponseNumber.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// Associates a normalized device code with a measurement value
|
|||
/// </summary>
|
|||
internal struct IccResponseNumber : IEquatable<IccResponseNumber> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccResponseNumber"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="deviceCode">Device Code</param>
|
|||
/// <param name="measurementValue">Measurement Value</param>
|
|||
public IccResponseNumber(ushort deviceCode, float measurementValue) |
|||
{ |
|||
this.DeviceCode = deviceCode; |
|||
this.MeasurementValue = measurementValue; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the device code
|
|||
/// </summary>
|
|||
public ushort DeviceCode { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the measurement value
|
|||
/// </summary>
|
|||
public float MeasurementValue { get; } |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="IccResponseNumber"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="IccResponseNumber"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="IccResponseNumber"/> on the right side of the operand.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator ==(IccResponseNumber left, IccResponseNumber right) |
|||
{ |
|||
return left.Equals(right); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="IccResponseNumber"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="IccResponseNumber"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="IccResponseNumber"/> on the right side of the operand.</param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator !=(IccResponseNumber left, IccResponseNumber right) |
|||
{ |
|||
return !left.Equals(right); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object other) |
|||
{ |
|||
return (other is IccResponseNumber) && this.Equals((IccResponseNumber)other); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(IccResponseNumber other) |
|||
{ |
|||
return this.DeviceCode == other.DeviceCode |
|||
&& this.MeasurementValue == other.MeasurementValue; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() |
|||
{ |
|||
unchecked |
|||
{ |
|||
int hashCode = this.DeviceCode.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ this.MeasurementValue.GetHashCode(); |
|||
return hashCode; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
{ |
|||
return $"Code: {this.DeviceCode}; Value: {this.MeasurementValue}"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,105 @@ |
|||
// <copyright file="IccTagTableEntry.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// Entry of ICC tag table
|
|||
/// </summary>
|
|||
internal struct IccTagTableEntry : IEquatable<IccTagTableEntry> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IccTagTableEntry"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="signature">Signature of the tag</param>
|
|||
/// <param name="offset">Offset of entry in bytes</param>
|
|||
/// <param name="dataSize">Size of entry in bytes</param>
|
|||
public IccTagTableEntry(IccProfileTag signature, uint offset, uint dataSize) |
|||
{ |
|||
this.Signature = signature; |
|||
this.Offset = offset; |
|||
this.DataSize = dataSize; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the signature of the tag
|
|||
/// </summary>
|
|||
public IccProfileTag Signature { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the offset of entry in bytes
|
|||
/// </summary>
|
|||
public uint Offset { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the size of entry in bytes
|
|||
/// </summary>
|
|||
public uint DataSize { get; } |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="IccTagTableEntry"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">
|
|||
/// The <see cref="IccTagTableEntry"/> on the left side of the operand.
|
|||
/// </param>
|
|||
/// <param name="right">
|
|||
/// The <see cref="IccTagTableEntry"/> on the right side of the operand.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator ==(IccTagTableEntry left, IccTagTableEntry right) |
|||
{ |
|||
return left.Equals(right); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two <see cref="IccTagTableEntry"/> objects for equality.
|
|||
/// </summary>
|
|||
/// <param name="left">The <see cref="IccTagTableEntry"/> on the left side of the operand.</param>
|
|||
/// <param name="right">The <see cref="IccTagTableEntry"/> on the right side of the operand.</param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
|
|||
/// </returns>
|
|||
public static bool operator !=(IccTagTableEntry left, IccTagTableEntry right) |
|||
{ |
|||
return !left.Equals(right); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object other) |
|||
{ |
|||
return (other is IccProfileId) && this.Equals((IccProfileId)other); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(IccTagTableEntry other) |
|||
{ |
|||
return this.Signature == other.Signature |
|||
&& this.Offset == other.Offset |
|||
&& this.DataSize == other.DataSize; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() |
|||
{ |
|||
unchecked |
|||
{ |
|||
int hashCode = this.Signature.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ this.Offset.GetHashCode(); |
|||
hashCode = (hashCode * 397) ^ this.DataSize.GetHashCode(); |
|||
return hashCode; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
{ |
|||
return $"{this.Signature} (Offset: {this.Offset}; Size: {this.DataSize})"; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue