Skip to content

Cykooz/libheif-sys

Repository files navigation

libheif-sys

libheif-sys is a binding to libheif.

A high-level wrapper libheif-rs is also available.

CHANGELOG

System dependencies

  • libheif-dev >= 1.17.0.

Minimal supported API version

This crate supports libheif versions 1.17, 1.18 and 1.19.

You MUST specify a minimal version of libheif that is required for you. To do this, enable the corresponding feature: v1_17, v1_18 or v1_19.

Example:

[dependencies]
libheif-sys = { version = "4.0", features = ["v1_18"] }

There is also the latest feature. It always corresponds to the maximal supported by the crate version of libheif.

Linux

The crate uses pkg-confing to find installed libheif (with help of system-deps crate).

You can also enable embedded-libheif feature to compile libheif v1.19.7 from embedded sources and then link it statically.

Note: Static linked version of libheif doesn't have statically linked it dependencies, such as libde256, libaom and other.

Windows

The crate uses vcpkg crate to find libheif installed with help of vcpkg.

You can use cargo-vcpkg to install libheif with help of cargo command:

cargo vcpkg -v build

cargo-vcpkg can fetch and build a vcpkg installation of required packages from scratch. It merges package requirements specified in the Cargo.toml of crates in the dependency tree.

Example of reading and decoding HEIF-image

use std::ffi;
use std::ptr;

use libheif_sys as lh;

#[test]
fn read_and_decode_heif_file() {
    unsafe {
        lh::heif_init(ptr::null_mut());

        let ctx = lh::heif_context_alloc();
        assert!(!ctx.is_null());

        let c_name = ffi::CString::new("data/test.heif").unwrap();
        let err = lh::heif_context_read_from_file(
            ctx,
            c_name.as_ptr(),
            ptr::null()
        );
        assert_eq!(err.code, lh::heif_error_code_heif_error_Ok);

        let mut handle = ptr::null_mut();
        let err = lh::heif_context_get_primary_image_handle(
            ctx,
            &mut handle
        );
        assert_eq!(err.code, lh::heif_error_code_heif_error_Ok);
        assert!(!handle.is_null());

        let width = lh::heif_image_handle_get_width(handle);
        assert_eq!(width, 4032);
        let height = lh::heif_image_handle_get_height(handle);
        assert_eq!(height, 3024);

        let mut image = ptr::null_mut();
        let options = lh::heif_decoding_options_alloc();
        let err = lh::heif_decode_image(
            handle,
            &mut image,
            lh::heif_colorspace_heif_colorspace_RGB,
            lh::heif_chroma_heif_chroma_interleaved_RGB,
            options,
        );
        lh::heif_decoding_options_free(options);
        assert_eq!(err.code, lh::heif_error_code_heif_error_Ok);
        assert!(!image.is_null());

        let colorspace = lh::heif_image_get_colorspace(image);
        assert_eq!(
            colorspace,
            lh::heif_colorspace_heif_colorspace_RGB
        );
        let chroma_format = lh::heif_image_get_chroma_format(image);
        assert_eq!(
            chroma_format,
            lh::heif_chroma_heif_chroma_interleaved_RGB
        );
        let width = lh::heif_image_get_width(
            image,
            lh::heif_channel_heif_channel_interleaved
        );
        assert_eq!(width, 4032);
        let height = lh::heif_image_get_height(
            image,
            lh::heif_channel_heif_channel_interleaved
        );
        assert_eq!(height, 3024);

        lh::heif_context_free(ctx);

        lh::heif_deinit();
    };
}