Browse Source

Exposed used compression method in metadata

pull/2633/head
Ynse Hoornenborg 2 years ago
parent
commit
e972551bb5
  1. 45
      src/ImageSharp/Formats/Heic/HeicCompressionMethod.cs
  2. 12
      src/ImageSharp/Formats/Heic/HeicDecoderCore.cs
  3. 8
      src/ImageSharp/Formats/Heic/HeicMetadata.cs
  4. 16
      tests/ImageSharp.Tests/Formats/Heic/HeicDecoderTests.cs
  5. 1
      tests/ImageSharp.Tests/TestImages.cs

45
src/ImageSharp/Formats/Heic/HeicCompressionMethod.cs

@ -0,0 +1,45 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
namespace SixLabors.ImageSharp.Formats.Heic;
/// <summary>
/// Compression algorithms possible inside an HEIF (High Efficiency File Format) based file.
/// </summary>
public enum HeicCompressionMethod
{
/// <summary>
/// High Efficiency Video Coding
/// </summary>
Hevc,
/// <summary>
/// Legact JPEG
/// </summary>
LegacyJpeg,
/// <summary>
/// JPEG 2000
/// </summary>
Jpeg2000,
/// <summary>
/// JPEG-XR
/// </summary>
JpegXR,
/// <summary>
/// JPEG-XS
/// </summary>
JpegXS,
/// <summary>
/// AOMedia's Video 1 coding
/// </summary>
Av1,
/// <summary>
/// Advanced Video Coding
/// </summary>
Avc,
}

12
src/ImageSharp/Formats/Heic/HeicDecoderCore.cs

@ -25,7 +25,7 @@ internal sealed class HeicDecoderCore : IImageDecoderInternals
/// <summary> /// <summary>
/// The <see cref="ImageMetadata"/> decoded by this decoder instance. /// The <see cref="ImageMetadata"/> decoded by this decoder instance.
/// </summary> /// </summary>
private ImageMetadata? metadata; private readonly ImageMetadata metadata;
private uint primaryItem; private uint primaryItem;
@ -130,6 +130,12 @@ internal sealed class HeicDecoderCore : IImageDecoderInternals
throw new ImageFormatException("No primary item found"); throw new ImageFormatException("No primary item found");
} }
HeicMetadata meta = this.metadata.GetHeicMetadata();
if (this.itemLinks.Any(link => link.Type == Heic4CharCode.thmb))
{
meta.CompressionMethod = HeicCompressionMethod.LegacyJpeg;
}
return new ImageInfo(new PixelTypeInfo(item.BitsPerPixel), new(item.Extent.Width, item.Extent.Height), this.metadata); return new ImageInfo(new PixelTypeInfo(item.BitsPerPixel), new(item.Extent.Width, item.Extent.Height), this.metadata);
} }
@ -432,6 +438,7 @@ internal sealed class HeicDecoderCore : IImageDecoderInternals
case Heic4CharCode.rloc: case Heic4CharCode.rloc:
case Heic4CharCode.udes: case Heic4CharCode.udes:
// TODO: Implement // TODO: Implement
properties.Add(new KeyValuePair<Heic4CharCode, object>(itemType, new object()));
break; break;
default: default:
throw new ImageFormatException($"Unknown item type in property box of '{PrettyPrint(itemType)}'"); throw new ImageFormatException($"Unknown item type in property box of '{PrettyPrint(itemType)}'");
@ -594,6 +601,9 @@ internal sealed class HeicDecoderCore : IImageDecoderInternals
Span<byte> thumbSpan = thumbMemory.GetSpan(); Span<byte> thumbSpan = thumbMemory.GetSpan();
stream.Read(thumbSpan); stream.Read(thumbSpan);
HeicMetadata meta = this.metadata.GetHeicMetadata();
meta.CompressionMethod = HeicCompressionMethod.LegacyJpeg;
return Image.Load<TPixel>(thumbSpan); return Image.Load<TPixel>(thumbSpan);
} }

