diff options
-rw-r--r-- | dhwt-codec/.gitignore | 2 | ||||
-rw-r--r-- | dhwt-codec/Cargo.lock | 350 | ||||
-rw-r--r-- | dhwt-codec/Cargo.toml | 9 | ||||
-rwxr-xr-x | dhwt-codec/run | 16 | ||||
-rw-r--r-- | dhwt-codec/src/bin/decode.rs | 54 | ||||
-rw-r--r-- | dhwt-codec/src/bin/encode.rs | 54 | ||||
-rw-r--r-- | dhwt-codec/src/bin/export.rs | 42 | ||||
-rw-r--r-- | dhwt-codec/src/bin/import.rs | 51 | ||||
-rw-r--r-- | dhwt-codec/src/io.rs | 71 | ||||
-rw-r--r-- | dhwt-codec/src/lib.rs | 23 | ||||
-rw-r--r-- | dhwt-codec/src/transform.rs | 42 | ||||
-rw-r--r-- | dhwt-codec/src/trim.rs | 36 | ||||
-rw-r--r-- | dhwt-codec/src/view.rs | 42 | ||||
-rw-r--r-- | vgcodec/.gitignore | 3 | ||||
-rw-r--r-- | vgcodec/Cargo.lock | 1310 | ||||
-rw-r--r-- | vgcodec/Cargo.toml | 13 | ||||
-rw-r--r-- | vgcodec/src/app.rs | 37 | ||||
-rw-r--r-- | vgcodec/src/diff.rs | 120 | ||||
-rw-r--r-- | vgcodec/src/diff.wgsl | 17 | ||||
-rw-r--r-- | vgcodec/src/export.rs | 80 | ||||
-rw-r--r-- | vgcodec/src/main.rs | 76 | ||||
-rw-r--r-- | vgcodec/src/paint.rs | 120 | ||||
-rw-r--r-- | vgcodec/src/paint.wgsl | 19 |
23 files changed, 2587 insertions, 0 deletions
diff --git a/dhwt-codec/.gitignore b/dhwt-codec/.gitignore new file mode 100644 index 0000000..495c6ed --- /dev/null +++ b/dhwt-codec/.gitignore @@ -0,0 +1,2 @@ +/target +/a diff --git a/dhwt-codec/Cargo.lock b/dhwt-codec/Cargo.lock new file mode 100644 index 0000000..715ba3e --- /dev/null +++ b/dhwt-codec/Cargo.lock @@ -0,0 +1,350 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bincode" +version = "2.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb50c5a2ef4b9b1e7ae73e3a73b52ea24b20312d629f9c4df28260b7ad2c3c4" +dependencies = [ + "bincode_derive", + "serde", +] + +[[package]] +name = "bincode_derive" +version = "2.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a45a23389446d2dd25dc8e73a7a3b3c43522b630cac068927f0649d43d719d2" +dependencies = [ + "virtue", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "clap_lex", + "once_cell", + "strsim", + "termcolor", +] + +[[package]] +name = "clap_derive" +version = "4.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bf8df95e795db1a4aca2957ad884a2df35413b24bbeb3114422f3cc21498e8" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "422f23e724af1240ec469ea1e834d87a4b59ce2efe2c6a96256b0c47e2fd86aa" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "dhwt-codec" +version = "0.1.0" +dependencies = [ + "bincode", + "clap", + "rayon", +] + +[[package]] +name = "either" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "libc" +version = "0.2.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "os_str_bytes" +version = "6.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5bf27447411e9ee3ff51186bf7a08e16c341efdde93f4d823e8844429bed7e" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e060280438193c554f654141c9ea9417886713b7acd75974c85b18a69a88e0b" +dependencies = [ + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "serde" +version = "1.0.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "virtue" +version = "0.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b60dcd6a64dd45abf9bd426970c9843726da7fc08f44cd6fcebf68c21220a63" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/dhwt-codec/Cargo.toml b/dhwt-codec/Cargo.toml new file mode 100644 index 0000000..080fe20 --- /dev/null +++ b/dhwt-codec/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "dhwt-codec" +version = "0.1.0" +edition = "2021" + +[dependencies] +bincode = "2.0.0-rc.2" +clap = { version = "4.0.26", features = ["derive"] } +rayon = "1.6.0" diff --git a/dhwt-codec/run b/dhwt-codec/run new file mode 100755 index 0000000..9f7013e --- /dev/null +++ b/dhwt-codec/run @@ -0,0 +1,16 @@ +#!/bin/fish + +set f $argv[1] +set x $argv[2] +set y $argv[3] +set z $argv[4] + +# cat /dev/urandom | cargo run --release --bin import -- -x $x -y $y -z $z a/inp +ffmpeg -i $f -frames:v $z -filter_complex [0]scale={$x}x{$y},format=rgb24 -f rawvideo pipe:1 | cargo run --release --bin import -- -x $x -y $y -z $z a/inp + +time cargo run --release --bin encode -- -x $x -y $y -z $z a/inp a/enc +time cargo run --release --bin decode -- -x $x -y $y -z $z a/enc a/out + +cargo run --release --bin export -- -x (math $x / 2) -y (math $y / 2) -z (math $z / 2) a/enc | ffmpeg -y -pixel_format rgb24 -f rawvideo -video_size (math $x / 2)x(math $y / 2) -i pipe:0 a/enc.webm +cargo run --release --bin export -- -x $x -y $y -z $z a/out | ffmpeg -y -pixel_format rgb24 -f rawvideo -video_size {$x}x{$y} -i pipe:0 a/out.webm +# cargo run --release --bin export -- -x $x -y $y -z $z a/raw_out | ffplay -pixel_format rgb24 -f rawvideo -video_size {$x}x{$y} pipe:0 diff --git a/dhwt-codec/src/bin/decode.rs b/dhwt-codec/src/bin/decode.rs new file mode 100644 index 0000000..35881fc --- /dev/null +++ b/dhwt-codec/src/bin/decode.rs @@ -0,0 +1,54 @@ +use clap::Parser; +use dhwt_codec::{ + io::{empty_videobuf, infile, outfile, read_videobuf_small, write_videobuf, VideoBuf}, + transform, trim, + view::{BufferView, IndexMode}, + CommonArgs, +}; +use rayon::prelude::{IntoParallelIterator, ParallelIterator}; + +fn main() { + let args = CommonArgs::parse(); + + let mut inf = infile(&args.infile); + let mut of = outfile(&args.outfile); + + for c in 0..args.channels { + eprintln!("encoding channel #{c}"); + let a = empty_videobuf(args.x, args.y, args.z); + let b = read_videobuf_small(&mut inf); + + eprintln!("\tdecoding Z"); + (0..args.x).into_par_iter().for_each(|x| { + for y in 0..args.y { + run_mode(make_mut(&b), make_mut(&a), IndexMode::XY(x, y), args.z) + } + }); + eprintln!("\tdecoding Y"); + (0..args.x).into_par_iter().for_each(|x| { + for z in 0..args.z { + run_mode(make_mut(&a), make_mut(&b), IndexMode::XZ(x, z), args.y) + } + }); + eprintln!("\tdecoding X"); + (0..args.y).into_par_iter().for_each(|y| { + for z in 0..args.z { + run_mode(make_mut(&b), make_mut(&a), IndexMode::YZ(y, z), args.x) + } + }); + write_videobuf(&mut of, a); + } +} + +fn run_mode(a: &mut VideoBuf, b: &mut VideoBuf, mode: IndexMode, size: usize) { + trim::untrim(size, &mut BufferView::new(b, mode)); + transform::decode( + size, + &mut BufferView::new(a, mode), + &mut BufferView::new(b, mode), + ); +} + +fn make_mut<T>(r: &T) -> &mut T { + unsafe { &mut *((r as *const T) as *mut T) } +} diff --git a/dhwt-codec/src/bin/encode.rs b/dhwt-codec/src/bin/encode.rs new file mode 100644 index 0000000..0e711b0 --- /dev/null +++ b/dhwt-codec/src/bin/encode.rs @@ -0,0 +1,54 @@ +use clap::Parser; +use dhwt_codec::{ + io::{empty_videobuf, infile, outfile, read_videobuf, write_videobuf_small, VideoBuf}, + transform, trim, + view::{BufferView, IndexMode}, + CommonArgs, +}; +use rayon::prelude::{IntoParallelIterator, ParallelIterator}; + +fn main() { + let args = CommonArgs::parse(); + + let mut inf = infile(&args.infile); + let mut of = outfile(&args.outfile); + + for c in 0..args.channels { + eprintln!("encoding channel #{c}"); + let o = empty_videobuf(args.x, args.y, args.z); + let i = read_videobuf(&mut inf); + + eprintln!("\tencoding X"); + (0..args.y).into_par_iter().for_each(|y| { + for z in 0..args.z { + run_mode(make_mut(&i), make_mut(&o), IndexMode::YZ(y, z), args.x) + } + }); + eprintln!("\tencoding Y"); + (0..args.x).into_par_iter().for_each(|x| { + for z in 0..args.z { + run_mode(make_mut(&o), make_mut(&i), IndexMode::XZ(x, z), args.y) + } + }); + eprintln!("\tencoding Z"); + (0..args.x).into_par_iter().for_each(|x| { + for y in 0..args.y { + run_mode(make_mut(&i), make_mut(&o), IndexMode::XY(x, y), args.z) + } + }); + write_videobuf_small(&mut of, o); + } +} + +fn run_mode(a: &mut VideoBuf, b: &mut VideoBuf, mode: IndexMode, size: usize) { + transform::encode( + size, + &mut BufferView::new(a, mode), + &mut BufferView::new(b, mode), + ); + trim::trim(size, &mut BufferView::new(b, mode)); +} + +fn make_mut<T>(r: &T) -> &mut T { + unsafe { &mut *((r as *const T) as *mut T) } +} diff --git a/dhwt-codec/src/bin/export.rs b/dhwt-codec/src/bin/export.rs new file mode 100644 index 0000000..73f3067 --- /dev/null +++ b/dhwt-codec/src/bin/export.rs @@ -0,0 +1,42 @@ +use clap::Parser; +use dhwt_codec::io::{infile, read_videobuf}; +use std::io::{stdout, BufWriter, Write}; + +#[derive(Parser)] +#[clap(about)] +struct ExportArgs { + #[arg(short)] + x: usize, + #[arg(short)] + y: usize, + #[arg(short)] + z: usize, + + #[arg(short, long, default_value = "3")] + channels: usize, + + infile: String, +} + +fn main() { + let args = ExportArgs::parse(); + + let mut i = infile(&args.infile); + let mut writer = BufWriter::new(stdout()); + + let mut channels = vec![]; + for _ in 0..args.channels { + channels.push(read_videobuf(&mut i)) + } + + for z in 0..args.z { + for y in 0..args.y { + for x in 0..args.x { + for c in 0..args.channels { + writer.write_all(&[channels[c][x][y][z] as u8]).unwrap(); + } + } + } + } + writer.flush().unwrap(); +} diff --git a/dhwt-codec/src/bin/import.rs b/dhwt-codec/src/bin/import.rs new file mode 100644 index 0000000..cd2a35e --- /dev/null +++ b/dhwt-codec/src/bin/import.rs @@ -0,0 +1,51 @@ +use clap::Parser; +use dhwt_codec::io::{outfile, write_videobuf, Value}; +use std::io::{stdin, Read}; + +#[derive(Parser)] +#[clap(about)] +struct ImportArgs { + #[arg(short)] + x: usize, + #[arg(short)] + y: usize, + #[arg(short)] + z: usize, + + #[arg(short, long, default_value = "3")] + channels: usize, + + outfile: String, +} + +fn main() { + let args = ImportArgs::parse(); + + let mut rawbuf = (0..(args.x * args.y * args.z * args.channels)) + .map(|_| 0u8) + .collect::<Vec<_>>(); + stdin().read_exact(&mut rawbuf).unwrap(); + + let mut o = outfile(&args.outfile); + + for c in 0..args.channels { + let mut cols = vec![]; + for x in 0..args.x { + let mut col = vec![]; + for y in 0..args.y { + let mut span = vec![]; + for z in 0..args.z { + span.push( + rawbuf[c + + (x * args.channels) + + (y * args.channels * args.x) + + (z * args.channels * args.x * args.y)] as Value, + ); + } + col.push(span); + } + cols.push(col) + } + write_videobuf(&mut o, cols) + } +} diff --git a/dhwt-codec/src/io.rs b/dhwt-codec/src/io.rs new file mode 100644 index 0000000..c60bc79 --- /dev/null +++ b/dhwt-codec/src/io.rs @@ -0,0 +1,71 @@ +use bincode::config; +use std::{ + fs::File, + io::{BufReader, BufWriter, Read, Write}, +}; + +pub type Value = f32; +pub type VideoBuf = Vec<Vec<Vec<Value>>>; +pub const ZERO: Value = 0 as Value; +pub const TWO: Value = 2 as Value; + +pub fn empty_videobuf(x: usize, y: usize, z: usize) -> VideoBuf { + (0..x) + .map(|_| (0..y).map(|_| (0..z).map(|_| ZERO).collect()).collect()) + .collect() +} + +pub fn outfile(p: &str) -> impl Write { + BufWriter::new(File::create(p).unwrap()) +} +pub fn infile(p: &str) -> impl Read { + BufReader::new(File::open(p).unwrap()) +} + +pub fn read_videobuf(f: &mut impl Read) -> VideoBuf { + bincode::decode_from_std_read(f, config::standard()).unwrap() +} +pub fn write_videobuf(f: &mut impl Write, i: VideoBuf) { + bincode::encode_into_std_write(i, f, config::standard()).unwrap(); +} + +pub fn write_videobuf_small(f: &mut impl Write, mut i: VideoBuf) { + for _ in 0..(i.len() / 2) { + i.pop(); + } + for i in &mut i { + for _ in 0..(i.len() / 2) { + i.pop(); + } + for i in i { + for _ in 0..(i.len() / 2) { + i.pop(); + } + } + } + write_videobuf(f, i); +} +pub fn read_videobuf_small(f: &mut impl Read) -> VideoBuf { + let mut i = read_videobuf(f); + + for i in &mut i { + for i in i { + for _ in 0..i.len() { + i.push(ZERO); + } + } + } + for i in &mut i { + for _ in 0..i.len() { + i.push((0..i[0].len()).map(|_| ZERO).collect()); + } + } + for _ in 0..i.len() { + i.push( + (0..i[0].len()) + .map(|_| ((0..i[0][0].len()).map(|_| ZERO)).collect()) + .collect(), + ); + } + i +} diff --git a/dhwt-codec/src/lib.rs b/dhwt-codec/src/lib.rs new file mode 100644 index 0000000..69d6b4c --- /dev/null +++ b/dhwt-codec/src/lib.rs @@ -0,0 +1,23 @@ +use clap::Parser; + +pub mod io; +pub mod transform; +pub mod trim; +pub mod view; + +#[derive(Parser)] +#[clap(about)] +pub struct CommonArgs { + #[arg(short)] + pub x: usize, + #[arg(short)] + pub y: usize, + #[arg(short)] + pub z: usize, + + #[arg(short, long, default_value = "3")] + pub channels: usize, + + pub infile: String, + pub outfile: String, +} diff --git a/dhwt-codec/src/transform.rs b/dhwt-codec/src/transform.rs new file mode 100644 index 0000000..82bccd1 --- /dev/null +++ b/dhwt-codec/src/transform.rs @@ -0,0 +1,42 @@ +use crate::io::{Value, TWO}; +use std::ops::{Index, IndexMut}; + +pub fn encode<X: Index<usize, Output = Value> + IndexMut<usize, Output = Value>>( + size: usize, + a: &mut X, + b: &mut X, +) { + let mut k = size; + while k != 1 { + k /= 2; + for i in 0..k { + let x = a[i * 2]; + let y = a[i * 2 + 1]; + b[i] = x + y; + b[k + i] = x - y; + } + for i in 0..k { + a[i] = b[i] + } + } +} + +pub fn decode<X: Index<usize, Output = Value> + IndexMut<usize, Output = Value>>( + size: usize, + a: &mut X, + b: &mut X, +) { + let mut k = 1; + while k != size { + for i in 0..k { + let avr = a[i] / TWO; + let spread = a[i + k] / TWO; + b[i * 2] = avr + spread; + b[i * 2 + 1] = avr - spread; + } + k *= 2; + for i in 0..k { + a[i] = b[i] + } + } +} diff --git a/dhwt-codec/src/trim.rs b/dhwt-codec/src/trim.rs new file mode 100644 index 0000000..85a920a --- /dev/null +++ b/dhwt-codec/src/trim.rs @@ -0,0 +1,36 @@ +use crate::io::{Value, TWO, ZERO}; +use std::ops::{Index, IndexMut}; + +pub fn trim<X: Index<usize, Output = Value> + IndexMut<usize, Output = Value>>( + size: usize, + a: &mut X, +) { + let half = size / 2; + let quarter = size / 4; + for i in 0..(size / 2 / 4) { + let hi = half + i * 4; + let qi = quarter + i * 2; + a[qi] = (a[qi + 0] + a[qi + 1]) / TWO; + a[qi + 1] = (a[hi + 0] + a[hi + 1] + a[hi + 2] + a[hi + 3]) / (TWO * TWO); + } + for i in half..size { + a[i] = ZERO; + } +} + +pub fn untrim<X: Index<usize, Output = Value> + IndexMut<usize, Output = Value>>( + size: usize, + a: &mut X, +) { + let half = size / 2; + let quarter = size / 4; + for i in 0..(size / 2 / 4) { + let hi = half + i * 4; + let qi = quarter + i * 2; + a[hi + 0] = a[qi + 1]; + a[hi + 1] = a[qi + 1]; + a[hi + 2] = a[qi + 1]; + a[hi + 3] = a[qi + 1]; + a[qi + 1] = a[qi]; + } +} diff --git a/dhwt-codec/src/view.rs b/dhwt-codec/src/view.rs new file mode 100644 index 0000000..0f2ecf7 --- /dev/null +++ b/dhwt-codec/src/view.rs @@ -0,0 +1,42 @@ +use std::ops::{Index, IndexMut}; + +use crate::io::{VideoBuf, Value}; + +#[derive(Copy, Clone, Debug)] +pub enum IndexMode { + XY(usize, usize), + XZ(usize, usize), + YZ(usize, usize), +} + +pub struct BufferView<'a> { + mode: IndexMode, + buf: &'a mut VideoBuf, +} + +impl<'a> BufferView<'a> { + pub fn new(buf: &'a mut VideoBuf, mode: IndexMode) -> Self { + BufferView { mode, buf } + } +} + +impl Index<usize> for BufferView<'_> { + type Output = Value; + + fn index(&self, a: usize) -> &Self::Output { + match self.mode { + IndexMode::XY(x, y) => &self.buf[x][y][a], + IndexMode::XZ(x, z) => &self.buf[x][a][z], + IndexMode::YZ(y, z) => &self.buf[a][y][z], + } + } +} +impl IndexMut<usize> for BufferView<'_> { + fn index_mut(&mut self, a: usize) -> &mut Self::Output { + match self.mode { + IndexMode::XY(x, y) => &mut self.buf[x][y][a], + IndexMode::XZ(x, z) => &mut self.buf[x][a][z], + IndexMode::YZ(y, z) => &mut self.buf[a][y][z], + } + } +} diff --git a/vgcodec/.gitignore b/vgcodec/.gitignore new file mode 100644 index 0000000..775fc88 --- /dev/null +++ b/vgcodec/.gitignore @@ -0,0 +1,3 @@ +/target +/a + diff --git a/vgcodec/Cargo.lock b/vgcodec/Cargo.lock new file mode 100644 index 0000000..06a117c --- /dev/null +++ b/vgcodec/Cargo.lock @@ -0,0 +1,1310 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +dependencies = [ + "memchr", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "ash" +version = "0.37.0+1.3.209" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006ca68e0f2b03f22d6fa9f2860f85aed430d257fec20f8879b2145e7c7ae1a6" +dependencies = [ + "libloading", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "bumpalo" +version = "3.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" + +[[package]] +name = "bytemuck" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types", + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bf8df95e795db1a4aca2957ad884a2df35413b24bbeb3114422f3cc21498e8" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "422f23e724af1240ec469ea1e834d87a4b59ce2efe2c6a96256b0c47e2fd86aa" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] +name = "d3d12" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "827914e1f53b1e0e025ecd3d967a7836b7bcb54520f90e21ef8df7b4d88a2759" +dependencies = [ + "bitflags", + "libloading", + "winapi", +] + +[[package]] +name = "either" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "exr" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eb5f255b5980bb0c8cf676b675d1a99be40f316881444f44e0462eaf5df5ded" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide 0.6.2", + "smallvec", + "threadpool", +] + +[[package]] +name = "flate2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +dependencies = [ + "crc32fast", + "miniz_oxide 0.5.4", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin", +] + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gif" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "glow" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8bd5877156a19b8ac83a29b2306fe20537429d318f3ff0a1a2119f8d9c61919" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gpu-alloc" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc59e5f710e310e76e6707f86c561dd646f69a8876da9131703b2f717de818d" +dependencies = [ + "bitflags", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54804d0d6bc9d7f26db4eaec1ad10def69b599315f487d32c334a80d1efe67a5" +dependencies = [ + "bitflags", +] + +[[package]] +name = "gpu-descriptor" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b0c02e1ba0bdb14e965058ca34e09c020f8e507a760df1121728e0aef68d57a" +dependencies = [ + "bitflags", + "gpu-descriptor-types", + "hashbrown", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "363e3677e55ad168fef68cf9de3a4a310b53124c5e784c53a1d70e92d23f2126" +dependencies = [ + "bitflags", +] + +[[package]] +name = "half" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad6a9459c9c30b177b925162351f97e7d967c7ea8bab3b8352805327daf45554" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "image" +version = "0.24.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-rational", + "num-traits", + "png", + "scoped_threadpool", + "tiff", +] + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +dependencies = [ + "rayon", +] + +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "khronos-egl" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c2352bd1d0bceb871cb9d40f24360c8133c11d7486b68b5381c1dd1a32015e3" +dependencies = [ + "libc", + "libloading", + "pkg-config", +] + +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "libc" +version = "0.2.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "metal" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de11355d1f6781482d027a3b4d4de7825dcedb197bf573e0596d00008402d060" +dependencies = [ + "bitflags", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", +] + +[[package]] +name = "miniz_oxide" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +dependencies = [ + "adler", +] + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "naga" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "262d2840e72dbe250e8cf2f522d080988dfca624c4112c096238a4845f591707" +dependencies = [ + "bit-set", + "bitflags", + "codespan-reporting", + "hexf-parse", + "indexmap", + "log", + "num-traits", + "rustc-hash", + "spirv", + "termcolor", + "thiserror", + "unicode-xid", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + +[[package]] +name = "png" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" +dependencies = [ + "bitflags", + "crc32fast", + "flate2", + "miniz_oxide 0.6.2", +] + +[[package]] +name = "pollster" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5da3b0203fd7ee5720aa0b5e790b591aa5d3f41c3ed2c34a3a393382198af2f7" + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74605f360ce573babfe43964cbe520294dcb081afbf8c108fc6e23036b4da2df" + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "range-alloc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e935c45e09cc6dcf00d2f0b2d630a58f4095320223d47fc68918722f0538b6" + +[[package]] +name = "raw-window-handle" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7e3d950b66e19e0c372f3fa3fbbcf85b1746b571f74e0c2af6042a5c93420a" +dependencies = [ + "cty", +] + +[[package]] +name = "rayon" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e060280438193c554f654141c9ea9417886713b7acd75974c85b18a69a88e0b" +dependencies = [ + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "renderdoc-sys" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "slotmap" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "spin" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spirv" +version = "0.2.0+1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830" +dependencies = [ + "bitflags", + "num-traits", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "tiff" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17def29300a156c19ae30814710d9c63cd50288a49c6fd3a10ccfbe4cf886fd" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vgcodec" +version = "0.1.0" +dependencies = [ + "bytemuck", + "env_logger", + "futures-intrusive", + "image", + "log", + "pollster", + "wgpu", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + +[[package]] +name = "web-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + +[[package]] +name = "wgpu" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2272b17bffc8a0c7d53897435da7c1db587c87d3a14e8dae9cdb8d1d210fc0f" +dependencies = [ + "arrayvec", + "js-sys", + "log", + "naga", + "parking_lot", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73d14cad393054caf992ee02b7da6a372245d39a484f7461c1f44f6f6359bd28" +dependencies = [ + "arrayvec", + "bit-vec", + "bitflags", + "cfg_aliases", + "codespan-reporting", + "fxhash", + "log", + "naga", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "thiserror", + "web-sys", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cc320a61acb26be4f549c9b1b53405c10a223fbfea363ec39474c32c348d12f" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set", + "bitflags", + "block", + "core-graphics-types", + "d3d12", + "foreign-types", + "fxhash", + "glow", + "gpu-alloc", + "gpu-descriptor", + "js-sys", + "khronos-egl", + "libloading", + "log", + "metal", + "naga", + "objc", + "parking_lot", + "profiling", + "range-alloc", + "raw-window-handle", + "renderdoc-sys", + "smallvec", + "thiserror", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "winapi", +] + +[[package]] +name = "wgpu-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb6b28ef22cac17b9109b25b3bf8c9a103eeb293d7c5f78653979b09140375f6" +dependencies = [ + "bitflags", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" diff --git a/vgcodec/Cargo.toml b/vgcodec/Cargo.toml new file mode 100644 index 0000000..5b15036 --- /dev/null +++ b/vgcodec/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "vgcodec" +version = "0.1.0" +edition = "2021" + +[dependencies] +wgpu = "0.14.0" +log = "0.4.17" +env_logger = "0.9.3" +pollster = "0.2.5" +bytemuck = "1.12.3" +futures-intrusive = "0.5.0" +image = "0.24.5" diff --git a/vgcodec/src/app.rs b/vgcodec/src/app.rs new file mode 100644 index 0000000..0c063a5 --- /dev/null +++ b/vgcodec/src/app.rs @@ -0,0 +1,37 @@ +use std::sync::Arc; + +use wgpu::{Adapter, Device, Instance, Queue}; + +pub struct App { + pub instance: Instance, + pub device: Device, + pub adapter: Adapter, + pub queue: Queue, +} + +impl App { + pub async fn new() -> Arc<Self> { + let instance = wgpu::Instance::new(wgpu::Backends::all()); + let adapter = instance + .request_adapter(&wgpu::RequestAdapterOptions::default()) + .await + .unwrap(); + let (device, queue) = adapter + .request_device( + &wgpu::DeviceDescriptor { + label: None, + features: wgpu::Features::empty(), + limits: wgpu::Limits::downlevel_defaults(), + }, + None, + ) + .await + .unwrap(); + Arc::new(Self { + adapter, + device, + instance, + queue, + }) + } +} diff --git a/vgcodec/src/diff.rs b/vgcodec/src/diff.rs new file mode 100644 index 0000000..44efabe --- /dev/null +++ b/vgcodec/src/diff.rs @@ -0,0 +1,120 @@ +use std::{borrow::Cow, sync::Arc}; +use wgpu::{util::DeviceExt, BindGroup, Buffer, ComputePipeline, Extent3d, Texture}; + +use crate::app::App; + +pub struct Differ { + app: Arc<App>, + size: Extent3d, + + pipeline: ComputePipeline, + bind_group: BindGroup, + + counter_buffer_size: u64, + counter_buffer: Buffer, + counter_staging_buffer: Buffer, +} + +impl Differ { + pub fn new(app: &Arc<App>, extent: Extent3d, tex_a: &Texture, tex_b: &Texture) -> Self { + let App { device, .. } = app.as_ref(); + let cs_module = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: None, + source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("diff.wgsl"))), + }); + + let counter_buffer_size = std::mem::size_of::<u32>() as wgpu::BufferAddress; + let counter_staging_buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: counter_buffer_size, + usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); + let counter_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice(&[0u32]), + usage: wgpu::BufferUsages::STORAGE + | wgpu::BufferUsages::COPY_DST + | wgpu::BufferUsages::COPY_SRC, + }); + + let pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: None, + layout: None, + module: &cs_module, + entry_point: "main", + }); + + let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &pipeline.get_bind_group_layout(0), + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView( + &tex_a.create_view(&wgpu::TextureViewDescriptor::default()), + ), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::TextureView( + &tex_b.create_view(&wgpu::TextureViewDescriptor::default()), + ), + }, + wgpu::BindGroupEntry { + binding: 2, + resource: counter_buffer.as_entire_binding(), + }, + ], + }); + Self { + app: app.clone(), + size: extent, + pipeline, + counter_buffer_size, + counter_buffer, + bind_group, + counter_staging_buffer, + } + } + + pub async fn run(&mut self) -> u32 { + let App { device, queue, .. } = self.app.as_ref(); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + { + let mut cpass = + encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: None }); + cpass.set_pipeline(&self.pipeline); + cpass.set_bind_group(0, &self.bind_group, &[]); + cpass.dispatch_workgroups(self.size.width, self.size.height, 1); + } + + encoder.copy_buffer_to_buffer( + &self.counter_buffer, + 0, + &self.counter_staging_buffer, + 0, + self.counter_buffer_size, + ); + + queue.submit(Some(encoder.finish())); + + let buffer_slice = self.counter_staging_buffer.slice(..); + let (sender, receiver) = futures_intrusive::channel::shared::oneshot_channel(); + buffer_slice.map_async(wgpu::MapMode::Read, move |v| { + sender.send(v.unwrap()).unwrap() + }); + device.poll(wgpu::Maintain::Wait); + receiver.receive().await; + + let data = buffer_slice.get_mapped_range(); + let result: u32 = bytemuck::cast_slice(&data).to_vec()[0]; + + drop(data); + self.counter_staging_buffer.unmap(); + + result + } +} diff --git a/vgcodec/src/diff.wgsl b/vgcodec/src/diff.wgsl new file mode 100644 index 0000000..bb5a3e1 --- /dev/null +++ b/vgcodec/src/diff.wgsl @@ -0,0 +1,17 @@ +@group(0) @binding(0) +var tex_a: texture_2d<f32>; +@group(0) @binding(1) +var tex_b: texture_2d<f32>; + +@group(0) @binding(2) +var<storage, read_write> exp: atomic<u32>; + +@compute @workgroup_size(1) +fn main(@builtin(global_invocation_id) global_id: vec3<u32>) { + var col_a = textureLoad(tex_a, vec2(i32(global_id.x), i32(global_id.y)), 0); + var col_b = textureLoad(tex_b, vec2(i32(global_id.x), i32(global_id.y)), 0); + var diff = col_a - col_b; + var diffsum = diff.r + diff.g + diff.b; + atomicAdd(&exp, u32(diffsum)); +} + diff --git a/vgcodec/src/export.rs b/vgcodec/src/export.rs new file mode 100644 index 0000000..7b02085 --- /dev/null +++ b/vgcodec/src/export.rs @@ -0,0 +1,80 @@ +use crate::app::App; +use image::RgbaImage; +use std::{num::NonZeroU32, sync::Arc}; +use wgpu::{ + Buffer, Extent3d, ImageCopyBuffer, ImageCopyTexture, ImageDataLayout, Origin3d, Texture, +}; + +pub struct Exporter { + app: Arc<App>, + size: Extent3d, + + padded_bytes_per_row: u32, + export_buffer: Buffer, +} + +impl Exporter { + pub fn new(app: &Arc<App>, size: Extent3d) -> Self { + let App { device, .. } = app.as_ref(); + + let bytes_per_pixel = std::mem::size_of::<u32>() as u32; + let unpadded_bytes_per_row = size.width * bytes_per_pixel; + let align = wgpu::COPY_BYTES_PER_ROW_ALIGNMENT; + let padded_bytes_per_row_padding = (align - unpadded_bytes_per_row % align) % align; + let padded_bytes_per_row = unpadded_bytes_per_row + padded_bytes_per_row_padding; + + let export_buffer_size = (padded_bytes_per_row * size.height) as u64; + let export_buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: export_buffer_size, + usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); + + Self { + padded_bytes_per_row, + app: app.clone(), + size, + export_buffer, + } + } + pub async fn run(&self, texture: &Texture, save_path: &str) { + let App { device, queue, .. } = self.app.as_ref(); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + encoder.copy_texture_to_buffer( + ImageCopyTexture { + texture, + aspect: wgpu::TextureAspect::All, + mip_level: 0, + origin: Origin3d::ZERO, + }, + ImageCopyBuffer { + buffer: &self.export_buffer, + layout: ImageDataLayout { + offset: 0, + bytes_per_row: Some(NonZeroU32::new(self.padded_bytes_per_row).unwrap()), + rows_per_image: None, + }, + }, + self.size, + ); + + queue.submit(Some(encoder.finish())); + + let buffer_slice = self.export_buffer.slice(..); + let (sender, receiver) = futures_intrusive::channel::shared::oneshot_channel(); + buffer_slice.map_async(wgpu::MapMode::Read, move |v| { + sender.send(v.unwrap()).unwrap() + }); + device.poll(wgpu::Maintain::Wait); + receiver.receive().await; + + let data = buffer_slice.get_mapped_range(); + let result: Vec<u8> = bytemuck::cast_slice(&data).to_vec(); + let image = RgbaImage::from_raw(self.size.width, self.size.height, result).unwrap(); + image.save(save_path).unwrap(); + } +} diff --git a/vgcodec/src/main.rs b/vgcodec/src/main.rs new file mode 100644 index 0000000..9450894 --- /dev/null +++ b/vgcodec/src/main.rs @@ -0,0 +1,76 @@ +pub mod app; +pub mod diff; +pub mod export; +pub mod paint; + +use app::App; +use diff::Differ; +use image::EncodableLayout; +use wgpu::{Extent3d, Queue, Texture, TextureUsages}; + +use crate::export::Exporter; + +fn main() { + env_logger::init_from_env("LOG"); + pollster::block_on(run()); +} + +async fn run() { + let app = app::App::new().await; + + let App { device, queue, .. } = app.as_ref(); + + let img_target = image::open("a/a.png").unwrap().into_rgba8(); + let img_initial = image::open("a/initial.png").unwrap().into_rgba8(); + + let size = wgpu::Extent3d { + width: img_initial.width(), + height: img_initial.height(), + depth_or_array_layers: 1, + }; + + let create_texture = || { + device.create_texture(&wgpu::TextureDescriptor { + size, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rgba8Unorm, + usage: TextureUsages::COPY_DST + | TextureUsages::TEXTURE_BINDING + | TextureUsages::COPY_SRC, + label: None, + }) + }; + + let tex_target = create_texture(); + let tex_approx = create_texture(); + + write_texture(queue, &tex_target, img_target.as_bytes(), size); + write_texture(queue, &tex_approx, img_initial.as_bytes(), size); + + let mut differ = Differ::new(&app, size, &tex_approx, &tex_target); + let exporter = Exporter::new(&app, size); + + println!("{}", differ.run().await); + + exporter.run(&tex_approx, "a/approx.png").await; +} + +pub fn write_texture(queue: &Queue, target: &Texture, data: &[u8], size: Extent3d) { + queue.write_texture( + wgpu::ImageCopyTexture { + texture: &target, + mip_level: 0, + origin: wgpu::Origin3d::ZERO, + aspect: wgpu::TextureAspect::All, + }, + &data, + wgpu::ImageDataLayout { + offset: 0, + bytes_per_row: Some(std::num::NonZeroU32::try_from((size.width * 4) as u32).unwrap()), + rows_per_image: None, + }, + size, + ); +} diff --git a/vgcodec/src/paint.rs b/vgcodec/src/paint.rs new file mode 100644 index 0000000..3da0647 --- /dev/null +++ b/vgcodec/src/paint.rs @@ -0,0 +1,120 @@ +use std::{borrow::Cow, sync::Arc}; +use wgpu::{util::DeviceExt, BindGroup, Buffer, ComputePipeline, Extent3d, Texture}; + +use crate::app::App; + +pub struct Painter { + app: Arc<App>, + size: Extent3d, + + pipeline: ComputePipeline, + bind_group: BindGroup, + + uniform_buffer_size: u64, + uniform_buffer: Buffer, + uniform_staging_buffer: Buffer, +} + +impl Painter { + pub fn new(app: &Arc<App>, extent: Extent3d, tex_a: &Texture, tex_b: &Texture) -> Self { + let App { device, .. } = app.as_ref(); + let cs_module = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: None, + source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("paint.wgsl"))), + }); + + let uniform_buffer_size = std::mem::size_of::<u32>() as wgpu::BufferAddress; + let uniform_staging_buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: uniform_buffer_size, + usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); + let uniform_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice(&[0u32]), + usage: wgpu::BufferUsages::STORAGE + | wgpu::BufferUsages::COPY_DST + | wgpu::BufferUsages::COPY_SRC, + }); + + let pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: None, + layout: None, + module: &cs_module, + entry_point: "main", + }); + + let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &pipeline.get_bind_group_layout(0), + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView( + &tex_a.create_view(&wgpu::TextureViewDescriptor::default()), + ), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::TextureView( + &tex_b.create_view(&wgpu::TextureViewDescriptor::default()), + ), + }, + wgpu::BindGroupEntry { + binding: 2, + resource: uniform_buffer.as_entire_binding(), + }, + ], + }); + Self { + app: app.clone(), + size: extent, + pipeline, + uniform_buffer_size, + uniform_buffer, + bind_group, + uniform_staging_buffer, + } + } + + pub async fn run(&mut self) -> u32 { + let App { device, queue, .. } = self.app.as_ref(); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + { + let mut cpass = + encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: None }); + cpass.set_pipeline(&self.pipeline); + cpass.set_bind_group(0, &self.bind_group, &[]); + cpass.dispatch_workgroups(self.size.width, self.size.height, 1); + } + + encoder.copy_buffer_to_buffer( + &self.uniform_buffer, + 0, + &self.uniform_staging_buffer, + 0, + self.uniform_buffer_size, + ); + + queue.submit(Some(encoder.finish())); + + let buffer_slice = self.uniform_staging_buffer.slice(..); + let (sender, receiver) = futures_intrusive::channel::shared::oneshot_channel(); + buffer_slice.map_async(wgpu::MapMode::Read, move |v| { + sender.send(v.unwrap()).unwrap() + }); + device.poll(wgpu::Maintain::Wait); + receiver.receive().await; + + let data = buffer_slice.get_mapped_range(); + let result: u32 = bytemuck::cast_slice(&data).to_vec()[0]; + + drop(data); + self.uniform_staging_buffer.unmap(); + + result + } +} diff --git a/vgcodec/src/paint.wgsl b/vgcodec/src/paint.wgsl new file mode 100644 index 0000000..02acd8e --- /dev/null +++ b/vgcodec/src/paint.wgsl @@ -0,0 +1,19 @@ +struct Uniforms { + x: f32, + y: f32, + radius: f32, + r: f32, + g: f32, + b: f32 +}; + +@group(0) @binding(0) var<uniform> uniforms: Uniforms; +@group(0) @binding(1) var tex: texture_storage_2d<rgba8unorm, write>; + +@compute @workgroup_size(1) +fn main(@builtin(global_invocation_id) global_id: vec3<u32>) { + let coords = vec2<i32>(global_id.xy); + if distance(vec2<f32>(coords), vec2(uniforms.x, uniforms.y)) < uniforms.radius { + textureStore(tex, coords.xy, vec4<f32>(vec3<f32>(uniforms.r, uniforms.g, uniforms.b), 1.0)); + } +} |