Browse Source

Fix reader and out of range exception

pull/1567/head
James Jackson-South 3 years ago
parent
commit
54856ff945
  1. 1
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/LutABCalculator.cs
  2. 21
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/LutCalculator.cs
  3. 8
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccConverterbase.Conversions.cs
  4. 1
      src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs
  5. 21
      src/ImageSharp/Metadata/Profiles/ICC/IccReader.cs
  6. 10
      src/ImageSharp/Metadata/Profiles/ICC/Various/IccTagTableEntry.cs
  7. 10
      tests/ImageSharp.Tests/Colorspaces/Icc/IccProfileConverterTests.cs

1
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/LutABCalculator.cs

@ -1,7 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System;
using System.Numerics;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;

21
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/LutCalculator.cs

@ -1,15 +1,14 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System;
using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc;
internal class LutCalculator : ISingleCalculator
{
private float[] lut;
private bool inverse;
private readonly float[] lut;
private readonly bool inverse;
public LutCalculator(float[] lut, bool inverse)
{
@ -25,10 +24,8 @@ internal class LutCalculator : ISingleCalculator
{
return this.LookupInverse(value);
}
else
{
return this.Lookup(value);
}
return this.Lookup(value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -37,7 +34,13 @@ internal class LutCalculator : ISingleCalculator
float factor = value * (this.lut.Length - 1);
int index = (int)factor;
float low = this.lut[index];
float high = this.lut[index + 1];
float high = 1F;
if (index < this.lut.Length - 1)
{
high = this.lut[index + 1];
}
return low + ((high - low) * (factor - index));
}

8
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccConverterbase.Conversions.cs

@ -22,8 +22,7 @@ internal abstract partial class IccConverterBase
/// <param name="renderingIntent">The wanted rendering intent. Can be ignored if not available</param>
protected void Init(IccProfile profile, bool toPcs, IccRenderingIntent renderingIntent)
{
ConversionMethod method = GetConversionMethod(profile, renderingIntent);
switch (method)
switch (GetConversionMethod(profile, renderingIntent))
{
case ConversionMethod.D0:
this.calculator = toPcs ?
@ -83,8 +82,7 @@ internal abstract partial class IccConverterBase
private static IVector4Calculator InitA(IccProfile profile, IccProfileTag tag)
{
IccTagDataEntry entry = GetTag(profile, tag);
switch (entry)
switch (GetTag(profile, tag))
{
case IccLut8TagDataEntry lut8:
return new LutEntryCalculator(lut8);
@ -96,6 +94,8 @@ internal abstract partial class IccConverterBase
return new LutABCalculator(lutBtoA);
default:
// TODO: This is where we likely return a matrix calculator.
throw new InvalidIccProfileException("Invalid entry.");
}
}

1
src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs

@ -206,7 +206,6 @@ public sealed class IccProfile : IDeepCloneable<IccProfile>
return;
}
IccReader reader = new();
this.entries = IccReader.ReadTagData(this.data);
}
}

21
src/ImageSharp/Metadata/Profiles/ICC/IccReader.cs

@ -83,28 +83,19 @@ internal sealed class IccReader
{
IccTagTableEntry[] tagTable = ReadTagTable(reader);
List<IccTagDataEntry> entries = new(tagTable.Length);
Dictionary<uint, IccTagDataEntry> store = new();
foreach (IccTagTableEntry tag in tagTable)
{
IccTagDataEntry entry;
if (store.ContainsKey(tag.Offset))
try
{
entry = store[tag.Offset];
entry = reader.ReadTagDataEntry(tag);
}
else
catch
{
try
{
entry = reader.ReadTagDataEntry(tag);
}
catch
{
// Ignore tags that could not be read
continue;
}
store.Add(tag.Offset, entry);
// Ignore tags that could not be read
continue;
}
entry.TagSignature = tag.Signature;

10
src/ImageSharp/Metadata/Profiles/ICC/Various/IccTagTableEntry.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc;
@ -49,9 +49,7 @@ internal readonly struct IccTagTableEntry : IEquatable<IccTagTableEntry>
/// 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);
}
=> left.Equals(right);
/// <summary>
/// Compares two <see cref="IccTagTableEntry"/> objects for equality.
@ -62,9 +60,7 @@ internal readonly struct IccTagTableEntry : IEquatable<IccTagTableEntry>
/// 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);
}
=> !left.Equals(right);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is IccTagTableEntry other && this.Equals(other);

10
tests/ImageSharp.Tests/Colorspaces/Icc/IccProfileConverterTests.cs

@ -9,16 +9,15 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Tests.Colorspaces.Icc;
public class IccProfileConverterTests
{
private static PngEncoder Encoder = new PngEncoder();
private static readonly PngEncoder Encoder = new();
[Theory]
[WithFile(TestImages.Jpeg.ICC.AdobeRgb, PixelTypes.Rgb24)]
[WithFile(TestImages.Jpeg.ICC.AppleRGB, PixelTypes.Rgb24)]
[WithFile(TestImages.Jpeg.ICC.ColorMatch, PixelTypes.Rgb24)]
[WithFile(TestImages.Jpeg.ICC.WideRGB, PixelTypes.Rgb24)]
// [WithFile(TestImages.Jpeg.ICC.SRgb, PixelTypes.Rgb24)] ConverterBase says this is invalid.
// [WithFile(TestImages.Jpeg.ICC.ProPhoto, PixelTypes.Rgb24)] ConverterBase says this is invalid.
[WithFile(TestImages.Jpeg.ICC.SRgb, PixelTypes.Rgb24)]
[WithFile(TestImages.Jpeg.ICC.ProPhoto, PixelTypes.Rgb24)]
public void CanRoundTripProfile<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -37,10 +36,9 @@ public class IccProfileConverterTests
Assert.Equal(expected, actual);
}
// TODO: This fails as the base calculator says sRGB is invalid.
[Theory]
[WithFile(TestImages.Jpeg.ICC.AdobeRgb, PixelTypes.Rgb24)]
public void CanConvertTosRGB<TPixel>(TestImageProvider<TPixel> provider)
public void CanConvertToWide<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using Image<TPixel> image = provider.GetImage();

Loading…
Cancel
Save