8
src/ImageSharp/Formats/Heic/HeicMetadata.cs

@ -20,8 +20,12 @@ public class HeicMetadata : IDeepCloneable
/// </summary> /// </summary>
/// <param name="other">The metadata to create an instance from.</param> /// <param name="other">The metadata to create an instance from.</param>
private HeicMetadata(HeicMetadata other) private HeicMetadata(HeicMetadata other)
{ => this.CompressionMethod = other.CompressionMethod;
}
/// <summary>
/// Gets or sets the compression method used for the primary frame.
/// </summary>
public HeicCompressionMethod CompressionMethod { get; set; }
/// <inheritdoc/> /// <inheritdoc/>
public IDeepCloneable DeepClone() => new HeicMetadata(this); public IDeepCloneable DeepClone() => new HeicMetadata(this);

16
tests/ImageSharp.Tests/Formats/Heic/HeicDecoderTests.cs

@ -11,10 +11,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Heic;
public class HeicDecoderTests public class HeicDecoderTests
{ {
[Theory] [Theory]
[InlineData(TestImages.Heic.Image1)] [InlineData(TestImages.Heic.Image1, HeicCompressionMethod.Hevc)]
[InlineData(TestImages.Heic.Sample640x427)] [InlineData(TestImages.Heic.Sample640x427, HeicCompressionMethod.Hevc)]
[InlineData(TestImages.Heic.FujiFilmHif)] [InlineData(TestImages.Heic.FujiFilmHif, HeicCompressionMethod.LegacyJpeg)]
public void Identify(string imagePath) public void Identify(string imagePath, HeicCompressionMethod compressionMethod)
{ {
TestFile testFile = TestFile.Create(imagePath); TestFile testFile = TestFile.Create(imagePath);
using MemoryStream stream = new(testFile.Bytes, false); using MemoryStream stream = new(testFile.Bytes, false);
@ -23,8 +23,8 @@ public class HeicDecoderTests
HeicMetadata heicMetadata = imageInfo.Metadata.GetHeicMetadata(); HeicMetadata heicMetadata = imageInfo.Metadata.GetHeicMetadata();
Assert.NotNull(imageInfo); Assert.NotNull(imageInfo);
Assert.Equal(imageInfo.Metadata.DecodedImageFormat, HeicFormat.Instance); Assert.Equal(HeicFormat.Instance, imageInfo.Metadata.DecodedImageFormat);
//Assert.Equal(heicMetadata.Channels, channels); Assert.Equal(compressionMethod, heicMetadata.CompressionMethod);
} }
[Theory] [Theory]
@ -33,10 +33,10 @@ public class HeicDecoderTests
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
using Image<TPixel> image = provider.GetImage(); using Image<TPixel> image = provider.GetImage();
HeicMetadata qoiMetadata = image.Metadata.GetHeicMetadata(); HeicMetadata heicMetadata = image.Metadata.GetHeicMetadata();
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(provider); image.CompareToReferenceOutput(provider);
//Assert.Equal(heicMetadata.Channels, channels); Assert.Equal(HeicCompressionMethod.LegacyJpeg, heicMetadata.CompressionMethod);
} }
} }

1
tests/ImageSharp.Tests/TestImages.cs

@ -1112,6 +1112,7 @@ public static class TestImages
public const string Image3 = "Heic/image3.heic"; public const string Image3 = "Heic/image3.heic";
public const string Image4 = "Heic/image4.heic"; public const string Image4 = "Heic/image4.heic";
public const string Sample640x427 = "Heic/dwsample-heic-640.heic"; public const string Sample640x427 = "Heic/dwsample-heic-640.heic";
// Downloaded from: https://github.com/draktable-org/darktable/issues/14473
public const string FujiFilmHif = "Heic/IMG-20230508-0053.hif"; public const string FujiFilmHif = "Heic/IMG-20230508-0053.hif";
} }
} }

Loading…
Cancel
Save