• Stars
    star
    1,383
  • Rank 33,990 (Top 0.7 %)
  • Language
    C++
  • License
    Other
  • Created almost 7 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

libheif is an HEIF and AVIF file format decoder and encoder.

libheif

Build Status Build Status Coverity Scan Build Status

libheif is an ISO/IEC 23008-12:2017 HEIF and AVIF (AV1 Image File Format) file format decoder and encoder. There is partial support for ISO/IEC 23008-12:2022 (2nd Edition) capabilities.

HEIF and AVIF are new image file formats employing HEVC (H.265) or AV1 image coding, respectively, for the best compression ratios currently possible.

libheif makes use of libde265 for HEIF image decoding and x265 for encoding. For AVIF, libaom, dav1d, svt-av1, or rav1e are used as codecs.

Supported features

libheif has support for decoding:

  • tiled images
  • alpha channels
  • thumbnails
  • reading EXIF and XMP metadata
  • reading the depth channel
  • multiple images in a file
  • image transformations (crop, mirror, rotate)
  • overlay images
  • plugin interface to add alternative codecs for additional formats (AVC, JPEG)
  • decoding of files while downloading (e.g. extract image size before file has been completely downloaded)
  • reading color profiles
  • heix images (10 and 12 bit, chroma 4:2:2)

The encoder supports:

  • lossy compression with adjustable quality
  • lossless compression
  • alpha channels
  • thumbnails
  • save multiple images to a file
  • save EXIF and XMP metadata
  • writing color profiles
  • 10 and 12 bit images
  • monochrome images

API

The library has a C API for easy integration and wide language support. Note that the API is still work in progress and may still change.

The decoder automatically supports both HEIF and AVIF through the same API. No changes are required to existing code to support AVIF. The encoder can be switched between HEIF and AVIF simply by setting heif_compression_HEVC or heif_compression_AV1 to heif_context_get_encoder_for_format().

Loading the primary image in an HEIF file is as easy as this:

heif_context* ctx = heif_context_alloc();
heif_context_read_from_file(ctx, input_filename, nullptr);

// get a handle to the primary image
heif_image_handle* handle;
heif_context_get_primary_image_handle(ctx, &handle);

// decode the image and convert colorspace to RGB, saved as 24bit interleaved
heif_image* img;
heif_decode_image(handle, &img, heif_colorspace_RGB, heif_chroma_interleaved_RGB, nullptr);

int stride;
const uint8_t* data = heif_image_get_plane_readonly(img, heif_channel_interleaved, &stride);

// ... process data as needed ...

// clean up resources
heif_image_release(img);
heif_image_handle_release(handle);
heif_context_free(ctx);

Writing an HEIF file can be done like this:

heif_context* ctx = heif_context_alloc();

// get the default encoder
heif_encoder* encoder;
heif_context_get_encoder_for_format(ctx, heif_compression_HEVC, &encoder);

// set the encoder parameters
heif_encoder_set_lossy_quality(encoder, 50);

// encode the image
heif_image* image; // code to fill in the image omitted in this example
heif_context_encode_image(ctx, image, encoder, nullptr, nullptr);

heif_encoder_release(encoder);

heif_context_write_to_file(ctx, "output.heic");

heif_context_free(ctx);

Get the EXIF data from an HEIF file:

heif_item_id exif_id;

int n = heif_image_handle_get_list_of_metadata_block_IDs(image_handle, "Exif", &exif_id, 1);
if (n==1) {
  size_t exifSize = heif_image_handle_get_metadata_size(image_handle, exif_id);
  uint8_t* exifData = malloc(exifSize);
  struct heif_error error = heif_image_handle_get_metadata(image_handle, exif_id, exifData);
}

See the header file heif.h for the complete C API.

There is also a C++ API which is a header-only wrapper to the C API. Hence, you can use the C++ API and still be binary compatible. Code using the C++ API is much less verbose than using the C API directly.

There is also an experimental Go API, but this is not stable yet.

Compiling

This library uses the CMake build system (the earlier autotools build files have been removed in v1.16.0).

Make sure that you compile and install libde265 first, so that the configuration script will find this. Also install x265 and its development files if you want to use HEIF encoding.

The basic build steps are as follows:

mkdir build
cd build
cmake --preset=release ..
make

