Browse Source

More HIF support

pull/2633/head
Ynse Hoornenborg 3 years ago
parent
commit
f90d4ebe95
  1. 5
      src/ImageSharp/Formats/Heic/Heic4CharCode.cs
  2. 1
      src/ImageSharp/Formats/Heic/Heic4CharCode.tt
  3. 2
      src/ImageSharp/Formats/Heic/HeicConstants.cs
  4. 17
      src/ImageSharp/Formats/Heic/HeicDecoderCore.cs
  5. 6
      src/ImageSharp/Formats/Heic/HeicItem.cs
  6. 20
      src/ImageSharp/Formats/Heic/HeicLocation.cs

5
src/ImageSharp/Formats/Heic/Heic4CharCode.cs

@ -223,4 +223,9 @@ public enum Heic4CharCode : uint
/// </summary>
uuid = 0x75756964U,
/// <summary>
/// Free space.
/// </summary>
free = 0x66726565U,
}

1
src/ImageSharp/Formats/Heic/Heic4CharCode.tt

@ -49,6 +49,7 @@
"uri ", "URI",
"pict", "Picture handler type",
"uuid", "Unique Identifier",
"free", "Free space",
};
#>

2
src/ImageSharp/Formats/Heic/HeicConstants.cs

@ -18,5 +18,5 @@ internal static class HeicConstants
/// <summary>
/// The list of file extensions that equate to a HEIC.
/// </summary>
public static readonly IEnumerable<string> FileExtensions = new[] { "heic", "heif", "avif" };
public static readonly IEnumerable<string> FileExtensions = new[] { "heic", "heif", "hif", "avif" };
}

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

@ -75,8 +75,15 @@ internal sealed class HeicDecoderCore : IImageDecoderInternals
case Heic4CharCode.mdat:
this.ParseMediaData(stream, boxLength);
break;
case Heic4CharCode.free:
SkipBox(stream, boxLength);
break;
case 0U:
// Some files have trailing zeros, skiping to EOF.
stream.Skip((int)(stream.Length - stream.Position));
break;
default:
throw new ImageFormatException($"Unknown box type of '{Enum.GetName(boxType)}'");
throw new ImageFormatException($"Unknown box type of '{PrettyPrint(boxType)}'");
}
}
@ -129,9 +136,10 @@ internal sealed class HeicDecoderCore : IImageDecoderInternals
long boxLength = this.ReadBoxHeader(stream, out Heic4CharCode boxType);
Span<byte> buffer = this.ReadIntoBuffer(stream, boxLength);
uint majorBrand = BinaryPrimitives.ReadUInt32BigEndian(buffer);
bool correctBrand = majorBrand == (uint)Heic4CharCode.heic || majorBrand == (uint)Heic4CharCode.heix;
// TODO: Interpret minorVersion and compatible brands.
return boxType == Heic4CharCode.ftyp && majorBrand == (uint)Heic4CharCode.heic;
return boxType == Heic4CharCode.ftyp && correctBrand;
}
private long ReadBoxHeader(BufferedReadStream stream, out Heic4CharCode boxType)
@ -490,6 +498,7 @@ internal sealed class HeicDecoderCore : IImageDecoderInternals
for (uint i = 0; i < itemCount; i++)
{
uint itemId = ReadUInt16Or32(buffer, version == 2, ref bytesRead);
HeicItem? item = this.FindItemById(itemId);
if (version is 1 or 2)
{
bytesRead++;
@ -506,11 +515,13 @@ internal sealed class HeicDecoderCore : IImageDecoderInternals
{
if (version is 1 or 2 && indexSize > 0)
{
ulong extentIndex = ReadUIntVariable(buffer, indexSize, ref bytesRead);
_ = ReadUIntVariable(buffer, indexSize, ref bytesRead);
}
ulong extentOffset = ReadUIntVariable(buffer, offsetSize, ref bytesRead);
ulong extentLength = ReadUIntVariable(buffer, lengthSize, ref bytesRead);
HeicLocation loc = new HeicLocation((long)extentOffset, (long)extentLength);
item?.DataLocations.Add(loc);
}
}
}

6
src/ImageSharp/Formats/Heic/HeicItem.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
namespace SixLabors.ImageSharp.Formats.Heic;
/// <summary>
@ -68,6 +69,11 @@ public class HeicItem(Heic4CharCode type, uint id)
/// </summary>
public Size GridCellExtent { get; private set; }
/// <summary>
/// Gets the list of data locations for this item.
/// </summary>
public List<HeicLocation> DataLocations { get; } = new List<HeicLocation>();
/// <summary>
/// Set the image extent.
/// </summary>

20
src/ImageSharp/Formats/Heic/HeicLocation.cs

@ -0,0 +1,20 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
namespace SixLabors.ImageSharp.Formats.Heic;
/// <summary>
/// Location within the file of an <see cref="HeicItem"/>.
/// </summary>
public class HeicLocation(long offset, long length)
{
/// <summary>
/// Gets the file offset of this location.
/// </summary>
public long Offset { get; } = offset;
/// <summary>
/// Gets the length of this location.
/// </summary>
public long Length { get; } = length;
}
Loading…
Cancel
Save