Crates.io | exr |
lib.rs | exr |
version | 1.73.0 |
source | src |
created_at | 2020-02-15 16:55:49.210752 |
updated_at | 2024-10-31 07:55:23.807392 |
description | Read and write OpenEXR files without any unsafe code |
homepage | |
repository | https://github.com/johannesvollmer/exrs |
max_upload_size | |
id | 209515 |
size | 1,875,314 |
This library is a 100% Rust and 100% safe code library for reading and writing OpenEXR images.
OpenEXR is the de-facto standard image format in animation, VFX, and other computer graphics pipelines, for it can represent an immense variety of pixel data with lossless compression.
Features include:
This library has matured quite a bit, but should still be considered incomplete. For example, deep data and DWA compression algorithms are not supported yet.
If you encounter an exr file that cannot be opened by this crate but should be, please leave an issue on this repository, containing the image file.
The focus is set on supporting all feature and correctness; some performance optimizations are to be done.
What we can do:
Supported OpenEXR Features
Nice Things
no unsafe code, no undefined behaviour
no CMake required or environment variables required
re-imagined exr api with low barrier of entry
(see read_rgba_file
, write_rgba_file
, read_all_data_from_file
),
plus embracing common high-level Rust abstractions
a full-fledged image data structure that can contain any exr image,
can open any image with a single function call (read_all_data_from_file
)
without knowing anything about the file in advance
compress and decompress image sections either in parallel or with low memory overhead
read and write progress callback
write blocks streams, one after another
memory mapping automatically supported
by using the generic std::io::Read
and std::io::Write
traits
[!TIP] If you want to use the newest version of
exrs
with an older Rust version, you can still do that, by forcing Rust to use an older version of thehalf
crate viacargo update -p half --precise 2.2.1
, or downgrade all dependencies viacargo +nightly -Zminimal-versions generate-lockfile
. Versionhalf 2.3.0
and higher have an MSRV above 1.61.
Add this to your Cargo.toml
:
[dependencies]
exr = "1.73.0"
# also, optionally add this to your crate for smaller binary size
# and better runtime performance
[profile.release]
lto = true
The master branch of this repository always matches the crates.io
version,
so you could also link the github repository master branch.
Example: generate an rgb exr file.
extern crate exr;
/// To write your image data, you need to specify how to retrieve a single pixel from it.
/// The closure may capture variables or generate data on the fly.
fn main() {
use exr::prelude::*;
// write a file, with 32-bit float precision per channel
write_rgba_file(
// this accepts paths or &str
"minimal_rgba.exr",
// image resolution is 2k
2048, 2048,
// generate (or lookup in your own image)
// an f32 rgb color for each of the 2048x2048 pixels
// (you could also create f16 values here to save disk space)
|x,y| {
(
x as f32 / 2048.0, // red
y as f32 / 2048.0, // green
1.0 - (y as f32 / 2048.0), // blue
1.0 // alpha
)
}
).unwrap();
}
See the the examples folder for more examples.
Or read the guide.
exrs
aims to provide a safe and convenient
interface to the OpenEXR file format. It is designed
to minimize the possibility of invalid files and runtime errors.
It contains a full-fledged image data structure that can contain any exr image,
but also grants access a low level block interface.
This library does not try to be a general purpose image file or image processing library. Therefore, color conversion, beautiful subsampling, and mip map generation are left to other crates for now. As the original OpenEXR implementation supports those operations, this library may choose to support them later. Furthermore, this implementation does not try to produce byte-exact file output matching the original implementation, instead, it is only aimed for correct output.
This library uses no unsafe code. In fact, this crate is annotated with #[forbid(unsafe_code)]
.
Some dependencies use unsafe code, though this is minimized by selecting dependencies carefully.
All information from a file is handled with caution. Allocations have a safe maximum size that will not be exceeded at once, to reduce memory exhaustion attacks.
This crate supports the wasm-unknown-unknown
target.
Until WASM has threads, decoding and encoding will be slower for compressed files.
Of course, you will need to read from byte buffers instead of file handles.
This library does not support the toxic mindset of rewriting existing C++ code in Rust just for the sake of switching the language. The OpenEXR image format is defined by a proven and battle-tested reference implementation.
However, as an alternative to the official reference implementation, this library has the opportunity to explore radically different designs, no matter what language it is written in. Neat!
Also, I really wanted to have a library which had an 'X' in its name in my git repositories.
Keep in mind that there are official Rust bindings to the C++ reference implementation, and they offer several advantages over this Rust implementation:
This library is modeled after the
official OpenEXRFileLayout.pdf
document. Unspecified behavior is concluded from the C++ library.
This project has awesome contributors and is welcoming for contributions on Github.
To run all fast tests on your native system, use cargo test
.
To start fuzzing on your native system indefinitely,
use cargo test --package exr --test fuzz fuzz -- --exact --ignored
.
To run all fast tests on an emulated system, use one of the following commands.
Each command requires a running docker
instance,
and cross-rs
to be installed on your machine (cargo install cross
).
cross test --target mips-unknown-linux-gnu --verbose
To benchmark the library, simply run cargo bench
.