libheif clib

HEIF/HEIC image codec for PascalAI. Read Apple iPhone photos (.heic), encode images in HEIF format with HEVC or AV1 compression — better quality at half the JPEG file size. Supports HDR, wide color, thumbnails, depth maps, and embedded EXIF/XMP metadata.

Version1.0.0
Typeclib
CategoryMultimedia
System reqlibheif-dev
CLib package — Ubuntu/Debian: sudo apt install libheif-dev
ppm install libheif

Quick Start

Read an iPhone HEIC photo

uses libheif;

{ One-shot convert to RGBA }
var w, h: Integer;
var rgba := HeicToRGBA('/photos/IMG_1234.heic', w, h);
WriteLn('Size: ' + IntToStr(w) + 'x' + IntToStr(h));
WriteLn('Pixels: ' + IntToStr(Length(rgba)) + ' bytes');

{ Or convert to PNG/JPEG }
HeicToPNG('/photos/IMG_1234.heic', '/output/photo.png');
HeicToJPEG('/photos/IMG_1234.heic', '/output/photo.jpg', 90);

Read with metadata access

uses libheif;

var ctx := OpenFile('/photos/burst.heic');
WriteLn('Images in file: ' + IntToStr(ImageCount(ctx)));

var h    := GetPrimaryHandle(ctx);
var info := GetInfo(h);
WriteLn('HDR: ' + BoolToStr(info.IsHDR));

{ Read EXIF data }
var exif := GetEXIF(h);
var xmp  := GetXMP(h);

var rgba := DecodeRGBA(h);
FreeHandle(h);
FreeContext(ctx);

Encode HEIF (requires x265 or AV1 encoder plugin)

uses libheif;

if CanEncode('hevc') then
begin
  var opts: THeifEncodeOptions;
  opts.Quality  := 85;
  opts.Lossless := False;
  opts.Threads  := 4;
  opts.Codec    := 'hevc';
  EncodeRGBAToFile(rgbaBytes, 4032, 3024, '/output/photo.heic', opts);
end;

Open/Close API

FunctionSignatureDescription
OpenFileOpenFile(path: string): THeifContextLoad a HEIF/HEIC file from disk into a context. Supports .heic, .heif, and .avif extensions.
OpenBytesOpenBytes(data: TBytes): THeifContextLoad a HEIF file from an in-memory byte array.
FreeContextFreeContext(ctx: THeifContext)Release all resources held by the context. Always call when done.
ImageCountImageCount(ctx: THeifContext): IntegerReturn the number of top-level images (items) in the file. Burst photos may contain many.

Handle API

Function / FieldTypeDescription
GetImageHandleGetImageHandle(ctx: THeifContext; index: Integer): THeifHandleGet a handle to the image at the given 0-based index.
GetPrimaryHandleGetPrimaryHandle(ctx: THeifContext): THeifHandleGet a handle to the primary (main) image. Equivalent to the photo you see in the camera roll.
FreeHandleFreeHandle(h: THeifHandle)Release the handle. The parent context remains valid.
GetInfoGetInfo(h: THeifHandle): THeifInfoRead image properties without fully decoding the pixel data.
THeifInfo.WidthIntegerImage width in pixels.
THeifInfo.HeightIntegerImage height in pixels.
THeifInfo.IsHDRBooleanTrue if the image has more than 8 bits per channel (HDR content).
THeifInfo.HasAlphaBooleanTrue if an alpha channel is present.
THeifInfo.BitDepthIntegerBits per channel (8, 10, or 12).
THeifInfo.ColorProfilestringColor profile name (e.g., "sRGB", "Display P3").

Decode API

FunctionSignatureDescription
DecodeRGBDecodeRGB(h: THeifHandle): TBytesDecode to a flat RGB byte array (width × height × 3 bytes).
DecodeRGBADecodeRGBA(h: THeifHandle): TBytesDecode to a flat RGBA byte array (width × height × 4 bytes).
DecodeGrayDecodeGray(h: THeifHandle): TBytesDecode to grayscale (width × height × 1 byte per pixel).
DecodeImageDecodeImage(h: THeifHandle; colorspace: THeifColorspace): THeifImageDecode to a structured image object with named planes.
FreeImageFreeImage(img: THeifImage)Release a decoded THeifImage object.
GetImagePlaneGetImagePlane(img: THeifImage; channel: THeifChannel): TBytesExtract a single channel plane (hcY, hcCb, hcCr, hcR, hcG, hcB, hcAlpha) from a decoded image.

