diff --git a/CHANGELOG.md b/CHANGELOG.md index dfeba9b7..4e66db81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ **Version 0.9.0 (unreleased)** - [SEMVER_MAJOR] Significant refactoring of modules - Use `itertools` to cleanup areas of code + - Use multiple threads for filtering trials **Version 0.8.2** - Fix issue where images smaller than 4px width would crash on interlacing ([#42](https://github.com/shssoichiro/oxipng/issues/42)) diff --git a/src/lib.rs b/src/lib.rs index 67e2da6d..d522be34 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -371,22 +371,33 @@ fn optimize_png(mut png: &mut png::PngData, file_original_size: usize, opts: &Op let best: Arc>> = Arc::new(Mutex::new(None)); let combinations = filter.len() * compression.len() * memory.len() * strategies.len(); let mut results: Vec<(u8, u8, u8, u8)> = Vec::with_capacity(combinations); - let mut filters: HashMap> = HashMap::with_capacity(filter.len()); + let filters: Arc>>> = + Arc::new(Mutex::new(HashMap::with_capacity(filter.len()))); if opts.verbosity.is_some() { writeln!(&mut stderr(), "Trying: {} combinations", combinations).ok(); } - for f in &filter { - let filtered = png.filter_image(*f); - filters.insert(*f, filtered.clone()); - for zc in &compression { - for zm in &memory { - for zs in &strategies { - results.push((*f, *zc, *zm, *zs)); + pool.scoped(|scope| { + for f in &filter { + let png = png.clone(); + let filters = filters.clone(); + for zc in &compression { + for zm in &memory { + for zs in &strategies { + results.push((*f, *zc, *zm, *zs)); + } } } + scope.execute(move || { + let filtered = png.filter_image(*f); + let mut filters = filters.lock().unwrap(); + filters.insert(*f, filtered); + }); } - } + }); + + let filters = filters.lock().unwrap(); + pool.scoped(|scope| { let original_len = png.idat_data.len(); let interlacing_changed = opts.interlace.is_some() &&