diff --git a/src/ImageSharp/Formats/Heic/HeicCompressionMethod.cs b/src/ImageSharp/Formats/Heic/HeicCompressionMethod.cs
new file mode 100644
index 0000000000..efe826f85c
--- /dev/null
+++ b/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;
+
+///
+/// Compression algorithms possible inside an HEIF (High Efficiency File Format) based file.
+///
+public enum HeicCompressionMethod
+{
+ ///
+ /// High Efficiency Video Coding
+ ///
+ Hevc,
+
+ ///
+ /// Legact JPEG
+ ///
+ LegacyJpeg,
+
+ ///
+ /// JPEG 2000
+ ///
+ Jpeg2000,
+
+ ///
+ /// JPEG-XR
+ ///
+ JpegXR,
+
+ ///
+ /// JPEG-XS
+ ///
+ JpegXS,
+
+ ///
+ /// AOMedia's Video 1 coding
+ ///
+ Av1,
+
+ ///
+ /// Advanced Video Coding
+ ///
+ Avc,
+}
diff --git a/src/ImageSharp/Formats/Heic/HeicDecoderCore.cs b/src/ImageSharp/Formats/Heic/HeicDecoderCore.cs
index 0d3a31f0d3..ed2381cc62 100644
--- a/src/ImageSharp/Formats/Heic/HeicDecoderCore.cs
+++ b/src/ImageSharp/Formats/Heic/HeicDecoderCore.cs
@@ -25,7 +25,7 @@ internal sealed class HeicDecoderCore : IImageDecoderInternals
///
/// The decoded by this decoder instance.
///
- private ImageMetadata? metadata;
+ private readonly ImageMetadata metadata;
private uint primaryItem;
@@ -130,6 +130,12 @@ internal sealed class HeicDecoderCore : IImageDecoderInternals
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);
}
@@ -432,6 +438,7 @@ internal sealed class HeicDecoderCore : IImageDecoderInternals
case Heic4CharCode.rloc:
case Heic4CharCode.udes:
// TODO: Implement
+ properties.Add(new KeyValuePair(itemType, new object()));
break;
default:
throw new ImageFormatException($"Unknown item type in property box of '{PrettyPrint(itemType)}'");
@@ -594,6 +601,9 @@ internal sealed class HeicDecoderCore : IImageDecoderInternals
Span thumbSpan = thumbMemory.GetSpan();
stream.Read(thumbSpan);
+ HeicMetadata meta = this.metadata.GetHeicMetadata();
+ meta.CompressionMethod = HeicCompressionMethod.LegacyJpeg;
+
return Image.Load(thumbSpan);
}
diff --git a/src/ImageSharp/Formats/Heic/HeicMetadata.cs b/src/ImageSharp/Formats/Heic/HeicMetadata.cs
index 55f3d7ba82..f6f95a86cd 100644
--- a/src/ImageSharp/Formats/Heic/HeicMetadata.cs
+++ b/src/ImageSharp/Formats/Heic/HeicMetadata.cs
@@ -20,8 +20,12 @@ public class HeicMetadata : IDeepCloneable
///
/// The metadata to create an instance from.
private HeicMetadata(HeicMetadata other)
- {
- }
+ => this.CompressionMethod = other.CompressionMethod;
+
+ ///
+ /// Gets or sets the compression method used for the primary frame.
+ ///
+ public HeicCompressionMethod CompressionMethod { get; set; }
///
public IDeepCloneable DeepClone() => new HeicMetadata(this);
diff --git a/tests/ImageSharp.Tests/Formats/Heic/HeicDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Heic/HeicDecoderTests.cs
index 8f50b2298f..b3862c3d06 100644
--- a/tests/ImageSharp.Tests/Formats/Heic/HeicDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Heic/HeicDecoderTests.cs
@@ -11,10 +11,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Heic;
public class HeicDecoderTests
{
[Theory]
- [InlineData(TestImages.Heic.Image1)]
- [InlineData(TestImages.Heic.Sample640x427)]
- [InlineData(TestImages.Heic.FujiFilmHif)]
- public void Identify(string imagePath)
+ [InlineData(TestImages.Heic.Image1, HeicCompressionMethod.Hevc)]
+ [InlineData(TestImages.Heic.Sample640x427, HeicCompressionMethod.Hevc)]
+ [InlineData(TestImages.Heic.FujiFilmHif, HeicCompressionMethod.LegacyJpeg)]
+ public void Identify(string imagePath, HeicCompressionMethod compressionMethod)
{
TestFile testFile = TestFile.Create(imagePath);
using MemoryStream stream = new(testFile.Bytes, false);
@@ -23,8 +23,8 @@ public class HeicDecoderTests
HeicMetadata heicMetadata = imageInfo.Metadata.GetHeicMetadata();
Assert.NotNull(imageInfo);
- Assert.Equal(imageInfo.Metadata.DecodedImageFormat, HeicFormat.Instance);
- //Assert.Equal(heicMetadata.Channels, channels);
+ Assert.Equal(HeicFormat.Instance, imageInfo.Metadata.DecodedImageFormat);
+ Assert.Equal(compressionMethod, heicMetadata.CompressionMethod);
}
[Theory]
@@ -33,10 +33,10 @@ public class HeicDecoderTests
where TPixel : unmanaged, IPixel
{
using Image image = provider.GetImage();
- HeicMetadata qoiMetadata = image.Metadata.GetHeicMetadata();
+ HeicMetadata heicMetadata = image.Metadata.GetHeicMetadata();
image.DebugSave(provider);
image.CompareToReferenceOutput(provider);
- //Assert.Equal(heicMetadata.Channels, channels);
+ Assert.Equal(HeicCompressionMethod.LegacyJpeg, heicMetadata.CompressionMethod);
}
}
diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs
index d30974fa1d..ef80704b08 100644
--- a/tests/ImageSharp.Tests/TestImages.cs
+++ b/tests/ImageSharp.Tests/TestImages.cs
@@ -1112,6 +1112,7 @@ public static class TestImages
public const string Image3 = "Heic/image3.heic";
public const string Image4 = "Heic/image4.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";
}
}