Browse Source

Fix mistake reading the clut values

pull/1567/head
Brian Popow 4 years ago
parent
commit
b036cc36d1
  1. 36
      src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Lut.cs
  2. 35
      src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Primitives.cs
  3. 3
      src/ImageSharp/Metadata/Profiles/ICC/Various/IccClut.cs

36
src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Lut.cs

@ -72,22 +72,26 @@ internal sealed partial class IccDataReader
/// <returns>The read CLUT8.</returns> /// <returns>The read CLUT8.</returns>
public IccClut ReadClut8(int inChannelCount, int outChannelCount, byte[] gridPointCount) public IccClut ReadClut8(int inChannelCount, int outChannelCount, byte[] gridPointCount)
{ {
int start = this.currentIndex;
int length = 0; int length = 0;
for (int i = 0; i < inChannelCount; i++) for (int i = 0; i < inChannelCount; i++)
{ {
length += (int)Math.Pow(gridPointCount[i], inChannelCount); length += (int)Math.Pow(gridPointCount[i], inChannelCount);
} }
length /= inChannelCount;
const float Max = byte.MaxValue; const float Max = byte.MaxValue;
var values = new float[length]; float[] values = new float[length * outChannelCount];
int offset = 0;
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
{ {
values[i] = this.data[this.currentIndex++] / Max; for (int j = 0; j < outChannelCount; j++)
{
values[offset++] = this.data[this.currentIndex++] / Max;
}
} }
this.currentIndex = start + length;
return new IccClut(values, gridPointCount, IccClutDataType.UInt8, outChannelCount); return new IccClut(values, gridPointCount, IccClutDataType.UInt8, outChannelCount);
} }
@ -107,15 +111,21 @@ internal sealed partial class IccDataReader
length += (int)Math.Pow(gridPointCount[i], inChannelCount); length += (int)Math.Pow(gridPointCount[i], inChannelCount);
} }
length /= inChannelCount;
const float Max = ushort.MaxValue; const float Max = ushort.MaxValue;
var values = new float[length]; float[] values = new float[length * outChannelCount];
int offset = 0;
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
{ {
values[i] = this.ReadUInt16() / Max; for (int j = 0; j < outChannelCount; j++)
{
values[offset++] = this.ReadUInt16() / Max;
}
} }
this.currentIndex = start + (length * 2); this.currentIndex = start + (length * outChannelCount * 2);
return new IccClut(values, gridPointCount, IccClutDataType.UInt16, outChannelCount); return new IccClut(values, gridPointCount, IccClutDataType.UInt16, outChannelCount);
} }
@ -135,13 +145,19 @@ internal sealed partial class IccDataReader
length += (int)Math.Pow(gridPointCount[i], inChCount); length += (int)Math.Pow(gridPointCount[i], inChCount);
} }
var values = new float[length]; length /= inChCount;
float[] values = new float[length * outChCount];
int offset = 0;
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
{ {
values[i] = this.ReadSingle(); for (int j = 0; j < outChCount; j++)
{
values[offset++] = this.ReadSingle();
}
} }
this.currentIndex = start + (length * 4); this.currentIndex = start + (length * outChCount * 4);
return new IccClut(values, gridPointCount, IccClutDataType.Float, outChCount); return new IccClut(values, gridPointCount, IccClutDataType.Float, outChCount);
} }
} }

35
src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Primitives.cs

@ -16,55 +16,37 @@ internal sealed partial class IccDataReader
/// Reads an ushort /// Reads an ushort
/// </summary> /// </summary>
/// <returns>the value</returns> /// <returns>the value</returns>
public ushort ReadUInt16() public ushort ReadUInt16() => BinaryPrimitives.ReadUInt16BigEndian(this.data.AsSpan(this.AddIndex(2), 2));
{
return BinaryPrimitives.ReadUInt16BigEndian(this.data.AsSpan(this.AddIndex(2), 2));
}
/// <summary> /// <summary>
/// Reads a short /// Reads a short
/// </summary> /// </summary>
/// <returns>the value</returns> /// <returns>the value</returns>
public short ReadInt16() public short ReadInt16() => BinaryPrimitives.ReadInt16BigEndian(this.data.AsSpan(this.AddIndex(2), 2));
{
return BinaryPrimitives.ReadInt16BigEndian(this.data.AsSpan(this.AddIndex(2), 2));
}
/// <summary> /// <summary>
/// Reads an uint /// Reads an uint
/// </summary> /// </summary>
/// <returns>the value</returns> /// <returns>the value</returns>
public uint ReadUInt32() public uint ReadUInt32() => BinaryPrimitives.ReadUInt32BigEndian(this.data.AsSpan(this.AddIndex(4), 4));
{
return BinaryPrimitives.ReadUInt32BigEndian(this.data.AsSpan(this.AddIndex(4), 4));
}
/// <summary> /// <summary>
/// Reads an int /// Reads an int
/// </summary> /// </summary>
/// <returns>the value</returns> /// <returns>the value</returns>
public int ReadInt32() public int ReadInt32() => BinaryPrimitives.ReadInt32BigEndian(this.data.AsSpan(this.AddIndex(4), 4));
{
return BinaryPrimitives.ReadInt32BigEndian(this.data.AsSpan(this.AddIndex(4), 4));
}
/// <summary> /// <summary>
/// Reads an ulong /// Reads an ulong
/// </summary> /// </summary>
/// <returns>the value</returns> /// <returns>the value</returns>
public ulong ReadUInt64() public ulong ReadUInt64() => BinaryPrimitives.ReadUInt64BigEndian(this.data.AsSpan(this.AddIndex(8), 8));
{
return BinaryPrimitives.ReadUInt64BigEndian(this.data.AsSpan(this.AddIndex(8), 8));
}
/// <summary> /// <summary>
/// Reads a long /// Reads a long
/// </summary> /// </summary>
/// <returns>the value</returns> /// <returns>the value</returns>
public long ReadInt64() public long ReadInt64() => BinaryPrimitives.ReadInt64BigEndian(this.data.AsSpan(this.AddIndex(8), 8));
{
return BinaryPrimitives.ReadInt64BigEndian(this.data.AsSpan(this.AddIndex(8), 8));
}
/// <summary> /// <summary>
/// Reads a float. /// Reads a float.
@ -152,10 +134,7 @@ internal sealed partial class IccDataReader
/// Reads an unsigned 16bit number with 8 value bits and 8 fractional bits. /// Reads an unsigned 16bit number with 8 value bits and 8 fractional bits.
/// </summary> /// </summary>
/// <returns>The number as double</returns> /// <returns>The number as double</returns>
public float ReadUFix8() public float ReadUFix8() => this.ReadUInt16() / 256f;
{
return this.ReadUInt16() / 256f;
}
/// <summary> /// <summary>
/// Reads a number of bytes and advances the index. /// Reads a number of bytes and advances the index.

3
src/ImageSharp/Metadata/Profiles/ICC/Various/IccClut.cs

@ -113,6 +113,7 @@ internal sealed class IccClut : IEquatable<IccClut>
length += (int)Math.Pow(this.GridPointCount[i], this.InputChannelCount); length += (int)Math.Pow(this.GridPointCount[i], this.InputChannelCount);
} }
Guard.IsTrue(this.Values.Length == length, nameof(this.Values), "Length of values array does not match the grid points"); // TODO: Disabled this check, not sure if this check is correct.
// Guard.IsTrue(this.Values.Length == length, nameof(this.Values), "Length of values array does not match the grid points");
} }
} }

Loading…
Cancel
Save