There are CMake presets to cover the most frequent use cases.

  • release: the preferred preset which compiles all codecs as separate plugins. If you do not want to distribute some of these plugins (e.g. HEIC), you can omit packaging these.
  • release-noplugins: this is a smaller, self-contained build of libheif without using the plugin system. A single library is built with support for HEIC and AVIF.
  • testing: for building and executing the unit tests. Also the internal library symbols are exposed. Do not use for distribution.
  • fuzzing: similar to testing, this builds the fuzzers. The library should not distributed.

You can optionally adapt these standard configurations to your needs. This can be done, for example, by calling ccmake .. from within the build directory.

macOS

  1. Install dependencies with Homebrew

    brew install cmake make pkg-config x265 libde265 libjpeg libtool
  2. Configure and build project

    mkdir build
    cd build
    cmake --preset=release ..
    ./configure
    make

Windows

You can build and install libheif using the vcpkg dependency manager:

git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.bat
./vcpkg integrate install
./vcpkg install libheif

The libheif port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request on the vcpkg repository.

Adding libaom encoder/decoder for AVIF

  • Run the aom.cmd script in the third-party directory to download libaom and compile it.

When running cmake or configure, make sure that the environment variable PKG_CONFIG_PATH includes the absolute path to third-party/aom/dist/lib/pkgconfig.

Adding rav1e encoder for AVIF

  • Install cargo.
  • Install cargo-c by executing
cargo install --force cargo-c
  • Run the rav1e.cmd script in the third-party directory to download rav1e and compile it.

When running cmake, make sure that the environment variable PKG_CONFIG_PATH includes the absolute path to third-party/rav1e/dist/lib/pkgconfig.

Adding dav1d decoder for AVIF

  • Install meson.
  • Run the dav1d.cmd script in the third-party directory to download dav1d and compile it.

When running cmake, make sure that the environment variable PKG_CONFIG_PATH includes the absolute path to third-party/dav1d/dist/lib/x86_64-linux-gnu/pkgconfig.

Adding SVT-AV1 encoder for AVIF

You can either use the SVT-AV1 encoder libraries installed in the system or use a self-compiled current version. If you want to compile SVT-AV1 yourself,

  • Run the svt.cmd script in the third-party directory to download SVT-AV1 and compile it.

When running cmake or configure, make sure that the environment variable PKG_CONFIG_PATH includes the absolute path to third-party/SVT-AV1/Build/linux/Release. You may have to replace linux in this path with your system's identifier.

You have to enable SVT-AV1 with CMake.

Codec plugins

Starting with v1.14.0, each codec backend can be compiled statically into libheif or as a dynamically loaded plugin (currently Linux only). You can choose this individually for each codec backend in the CMake settings. Compiling a codec backend as dynamic plugin will generate a shared library that is installed in the system together with libheif. The advantage is that only the required plugins have to be installed and libheif has fewer dependencies.

The plugins are loaded from the colon-separated (semicolon-separated on Windows) list of directories stored in the environment variable LIBHEIF_PLUGIN_PATH. If this variable is empty, they are loaded from a directory specified in the CMake configuration. You can also add plugin directories programmatically.

Encoder benchmark

A current benchmark of the AVIF encoders (as of 14 Oct 2022) can be found on the Wiki page AVIF encoding benchmark.

Language bindings

