mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-17 23:38:06 +08:00
Raw-rs: run tests in parallel (#1968)
* Run raw-rs tests in parallel * cargo fmt * Fix clippy warnings * Use Fast CompressionType to speed up the tests * Fix benches * Use cfg_attr instead of cfg. --------- Co-authored-by: hypercube <0hypercube@gmail.com> Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
@@ -13,7 +13,7 @@ repository = "https://github.com/GraphiteEditor/Graphite/tree/master/libraries/r
|
||||
documentation = "https://docs.rs/raw-rs"
|
||||
|
||||
[features]
|
||||
raw-rs-tests = ["dep:image", "dep:libraw-rs", "dep:reqwest"]
|
||||
raw-rs-tests = ["dep:image", "dep:libraw-rs", "dep:reqwest", "dep:rayon"]
|
||||
|
||||
[dependencies]
|
||||
# Local dependencies
|
||||
@@ -33,3 +33,4 @@ reqwest = { workspace = true, optional = true }
|
||||
|
||||
# Optional dependencies (should be dev dependencies, but Cargo currently doesn't allow optional dev dependencies)
|
||||
libraw-rs = { version = "0.0.4", optional = true }
|
||||
rayon = { version = "1.10.0", optional = true }
|
||||
|
||||
@@ -6,11 +6,13 @@ use raw_rs::RawImage;
|
||||
use image::codecs::png::{CompressionType, FilterType, PngEncoder};
|
||||
use image::{ColorType, ImageEncoder};
|
||||
use libraw::Processor;
|
||||
use rayon::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Write;
|
||||
use std::fs::{create_dir, metadata, read_dir, File};
|
||||
use std::io::{BufWriter, Cursor, Read};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::time::Duration;
|
||||
|
||||
const TEST_FILES: [&str; 3] = ["ILCE-7M3-ARW2.3.5-blossoms.arw", "ILCE-7RM4-ARW2.3.5-kestrel.arw", "ILCE-6000-ARW2.3.1-windsock.arw"];
|
||||
@@ -21,52 +23,74 @@ const BASE_PATH: &str = "./tests/images/";
|
||||
fn test_images_match_with_libraw() {
|
||||
download_images();
|
||||
|
||||
let mut failed_tests = 0;
|
||||
|
||||
read_dir(BASE_PATH)
|
||||
let paths: Vec<_> = read_dir(BASE_PATH)
|
||||
.unwrap()
|
||||
.map(|dir_entry| dir_entry.unwrap().path())
|
||||
.filter(|path| path.is_file() && path.file_name().map(|file_name| file_name != ".gitkeep").unwrap_or(false))
|
||||
.for_each(|path| {
|
||||
let mut f = File::open(&path).unwrap();
|
||||
let mut content = vec![];
|
||||
f.read_to_end(&mut content).unwrap();
|
||||
.collect();
|
||||
|
||||
print!("{} => ", path.display());
|
||||
let failed_tests = if std::env::var("RAW_RS_TEST_RUN_SEQUENTIALLY").is_ok() {
|
||||
let mut failed_tests = 0;
|
||||
|
||||
let raw_image = match test_raw_data(&content) {
|
||||
Err(err_msg) => {
|
||||
failed_tests += 1;
|
||||
return println!("{}", err_msg);
|
||||
}
|
||||
Ok(raw_image) => raw_image,
|
||||
};
|
||||
|
||||
// TODO: The code below is kept commented because raw data to final image processing is
|
||||
// incomplete. Remove this once it is done.
|
||||
|
||||
// if let Err(err_msg) = test_final_image(&content, raw_image) {
|
||||
// failed_tests += 1;
|
||||
// return println!("{}", err_msg);
|
||||
// };
|
||||
|
||||
println!("Passed");
|
||||
|
||||
// TODO: Remove this later
|
||||
let mut image = raw_rs::process_8bit(raw_image);
|
||||
store_image(&path, "raw_rs", &mut image.data, image.width, image.height);
|
||||
|
||||
let processor = Processor::new();
|
||||
let libraw_image = processor.process_8bit(&content).unwrap();
|
||||
let mut data = Vec::from_iter(libraw_image.iter().copied());
|
||||
store_image(&path, "libraw_rs", &mut data[..], libraw_image.width() as usize, libraw_image.height() as usize);
|
||||
paths.iter().for_each(|path| {
|
||||
if !test_image(path) {
|
||||
failed_tests += 1;
|
||||
}
|
||||
});
|
||||
|
||||
failed_tests
|
||||
} else {
|
||||
let failed_tests = AtomicUsize::new(0);
|
||||
|
||||
paths.par_iter().for_each(|path| {
|
||||
if !test_image(path) {
|
||||
failed_tests.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
});
|
||||
|
||||
failed_tests.load(Ordering::SeqCst)
|
||||
};
|
||||
|
||||
if failed_tests != 0 {
|
||||
panic!("{} images have failed the tests", failed_tests);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_image(path: &Path) -> bool {
|
||||
let mut f = File::open(path).unwrap();
|
||||
let mut content = vec![];
|
||||
f.read_to_end(&mut content).unwrap();
|
||||
|
||||
let raw_image = match test_raw_data(&content) {
|
||||
Err(err_msg) => {
|
||||
println!("{} => {}", path.display(), err_msg);
|
||||
return false;
|
||||
}
|
||||
Ok(raw_image) => raw_image,
|
||||
};
|
||||
|
||||
// TODO: The code below is kept commented because raw data to final image processing is
|
||||
// incomplete. Remove this once it is done.
|
||||
|
||||
// if let Err(err_msg) = test_final_image(&content, raw_image) {
|
||||
// failed_tests += 1;
|
||||
// return println!("{}", err_msg);
|
||||
// };
|
||||
|
||||
println!("{} => Passed", path.display());
|
||||
|
||||
// TODO: Remove this later
|
||||
let mut image = raw_rs::process_8bit(raw_image);
|
||||
store_image(path, "raw_rs", &mut image.data, image.width, image.height);
|
||||
|
||||
let processor = Processor::new();
|
||||
let libraw_image = processor.process_8bit(&content).unwrap();
|
||||
let mut data = Vec::from_iter(libraw_image.iter().copied());
|
||||
store_image(path, "libraw_rs", &mut data[..], libraw_image.width() as usize, libraw_image.height() as usize);
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn store_image(path: &Path, suffix: &str, data: &mut [u8], width: usize, height: usize) {
|
||||
let mut output_path = PathBuf::new();
|
||||
if let Some(parent) = path.parent() {
|
||||
@@ -85,7 +109,7 @@ fn store_image(path: &Path, suffix: &str, data: &mut [u8], width: usize, height:
|
||||
output_path.set_extension("png");
|
||||
|
||||
let file = BufWriter::new(File::create(output_path).unwrap());
|
||||
let png_encoder = PngEncoder::new_with_quality(file, CompressionType::Best, FilterType::Adaptive);
|
||||
let png_encoder = PngEncoder::new_with_quality(file, CompressionType::Fast, FilterType::Adaptive);
|
||||
png_encoder.write_image(data, width as u32, height as u32, ColorType::Rgb8.into()).unwrap();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user