Glycin
Glycin allows to decode images into gdk::Textures and to extract image metadata.
The decoding happens in sandboxed modular image loaders.
- glycin – The image library
- glycin-utils – Utilities to write loaders for glycin
- loaders – Glycin loaders for several formats
Example
let file = for_path;
let image = new.request.await?;
let height = image.info.height;
let texture = image.next_frame.await?;
Image loader configuration
Loader configurations are read from XDG_DATA_DIRS and XDG_DATA_HOME. The location is typically of the from
<data-dir>/share/glycin/<compat-version>+/conf.d/<loader-name>.conf
so for example
<data-dir>/share/glycin/0+/conf.d/glyicn-image-rs.conf
The configs are glib KeyFiles of the the form
[loader:image/png]
Exec = /usr/libexec/glycin/0+/glycin-image-rs
Where the part behind loader is a mime-type and the value of Exec can be any executable path.
Existing compatibility versions
Not every new major version of the library has to break compatibility with the loaders. The formal definition is available in docs/. The following compatibility versions currently exist
| compat-version |
|---|
| 0+ |
| 1+ |
Supported image formats
The following features are supported by the glycin loaders provided in the loaders directory.
| Format | Decoder | ICC | CICP | EXIF | XMP | Animation | Library |
|---|---|---|---|---|---|---|---|
| AVIF | heif | ✔ | ✔ | ✔ | ✘ | ✘ | libheif-rs + libheif (C++) |
| BMP | image-rs | ✘ | — | — | — | — | image-rs |
| DDS | image-rs | — | — | — | — | — | image-rs |
| farbfeld | no mime | — | — | — | — | — | image-rs |
| QOI | image-rs | — | — | — | — | — | image-rs |
| GIF | image-rs | ✘ * | — | — | ✘ | ✔ | image-rs |
| HEIC | heif | ✔ | ✔ | ✔ | ✘ | ✘ | libheif-rs + libheif (C++) |
| ICO | image-rs | — | — | — | — | — | image-rs |
| JPEG | image-rs | ✔ | — | ✔ | ✘ | — | image-rs |
| JPEG 2000 | TODO | ✘ | — | ✘ | ? | ✘ | jpeg2k? + openjpeg (C) |
| JPEG XL | jxl | ✔ | ✘ | ✘ | ✘ | ✘ | jxl-oxide |
| OpenEXR | image-rs | — | — | — | — | — | image-rs |
| PNG | image-rs | ✔ | ✘ | ✔ | ✘ | ✔ | image-rs |
| PNM | image-rs | — | — | — | — | — | image-rs |
| SVG | image-rs | ✘ | — | — | ✘ * | — | librsvg + gdk-pixbuf |
| TGA | image-rs | — | — | — | — | — | image-rs |
| TIFF | image-rs | ✔ | — | ✔ | ✘ | — | image-rs |
| WEBP | image-rs | ✔ | — | ✔ | ✘ | ✔ | image-rs + libwebp (C) |
| Symbol | Meaning |
|---|---|
| ✔ | Supported |
| ✘ | Supported by format but not implemented yet |
| — | Not available for this format |
| ? | Unclear if supported by format, needs research |
| * | Unclear if used in practice, needs research |
Building and Testing
- The
-Dloadersoption allows to only build certain loaders. - The
-Dtest_skip_extoption allows to skip certain image filename extensions during tests. The-Dtest_skip_ext=heicmight be needed if x265 is not available. - Running integration tests requires the glycin loaders to be installed. By default this is done by
meson testautomatically. This behavior can be changed by setting-Dtest_skip_install=true.
Inner Workings
Glycin spawns one sandboxed process per image file via bwrap or flatpak-spawn. The communication happens via peer-to-peer D-Bus over a UNIX socket. The file data is read from a GFile and sent to the sandbox via a separate UNIX socket. The texture data is provided from the sandbox via a memfd that is sealed afterward and given as an mmap to GTK. For animations and SVGs the sandboxed process is kept alive for new frames or tiles as long as needed.
To implement a new loader, please consult the glycin-utils docs.
License
SPDX-License-Identifier: MPL-2.0 OR LGPL-2.1-or-later