Languages that can directly interface with C libraries (e.g., Swift, C#) should work out of the box.

Compiling to JavaScript

libheif can also be compiled to JavaScript using emscripten. See the build-emscripten.sh for further information.

Online demo

Check out this online demo. This is libheif running in JavaScript in your browser.

Example programs

Some example programs are provided in the examples directory. The program heif-convert converts all images stored in an HEIF/AVIF file to JPEG or PNG. heif-enc lets you convert JPEG files to HEIF/AVIF. The program heif-info is a simple, minimal decoder that dumps the file structure to the console.

For example convert example.heic to JPEGs and one of the JPEGs back to HEIF:

cd examples/
./heif-convert example.heic example.jpeg
./heif-enc example-1.jpeg -o example.heif

In order to convert example-1.jpeg to AVIF use:

./heif-enc example-1.jpeg -A -o example.avif

There is also a GIMP plugin using libheif here.

HEIF/AVIF thumbnails for the Gnome desktop

The program heif-thumbnailer can be used as an HEIF/AVIF thumbnailer for the Gnome desktop. The matching Gnome configuration files are in the gnome directory. Place the files heif.xml and avif.xml into /usr/share/mime/packages and heif.thumbnailer into /usr/share/thumbnailers. You may have to run update-mime-database /usr/share/mime to update the list of known MIME types.

gdk-pixbuf loader

libheif also includes a gdk-pixbuf loader for HEIF/AVIF images. 'make install' will copy the plugin into the system directories. However, you will still have to run gdk-pixbuf-query-loaders --update-cache to update the gdk-pixbuf loader database.

Software using libheif

Packaging status

libheif packaging status

Sponsors

Since I work as an independent developer, I need your support to be able to allocate time for libheif. You can sponsor the development using the link in the right hand column.

A big thank you goes to these major sponsors for supporting the development of libheif:

  • Shopify shopify-logo
  • StrukturAG

License

The libheif is distributed under the terms of the GNU Lesser General Public License. The sample applications are distributed under the terms of the MIT License.

See COPYING for more details.

Copyright (c) 2017-2020 Struktur AG
Copyright (c) 2017-2023 Dirk Farin
Contact: Dirk Farin [email protected]

More Repositories

1

libde265

Open h.265 video codec implementation.
C++
1,573
star
2

spreed-webrtc

WebRTC audio/video call and conferencing server.
JavaScript
1,077
star
3

libde265.js

JavaScript-only version of libde265 HEVC/H.265 decoder.
JavaScript
573
star
4

nextcloud-spreed-signaling

Standalone signaling server for Nextcloud Talk.
Go
322
star
5

docker-webrtc-turnserver

Docker image for a TURN server suitable for WebRTC
Shell
97
star
6

vlc-libde265

Standalone plugin for VLC 2.x to support decoding of HEVC/H.265 using libde265.
C
89
star
7

gstreamer-libde265

HEVC/H.265 video decoder using libde265 (GStreamer plugin)
C
59
star
8

nextcloud-spreedme

Spreed.ME Nextcloud app
JavaScript
55
star
9

VLCKit

Fork of http://git.videolan.org/?p=vlc-bindings/VLCKit.git to integrate a version of VLC supporting libde265.
Objective-C
51
star
10

vlc-2.1

Fork of http://git.videolan.org/?p=vlc/vlc-2.1.git to integrate libde265. Main integration development happens in https://github.com/strukturag/vlc.
C
51
star
11

pdfdraw

Nextcloud app to annotate PDF documents
JavaScript
42
star
12

libde265-ffmpeg

h.265 codec for ffmpeg using libde265
C
40
star
13

heif-gimp-plugin

Plugin for GIMP to load HEIF files.
C
23
star
14

phoenix

Go library providing support functionality for application startup, configuration, logging, and profiling.
Go
17
star
15

vlc-ports-ios

Fork of git://git.videolan.org/vlc-ports/ios.git to integrate a version of VLC supporting libde265.
Objective-C
9
star
16

vlc-2.2

Fork of http://git.videolan.org/?p=vlc/vlc-2.2.git to integrate libde265.
C
8
star
17

httputils

Go support library for HTTP servers.
Go
7
star
18

libde265-data

Example video stream data for libde265.
6
star
19

spreedme-iosapp

Spreed.ME iOS app
Objective-C
6
star
20

xudnsd

Tiny single host/IP DNS server
Go
4
star
21

tlsdumpster

TLS dumpster prints incoming TLS requests details (host, url, headers and body) to stdout and aborts the request with HTTP status 500.
Go
4
star
22

sloth

Tiny REST framework for Go
Go
3
star
23

gst-plugins-good

GStreamer "good" plugins with support for HEVC/H.265 decoding using libde265
C
3
star
24

webrtc-ios

WebRTC fork for Spreed.ME iOS app
C++
3
star
25

spreed-turnservicecli

TURN service client implementation for Go
Go
3
star
26

sling

Go support library for HTTP clients
Go
3
star
27

goacceptlanguageparser

Go library for parsing HTTP request header "Accept-Language".
Go
2
star
28

file-browser-ios

File browser for iOS
Objective-C
2
star
29

SortedDictionary

Sorted dictionary class for iOS/ macOS
Objective-C
2
star
30

spreed-webrtc-snap

Spreed WebRTC Ubuntu Snappy Snapcraft build repository.
Python
2
star
31

lavfilters-ffmpeg

ffmpeg with custom patches for LAV Filters (deprecated and no longer required by https://github.com/strukturag/LAVFilters)
C
2
star
32

gst-plugins-bad

GStreamer "bad" plugins with support for HEVC/H.265 decoding using libde265
C
2
star