improve build times by extracting asset opt into its own crate (#3273)

* improve build types by extracing asset opt as a dylib
* dont use dylib, but let regular workspace caching do the heavy lifting
* add prebuild to cli for better lock contention
* hoist deps
* disable slow tests
* re-enable sequential, debug=0 for dev
* use vfs for windows
* dont cache on failure, fix windows vfs caceh
* free disk space re-order
* add clippy + fmt to windows channel
* yoink makefile
* proper rustfmt/clippy on toolchain
* set incremental to zero since cargo-cache disables it
This commit is contained in:
Jonathan Kelley authored and GitHub committed 2024-12-02 16:52:40 -08:00
1 parent 79a2f023e7
commit 1cbfcde6cd
25 files changed
+550 -554

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
use image::{DynamicImage, EncodableLayout};
use std::{
io::{BufWriter, Write},
path::Path,
};
pub(crate) fn compress_jpg(image: DynamicImage, output_location: &Path) -> anyhow::Result<()> {
let mut comp = mozjpeg::Compress::new(mozjpeg::ColorSpace::JCS_EXT_RGBX);
let width = image.width() as usize;
let height = image.height() as usize;
comp.set_size(width, height);
let mut comp = comp.start_compress(Vec::new())?; // any io::Write will work
comp.write_scanlines(image.to_rgba8().as_bytes())?;
let jpeg_bytes = comp.finish()?;
let file = std::fs::File::create(output_location)?;
let w = &mut BufWriter::new(file);
w.write_all(&jpeg_bytes)?;
Ok(())
}
+62
View File
@@ -0,0 +1,62 @@
use std::path::Path;
use anyhow::Context;
use jpg::compress_jpg;
use manganis_core::{ImageAssetOptions, ImageFormat, ImageSize};
use png::compress_png;
mod jpg;
mod png;
pub(crate) fn process_image(
image_options: &ImageAssetOptions,
source: &Path,
output_path: &Path,
) -> anyhow::Result<()> {
let mut image = image::ImageReader::new(std::io::Cursor::new(&*std::fs::read(source)?))
.with_guessed_format()?
.decode();
if let Ok(image) = &mut image {
if let ImageSize::Manual { width, height } = image_options.size() {
*image = image.resize_exact(width, height, image::imageops::FilterType::Lanczos3);
}
}
match (image, image_options.format()) {
(image, ImageFormat::Png) => {
compress_png(image?, output_path);
}
(image, ImageFormat::Jpg) => {
compress_jpg(image?, output_path)?;
}
(Ok(image), ImageFormat::Avif) => {
if let Err(error) = image.save(output_path) {
tracing::error!("Failed to save avif image: {} with path {}. You must have the avif feature enabled to use avif assets", error, output_path.display());
}
}
(Ok(image), ImageFormat::Webp) => {
if let Err(err) = image.save(output_path) {
tracing::error!("Failed to save webp image: {}. You must have the avif feature enabled to use webp assets", err);
}
}
(Ok(image), _) => {
image.save(output_path)?;
}
// If we can't decode the image or it is of an unknown type, we just copy the file
_ => {
let source_file = std::fs::File::open(source)?;
let mut reader = std::io::BufReader::new(source_file);
let output_file = std::fs::File::create(output_path)?;
let mut writer = std::io::BufWriter::new(output_file);
std::io::copy(&mut reader, &mut writer).with_context(|| {
format!(
"Failed to write image to output location: {}",
output_path.display()
)
})?;
}
}
Ok(())
}
+52
View File
@@ -0,0 +1,52 @@
use std::{io::BufWriter, path::Path};
use image::DynamicImage;
pub(crate) fn compress_png(image: DynamicImage, output_location: &Path) {
// Image loading/saving is outside scope of this library
let width = image.width() as usize;
let height = image.height() as usize;
let bitmap: Vec<_> = image
.into_rgba8()
.pixels()
.map(|px| imagequant::RGBA::new(px[0], px[1], px[2], px[3]))
.collect();
// Configure the library
let mut liq = imagequant::new();
liq.set_speed(5).unwrap();
liq.set_quality(0, 99).unwrap();
// Describe the bitmap
let mut img = liq.new_image(&bitmap[..], width, height, 0.0).unwrap();
// The magic happens in quantize()
let mut res = match liq.quantize(&mut img) {
Ok(res) => res,
Err(err) => panic!("Quantization failed, because: {err:?}"),
};
let (palette, pixels) = res.remapped(&mut img).unwrap();
let file = std::fs::File::create(output_location).unwrap();
let w = &mut BufWriter::new(file);
let mut encoder = png::Encoder::new(w, width as u32, height as u32);
encoder.set_color(png::ColorType::Rgba);
let mut flattened_palette = Vec::new();
let mut alpha_palette = Vec::new();
for px in palette {
flattened_palette.push(px.r);
flattened_palette.push(px.g);
flattened_palette.push(px.b);
alpha_palette.push(px.a);
}
encoder.set_palette(flattened_palette);
encoder.set_trns(alpha_palette);
encoder.set_depth(png::BitDepth::Eight);
encoder.set_color(png::ColorType::Indexed);
encoder.set_compression(png::Compression::Best);
let mut writer = encoder.write_header().unwrap();
writer.write_image_data(&pixels).unwrap();
writer.finish().unwrap();
}