Sdcb.SimdCodecs.Heif 1.4.0

Prefix Reserved
dotnet add package Sdcb.SimdCodecs.Heif --version 1.4.0
                    
NuGet\Install-Package Sdcb.SimdCodecs.Heif -Version 1.4.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Sdcb.SimdCodecs.Heif" Version="1.4.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Sdcb.SimdCodecs.Heif" Version="1.4.0" />
                    
Directory.Packages.props
<PackageReference Include="Sdcb.SimdCodecs.Heif" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Sdcb.SimdCodecs.Heif --version 1.4.0
                    
#r "nuget: Sdcb.SimdCodecs.Heif, 1.4.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Sdcb.SimdCodecs.Heif@1.4.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Sdcb.SimdCodecs.Heif&version=1.4.0
                    
Install as a Cake Addin
#tool nuget:?package=Sdcb.SimdCodecs.Heif&version=1.4.0
                    
Install as a Cake Tool

Sdcb.SimdCodecs.Heif

Pure-managed HEIF / HEIC decoder for .NET 10. Reads ISOBMFF containers (ISO/IEC 14496-12), the HEIF item model (ISO/IEC 23008-12 / MIAF 23000-22), and decodes HEVC intra frames (ITU-T H.265 Main and Main 10 profiles) — the encoding used by every modern Android and iPhone camera.

Patent notice. HEVC (H.265) is patent-encumbered. This package is MIT and conveys no patent licence. Users are responsible for evaluating HEVC patent obligations in their jurisdiction before deploying this package.

This package is not included in the Sdcb.SimdCodecs meta-package, and the facade does not reference it: an MIT package cannot convey HEVC's patent licensing, so using HEVC is a decision each application makes for itself. Install it explicitly and register it with the facade once, at start-up:

using Sdcb.SimdCodecs;
using Sdcb.SimdCodecs.Heif;

SimdCodecs.Register(HeifImageDecoder.Registration);

// From here on every facade entry point handles HEIF / HEIC like any built-in format.
byte[] data = File.ReadAllBytes("photo.heic");
if (SimdCodecs.TryReadInfo(data, out var info))
{
    var bgra = new byte[info.Width * info.Height * 4];
    SimdCodecs.TryDecodeInto(data, bgra, 0, ImagePixelFormat.Bgra32);
}

Registering is idempotent and thread-safe, and cannot be undone. A registered codec is sniffed after the built-in ones. Before registration, SimdCodecs.DetectFormat still reports ImageFormat.Heif (so an application can tell the user what it cannot open) while IsDecodable(ImageFormat.Heif), CanDecode and the Try* methods return false.

HeifImageDecoder is the IImageDecoder adapter behind the registration; it can also be called directly without the facade. So can the codec's own API:

using HeifImage image = HeifDecoder.Decode(data);  // RGBA8, display-oriented
HeifInfo header = HeifDecoder.ReadInfo(data);       // size, coded bit depth, tiles, ICC — no HEVC decoding

What the facade returns

  • TryReadInfo: the displayed size (clap, irot and imir are already applied, so Orientation is always Normal), 3 channels, UInt8, BitDepth 8, one frame, Format = Heif.
  • TryDecode: an 8-bit RGB RasterImage with the container's ICC profile passed through. ColorEncoding comes from the colr nclx box (primaries, transfer); with only an ICC profile it is the assumed-sRGB default (it is never derived from a profile); with no colr box it comes from the HEVC VUI. It is always full range: limited-range Y′CbCr is expanded by the conversion.
  • TryDecodeInto: every ImagePixelFormat, any stride. The pixels equal ToRgba8() of the decoded image converted by PixelConverter.ConvertRow, except Gray8, which is the stored luma (Y) range-mapped to 8 bits — the formula is frozen in HeifColor — rather than the luma of the RGB; an identity-matrix (GBR) image takes the luma of the RGB. A PQ or HLG transfer function returns false (its code values are encoded for an HDR display), as PNG does for cICP PQ / HLG; TryDecode still decodes it and reports the transfer.
  • TryOpenFrames: a one-frame reader over the still image.

Limitations in 1.4

  • 10-bit sources are output as 8-bit samples. Main 10 decodes exactly, but the 1.x interfaces get 8-bit RGB; a 16-bit fidelity output is planned for 2.0.
  • Not decoded: alpha auxiliary images (the colour image decodes, opaque), HDR gain maps, depth maps and other auxiliary items; Exif is not read.
  • Not supported: image sequences (.heics, msf1) and the HEVC range-extension profiles (Main 10 Intra, Main 12, 4:4:4, …) — InvalidDataException, or false from the Try* methods.

Performance

AVX2 / Vector128 (SSE, AdvSimd) / scalar kernels for the inverse transform, intra prediction, SAO and the colour conversion, a CABAC engine with a 64-bit look-ahead window, grid tiles decoded in parallel and, for an image without tiles, a WPP wavefront (CTB rows in parallel) with parallel deblocking, SAO and colour passes. Measured on a Ryzen 7 5800X against libde265 1.1.1 and libheif 1.23.1 in the same process (M3 record):

  • one core, HEVC decoding alone: 0.68–0.87× libde265's time;
  • 8 cores, to RGBA: 0.20–0.32× libheif's time (tiled phone photos and single-item images alike), 0.09–0.14× Magick.NET's;
  • memory: each tile is converted straight into the output as soon as it is decoded, in every pixel layout and stride, so the only image-sized buffer is the output. Peak working-set rise for a 12.6 MP phone photo (48 MB of RGBA): 75 MB, libheif 80 MB; for 50 MP (192 MB): 230 MB, libheif 373 MB.

LINQPad samples

The package ships two runnable samples in linqpad-samples/:

  • decode: the codec's own API on real phone photos (a 12.6 MP 48-tile grid, the same in Main 10) and a single item with a clap crop — ReadInfo, Decode, DecodeTo into a reused buffer, timing and thumbnails.
  • facade: what SimdCodecs.Register(HeifImageDecoder.Registration) changes, then TryDecodeInto as BGRA with a padded stride and as Gray8, and TryDecode's ICC and colour encoding.

What is supported

  • HEIC still images (ftyp major brand heic / heix, compatible brand mif1)
  • Tiled images (grid item type) — the layout used by all phone cameras
  • HEVC Main (8-bit), Main 10 (10-bit) and Main Still Picture profiles, 4:2:0
  • Arbitrary HEVC intra syntax: WPP, sign data hiding, strong intra smoothing, AMP, transform skip, deblocking and SAO
  • hvcC (decoder configuration), ispe, pixi
  • colr box: nclx colour signalling (matrix from H.273) and ICC profile passthrough (prof / rICC, returned on HeifImage.IccProfile, not applied)
  • clap clean aperture, irot rotation and imir mirroring, applied in association order so the pixels come out as the file intends them to be displayed
  • Output is 8-bit; 10-bit input is converted with the correct matrix and range

Output contract

HEVC decoding is integer-arithmetic and deterministic: the Y / Cb / Cr planes of every coded image equal a pinned reference decoder's samples bit-for-bit (ffmpeg 8.1.2; see tests/Sdcb.SimdCodecs.Tests/Oracle/heif/README.md). The YCbCr → RGB conversion (HeifColor) is defined in-repo from the colr / nclx parameters and frozen like JpegColor, and so is the grey projection (HeifColor.ToGrayRow). Every vector kernel has a scalar twin and every tier (Vector256, Vector128, scalar; x64 and arm64) produces identical output; CI runs the HEIF tests on each.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.4.0 43 11/4/2026