Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenEXR basic support #1475

Merged
merged 47 commits into from
Jul 14, 2021
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
0ad1732
first ever exr prototype (not even compiled once)
johannesvollmer May 9, 2021
2e4e73a
use u16 for now (can easily be changed back to f32 again)
johannesvollmer May 9, 2021
11a8c2a
the minorest improvements (minor cleanup)
johannesvollmer May 10, 2021
958a4ac
Merge branch 'master' of https://github.com/image-rs/image into opene…
johannesvollmer Jun 1, 2021
2d6cf83
use newer exr library version with relaxed reader and writer bounds
johannesvollmer Jun 1, 2021
f0cccc0
update supported formats documentation (add exr, use camel case)
johannesvollmer Jun 1, 2021
307f7be
use f32 in writer and invert y
johannesvollmer Jun 1, 2021
5e90731
make it compile, with new exr version. also do not require seekable w…
johannesvollmer Jun 3, 2021
c7a0ef7
fix panic triggering for unsupported color types
johannesvollmer Jun 3, 2021
4367914
add tests to openexr module, load alpha only if present in file or re…
johannesvollmer Jun 4, 2021
57e6d8e
improve documentation: mention that writer argument should be buffered
johannesvollmer Jun 4, 2021
5487eb1
cosmetic improvements
johannesvollmer Jun 4, 2021
7ea5607
try adding an exr fuzzing script, rename exr test functions
johannesvollmer Jun 4, 2021
9b3f3b7
add test images (lol forgot that)
johannesvollmer Jun 4, 2021
a9073d1
add openexr feature flag to rust ci workflow
johannesvollmer Jun 4, 2021
dc534ac
try fix fuzzer, update readme format table from lib.rs,
johannesvollmer Jun 4, 2021
dccc0fe
add exr to other existing tests
johannesvollmer Jun 4, 2021
ad151b4
add exr to even more existing tests and documentation
johannesvollmer Jun 4, 2021
6d43853
remove exr from protected workflows file
johannesvollmer Jun 4, 2021
bf08b3b
remove exr error from public api
johannesvollmer Jun 4, 2021
6712173
implement original_color_type, add encoder trait implementation, remo…
johannesvollmer Jun 4, 2021
4df8dc2
use alpha flag in constructor instead of mutating the flag (avoiding …
johannesvollmer Jun 4, 2021
9ee062b
add docs to encoder wrapper
johannesvollmer Jun 4, 2021
724cc0c
remove commented-out functions
johannesvollmer Jun 4, 2021
fa1bf36
documentation improvements
johannesvollmer Jun 6, 2021
072fcfd
simplify imports, clarify reader buffering in documentation and remov…
johannesvollmer Jun 6, 2021
a3b2bda
rename exr to openexr, move ImageBuffer type alias definitions to the…
johannesvollmer Jun 6, 2021
465f927
remove outdated todo comment
johannesvollmer Jun 6, 2021
7198c5a
use display window instead of loading only the layer data
johannesvollmer Jun 7, 2021
6f3ea90
allow aligned buffers, make progress pub(crate), make image type alia…
johannesvollmer Jun 7, 2021
4276b44
implement trivial review suggestions
johannesvollmer Jun 23, 2021
61784de
Merge branch 'master' of https://github.com/image-rs/image into opene…
johannesvollmer Jun 23, 2021
6d7c802
bridge disconnected docs sections
johannesvollmer Jun 24, 2021
b18339d
make helper functions private (plus re-implement the helper methods c…
johannesvollmer Jun 25, 2021
495e990
re-implement more helper methods copy&paste for external fuzzer test …
johannesvollmer Jun 25, 2021
b3b349e
re-implement even more helper methods copy&paste for external fuzzer …
johannesvollmer Jun 25, 2021
9838118
simplify helper methodsfor external fuzzer test script
johannesvollmer Jun 25, 2021
5126f1b
fix unused crate import error
johannesvollmer Jun 25, 2021
d0c6872
fix more compiler errrors
johannesvollmer Jun 25, 2021
83148a3
fix fuzzer script compile errors
johannesvollmer Jun 25, 2021
d67a08b
fix fuzzer script compile errors
johannesvollmer Jun 25, 2021
6d729c9
unfix removing "unused imports"
johannesvollmer Jun 25, 2021
57a83b5
use overflow-safe size checks
johannesvollmer Jul 14, 2021
ab811e5
also check buffer dimensions in decoder, not only encoder
johannesvollmer Jul 14, 2021
9c6d68f
panic in decoder instead of returning an error
johannesvollmer Jul 14, 2021
4710fd7
when checking decoder buffer size, use strict equality, as declared i…
johannesvollmer Jul 14, 2021
899431f
re-trigger CI
johannesvollmer Jul 14, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ rgb = { version = "0.8.25", optional = true }
mp4parse = { version = "0.11.5", optional = true }
dav1d = { version = "0.6.0", optional = true }
dcv-color-primitives = { version = "0.1.16", optional = true }
exr = { version = "1.3.0", optional = true }
color_quant = "1.1"

[dev-dependencies]
Expand All @@ -47,7 +48,7 @@ criterion = "0.3"

[features]
# TODO: Add "avif" to this list while preparing for 0.24.0
default = ["gif", "jpeg", "ico", "png", "pnm", "tga", "tiff", "webp", "bmp", "hdr", "dxt", "dds", "farbfeld", "jpeg_rayon"]
default = ["gif", "jpeg", "ico", "png", "pnm", "tga", "tiff", "webp", "bmp", "hdr", "dxt", "dds", "farbfeld", "jpeg_rayon", "openexr"]

ico = ["bmp", "png"]
pnm = []
Expand All @@ -58,6 +59,7 @@ hdr = ["scoped_threadpool"]
dxt = []
dds = ["dxt"]
farbfeld = []
openexr = ["exr"]

# Enables multi-threading.
# Requires latest stable Rust.
Expand Down
4 changes: 3 additions & 1 deletion Cargo.toml.public-private-dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ tiff = { version = "0.6.0", optional = true }
ravif = { version = "0.6.0", optional = true }
rgb = { version = "0.8.25", optional = true }
color_quant = { version = "1.1", public = true }
exr = { version = "1.3.0", optional = true }

[dev-dependencies]
crc32fast = "1.2.0"
Expand All @@ -46,7 +47,7 @@ glob = "0.3"
quickcheck = "0.9"

[features]
default = ["gif", "jpeg", "ico", "png", "pnm", "tga", "tiff", "webp", "bmp", "hdr", "dxt", "dds", "jpeg_rayon"]
default = ["gif", "jpeg", "ico", "png", "pnm", "tga", "tiff", "webp", "bmp", "hdr", "dxt", "dds", "jpeg_rayon", "openexr"]

ico = ["bmp", "png"]
pnm = []
Expand All @@ -57,5 +58,6 @@ hdr = ["scoped_threadpool"]
dxt = []
dds = ["dxt"]
jpeg_rayon = ["jpeg/rayon"]
openexr = ["exr"]

benchmarks = []
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ All image processing functions provided operate on types that implement the `Gen
| PNG | All supported color types | Same as decoding |
| JPEG | Baseline and progressive | Baseline JPEG |
| GIF | Yes | Yes |
| BMP | Yes | RGB(8), RGBA(8), Gray(8), GrayA(8) |
johannesvollmer marked this conversation as resolved.
Show resolved Hide resolved
| BMP | Yes | Rgb8, Rgba8, Gray8, GrayA8 |
| ICO | Yes | Yes |
| TIFF | Baseline(no fax support) + LZW + PackBits | RGB(8), RGBA(8), Gray(8) |
| TIFF | Baseline(no fax support) + LZW + PackBits | Rgb8, Rgba8, Gray8 |
| WebP | Lossy(Luma channel only) | No |
| AVIF | Only 8-bit | Lossy |
| PNM | PBM, PGM, PPM, standard PAM | Yes |
| DDS | DXT1, DXT3, DXT5 | No |
| TGA | Yes | RGB(8), RGBA(8), BGR(8), BGRA(8), Gray(8), GrayA(8) |
| TGA | Yes | Rgb8, Rgba8, Bgr8, Bgra8, Gray8, GrayA8 |
| OpenEXR | Rgb32F, Rgba32F (no dwa compression) | Rgb32F, Rgba32F (no dwa compression) |
| farbfeld | Yes | Yes |

### The [`ImageDecoder`](https://docs.rs/image/*/image/trait.ImageDecoder.html) and [`ImageDecoderExt`](https://docs.rs/image/*/image/trait.ImageDecoderExt.html) Traits
Expand Down
4 changes: 4 additions & 0 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,7 @@ path = "fuzzers/fuzzer_script_ico.rs"
[[bin]]
name = "fuzzer_script_hdr"
path = "fuzzers/fuzzer_script_hdr.rs"

[[bin]]
name = "fuzzer_script_exr"
path = "fuzzers/fuzzer_script_exr.rs"
59 changes: 59 additions & 0 deletions fuzz/fuzzers/fuzzer_script_exr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#![no_main]
#[macro_use] extern crate libfuzzer_sys;
extern crate image;

use std::io::Cursor;
use image::ImageResult;
use image::codecs::openexr::*;
use image::Rgba32FImage;
use std::io::Seek;
use std::io::BufRead;
use std::convert::TryFrom;
use image::ImageDecoder;


// "just dont panic"
fn roundtrip(bytes: &[u8]) -> ImageResult<()> {
use std::io::Write;

/// Read the file from the specified path into an `Rgba32FImage`.
// TODO this method should probably already exist in the main image crate
fn read_as_rgba_byte_image(read: impl BufRead + Seek) -> ImageResult<(usize,usize,Vec<u8>)> {
let decoder = OpenExrDecoder::with_alpha_preference(read, Some(true))?;
let (width, height) = decoder.dimensions();

let mut buffer = vec![0; usize::try_from(decoder.total_bytes()).unwrap()];
decoder.read_image(buffer.as_mut_slice())?;

Ok((width, height, buffer))
}

/// Write an `Rgba32FImage`.
/// Assumes the writer is buffered. In most cases,
/// you should wrap your writer in a `BufWriter` for best performance.
// TODO this method should probably already exist in the main image crate
fn write_rgba_image(write: impl Write/* + Seek*/, image: &Rgba32FImage) -> ImageResult<()> {
OpenExrEncoder::new(write).write_image(
bytemuck::cast_slice(image.as_raw().as_slice()),
image.width(), image.height(),
ColorType::Rgba32F
)
}



let decoded_image = read_as_rgba_byte_image(Cursor::new(bytes))?;

let mut bytes = Vec::with_capacity(bytes.len() + 20);
write_rgba_image(Cursor::new(&mut bytes), &decoded_image)?;

let redecoded_image = read_as_rgba_byte_image(Cursor::new(bytes))?;

// if both images are valid, assert read/write consistency
assert_eq!(decoded_image, redecoded_image, "image was valid but was not reproducible");
Ok(())
}

fuzz_target!(|data: &[u8]| {
let _img = roundtrip(data); // fixme not optimized away?
});
14 changes: 13 additions & 1 deletion src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -896,8 +896,9 @@ where
/// Saves the buffer to a file at the path specified.
///
/// The image format is derived from the file extension.
/// Currently only jpeg, png, ico, pnm, bmp and
/// Currently only jpeg, png, ico, pnm, bmp and
/// tiff files are supported.
// TODO exr supported, but Rgba32F is not yet
pub fn save<Q>(&self, path: Q) -> ImageResult<()>
where
Q: AsRef<Path>,
Expand Down Expand Up @@ -948,6 +949,9 @@ where
{
/// Writes the buffer to a writer in the specified format.
///
/// Assumes the writer is buffered. In most cases,
/// you should wrap your writer in a `BufWriter` for best performance.
///
johannesvollmer marked this conversation as resolved.
Show resolved Hide resolved
/// See [`ImageOutputFormat`](../enum.ImageOutputFormat.html) for
/// supported types.
///
Expand Down Expand Up @@ -1340,6 +1344,14 @@ pub(crate) type Gray16Image = ImageBuffer<Luma<u16>, Vec<u16>>;
/// Sendable 16-bit grayscale + alpha channel image buffer
pub(crate) type GrayAlpha16Image = ImageBuffer<LumaA<u16>, Vec<u16>>;

/// An image buffer for 32-bit float RGB pixels,
/// where the backing container is a flattened vector of floats.
pub type Rgb32FImage = ImageBuffer<Rgb<f32>, Vec<f32>>;

/// An image buffer for 32-bit float RGBA pixels,
/// where the backing container is a flattened vector of floats.
pub type Rgba32FImage = ImageBuffer<Rgba<f32>, Vec<f32>>;

#[cfg(test)]
mod test {
use super::{ImageBuffer, RgbImage};
Expand Down
Loading