Skip to content

Commit

Permalink
avif decode on full rust.
Browse files Browse the repository at this point in the history
  • Loading branch information
mothsART committed Sep 14, 2024
1 parent 533baea commit aac0aad
Show file tree
Hide file tree
Showing 10 changed files with 273 additions and 56 deletions.
249 changes: 196 additions & 53 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ resvg="0.43"
usvg="0.43"
tiny-skia="0.11"
image = { version="0.25" }
avif-decode = "1.0"
markdown = "0.3"
colored = "2"
zip = "2"
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ ls *.svg | machmap -e avif
ls *.svg | machmap -e pdf
```

Convert avif files to png :

```zsh
ls *.avif | machmap -e png
```

Convert webp files to png, jpg and avif :

```zsh
Expand Down
Binary file added house_source_avif.avif
Binary file not shown.
1 change: 1 addition & 0 deletions src/bin/machmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ fn main() {
process::exit(exitcode::DATAERR);
}

println!("blue0");
for _l in readlines() {
if !Path::new(&_l).exists() {
colored_err!(format!("Input file \"{_l}\" doesn't exist"));
Expand Down
19 changes: 19 additions & 0 deletions src/machmap/avif/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use image::{ImageFormat, ImageReader};
use colored::Colorize;

use crate::machmap::{Error, HashMap, InputTo, AVIFInputFile};

impl<'a> AVIFInputFile<'a> {
pub fn new(input_file: &'a str, output_file: &'a str) -> AVIFInputFile<'a> {
convert_img!(AvifToPng, "avif", "png");
let png = AvifToPng::new(input_file, output_file);

let mut map: HashMap<&'a str, Box<dyn InputTo<'a> + 'a>> = HashMap::new();
map.insert("image/png", Box::new(png));
AVIFInputFile {
input_file,
output_file,
map,
}
}
}
24 changes: 23 additions & 1 deletion src/machmap/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,29 @@ macro_rules! convert_img {

impl<'a> InputTo<'a> for $struct_name<'a> {
fn convert(&self) -> Result<String, Box<dyn Error + 'a>> {
let img = ImageReader::open(&self.input_file)?.decode()?;
println!("before open avif");
let dyn_img = ImageReader::open(&self.input_file)?;
let format = ImageFormat::from_path(&self.input_file);
if format == Some(Avif) {
let data = std::fs::read(&self.input_file)?;
let d = Decoder::from_avif(&data)?;
let encoded = match d.to_image()? {
Image::Rgb8(img) => {
let (buf, width, height) = img.into_contiguous_buf();
lodepng::encode_memory(&buf, width, height, lodepng::ColorType::RGB, 8)
},
_ => {}
}?;
std::fs::write(&eslf.output_file, encoded);
Ok(format!(
"convert {} to {} : {} -> {}",
$input_name, $output_name, self.input_file, self.output_file,
))
}

println!("after open avif {:?}", ImageFormat::from_path(&self.input_file).ok());
let img = dyn_img.decode()?;
println!("after decode avif");
let format = ImageFormat::from_path(self.output_file)?;
if format == ImageFormat::Jpeg {
if img.color().has_alpha() {
Expand Down
18 changes: 16 additions & 2 deletions src/machmap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod macros;

pub mod jpg;
pub mod png;
pub mod avif;
pub mod webp;

pub mod markdown;
Expand All @@ -29,18 +30,22 @@ pub struct InputsFiles<'a> {

impl<'a> InputsFiles<'a> {
pub fn new(input_file: &'a str, output_file: &'a str) -> InputsFiles<'a> {
println!("yolo0");
let mut map: HashMap<&'a str, Box<dyn IFile + 'a>> = HashMap::new();
let svg = SVGInputFile::new(input_file, output_file);
let jpg = JPGInputFile::new(input_file, output_file);
let png = PNGInputFile::new(input_file, output_file);
let avif = AVIFInputFile::new(input_file, output_file);
let webp = WebpInputFile::new(input_file, output_file);
let markdown = MarkdownInputFile::new(input_file, output_file);
let yaml = YamlInputFile::new(input_file, output_file);
let json = JsonInputFile::new(input_file, output_file);

println!("yolo1");
map.insert("image/svg+xml", Box::new(svg));
map.insert("image/jpeg", Box::new(jpg));
map.insert("image/png", Box::new(png));
map.insert("image/avif", Box::new(avif));
map.insert("image/webp", Box::new(webp));
map.insert("text/markdown", Box::new(markdown));
map.insert("text/x-yaml", Box::new(yaml));
Expand Down Expand Up @@ -68,17 +73,25 @@ impl<'a> InputsFiles<'a> {
}

pub fn mime_map(&self) -> Result<String, Box<dyn Error + 'a>> {
println!("yolo2");
let input_mime = mime_guess::from_path(self.input_file);
println!("{:?}", input_mime);
let e = UnSupportedError {
input_file: self.input_file,
output_ext: self.output_file,
};
match &input_mime.first_raw() {
Some(i_mime) => match self.map.get(i_mime) {
Some(val) => val.mime_map(),
Some(val) => {
println!("ok boomer");
val.mime_map()
},
None => Err(Box::new(e)),
},
None => Err(Box::new(e)),
None => {
println!("yolo3");
Err(Box::new(e))
},
}
}
}
Expand All @@ -90,6 +103,7 @@ trait InputTo<'a> {
create_input!(SVGInputFile, InputTo);
create_input!(JPGInputFile, InputTo);
create_input!(PNGInputFile, InputTo);
create_input!(AVIFInputFile, InputTo);
create_input!(WebpInputFile, InputTo);
create_input!(MarkdownInputFile, InputTo);
create_input!(YamlInputFile, InputTo);
Expand Down
Binary file added tests/datasets/house_source_avif.avif
Binary file not shown.
11 changes: 11 additions & 0 deletions tests/machmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,17 @@ fn webp_to_avif() {
);
}

#[test]
fn avif_to_png() {
assert_eq!(
"ded9ac7d150e74b53037a7c63e79e5dc11a71e3f",
get_hash_after(
"tests/datasets/house_source_avif.avif",
"tests/datasets/machmap/house_source_avif.png"
)
);
}

#[test]
fn png_to_jpg() {
assert_eq!(
Expand Down

0 comments on commit aac0aad

Please sign in to comment.