Thumbnail API

FunctionSignatureDescription
ThumbnailCountThumbnailCount(h: THeifHandle): IntegerReturn the number of embedded thumbnails for this image. iPhone photos typically include one.
GetThumbnailGetThumbnail(h: THeifHandle; index: Integer): THeifHandleGet a handle to the thumbnail at the given index. Decode it with DecodeRGBA or DecodeRGB as usual.

Encode API

Encoder plugins required: HEVC encoding requires sudo apt install libde265-dev x265 and a libheif build with HEVC write support. AV1 encoding requires sudo apt install libaom-dev.
Function / FieldType / SignatureDescription
EncodeRGBToFileEncodeRGBToFile(data: TBytes; w, h: Integer; path: string; opts: THeifEncodeOptions)Encode a flat RGB byte array to a HEIF file on disk.
EncodeRGBAToFileEncodeRGBAToFile(data: TBytes; w, h: Integer; path: string; opts: THeifEncodeOptions)Encode a flat RGBA byte array to a HEIF file on disk.
EncodeRGBToBytesEncodeRGBToBytes(data: TBytes; w, h: Integer; opts: THeifEncodeOptions): TBytesEncode to HEIF and return the result as an in-memory byte array.
THeifEncodeOptions.QualityInteger (1–100)Visual quality level. 85 is a good default for photographs.
THeifEncodeOptions.LosslessBooleanWhen True, forces lossless encoding (Quality is ignored).
THeifEncodeOptions.ThreadsIntegerNumber of encoder threads. Use 0 for automatic (hardware concurrency).
THeifEncodeOptions.Codecstring ('hevc' or 'av1')Compression codec to use. 'hevc' for maximum compatibility, 'av1' for best compression.

Metadata API

FunctionSignatureDescription
GetEXIFGetEXIF(h: THeifHandle): TBytesExtract the raw EXIF block as bytes. Parse with a dedicated EXIF library (e.g. libexif) for tag-level access.
GetXMPGetXMP(h: THeifHandle): stringExtract the XMP metadata block as a UTF-8 XML string.
GetICCProfileGetICCProfile(h: THeifHandle): TBytesExtract the embedded ICC color profile as raw bytes. Returns empty array if no profile is present.

Conversion Helpers

FunctionSignatureDescription
HeicToRGBAHeicToRGBA(path: string; out w, h: Integer): TBytesOne-shot: open, decode primary image to RGBA, close. Returns pixel bytes and sets w/h.
HeicToPNGHeicToPNG(heicPath, pngPath: string)One-shot: convert the primary image of a HEIC file to a PNG file.
HeicToJPEGHeicToJPEG(heicPath, jpegPath: string; quality: Integer)One-shot: convert the primary image of a HEIC file to a JPEG file at the given quality (1–100).

Codec Support

FunctionSignatureDescription
CanDecodeCanDecode(codec: string): BooleanReturn True if the named codec (e.g. 'hevc', 'av1') is available for decoding in the current libheif build.
CanEncodeCanEncode(codec: string): BooleanReturn True if the named codec is available for encoding. Always check before calling EncodeRGBAToFile.
ListDecodersListDecoders(): array of stringReturn the names of all available decode plugins.
ListEncodersListEncoders(): array of stringReturn the names of all available encode plugins.
Installing codec plugins (Ubuntu)
HEVC decode: sudo apt install libde265-dev • HEVC encode: sudo apt install x265 • AV1 decode/encode: sudo apt install libaom-dev

HEIF vs JPEG

FeatureHEIF/HEICJPEG
File size (same quality)~50% smallerBaseline
HDR supportYes (10-bit, 12-bit)No (8-bit only)
Wide color gamutYes (Display P3)sRGB only
Multi-image (burst)YesNo
Depth mapsYesNo
Browser supportPartial (Safari only)Universal
Encoding speedSlower (HEVC/AV1)Fast