diff --git a/README.md b/README.md index 0f64aba..bfcb8e1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,17 @@ -# fractal-wavelet-compression -Image compression with fractal wavelet transform +# `frave` +![fractals](img/fractals.gif) + +`frave` is an image compression algorithm based on complex-base system fractals. + +## Decomposition of an image +Unlike other compression algorithms `frave` works on tame-twindragon fractals rather than on blocks. + +## Compression pipeline +- Decomposing image to fractals using complex-base numeral systems +- Saving the residues of each block +- Quantization based on dividing the smallest layer of fractals +- Entropy coding with ANS + +## Compression rates +> TBD! + diff --git a/img/decomposition.gif b/img/decomposition.gif deleted file mode 100644 index a52b4ac..0000000 Binary files a/img/decomposition.gif and /dev/null differ diff --git a/img/fractals.gif b/img/fractals.gif new file mode 100644 index 0000000..8d68d2e Binary files /dev/null and b/img/fractals.gif differ diff --git a/src/compression/decoder.rs b/src/compression/decoder.rs index ce7ce5d..1ec40c5 100644 --- a/src/compression/decoder.rs +++ b/src/compression/decoder.rs @@ -1,6 +1,5 @@ use std::collections::HashMap; -use itertools::Itertools; use rans::b64_decoder::B64RansDecoderMulti; use rans::RansDecoderMulti; @@ -72,7 +71,7 @@ impl Decoder for FractalImage { let length = self.coef.iter().filter(|x| x.is_some()).count(); let mut coef = self.coef.clone(); let depth = utils::get_prev_power_two(length).trailing_zeros() + 1; - let scale_bits = u32::try_from(depth - 1).unwrap(); + let scale_bits = depth - 1; let mut decoder: B64RansDecoderMulti<3> = B64RansDecoderMulti::new(compressed_coef); let ctxs = ans_contexts; let layers = vec![ diff --git a/src/compression/encoder.rs b/src/compression/encoder.rs index e184583..d0fe798 100644 --- a/src/compression/encoder.rs +++ b/src/compression/encoder.rs @@ -84,7 +84,12 @@ impl Encoder for FractalImage { } fn ans_encode(&self) -> (Vec, Vec) { - let valid_coef = &self.coef.clone().into_iter().flatten().collect::>(); + let valid_coef = &self + .coef + .clone() + .into_iter() + .flatten() + .collect::>(); let true_depth = utils::get_prev_power_two(valid_coef.len()).trailing_zeros() + 1; let layer1 = &valid_coef[1 << (true_depth - 1)..]; let layer2 = &valid_coef[1 << (true_depth - 2)..1 << (true_depth - 1)]; @@ -94,7 +99,7 @@ impl Encoder for FractalImage { let mut contexts: Vec = vec![]; for (i, layer) in [layer1, layer2, layer3].into_iter().enumerate() { - let counter = layer.clone().into_iter().counts(); + let counter = &(*layer).iter().counts(); let freq = counter .values() .map(|e| u32::try_from(*e).unwrap()) diff --git a/src/fractal/image.rs b/src/fractal/image.rs index 5632539..5c48885 100644 --- a/src/fractal/image.rs +++ b/src/fractal/image.rs @@ -1,5 +1,3 @@ -use std::cmp; - use image::GrayImage; use serde::{Deserialize, Serialize}; @@ -55,7 +53,6 @@ impl FractalImage { x: width as i32 / 2, y: height as i32 / 2, }; //;Self::find_center(depth, variant); - dbg!(depth, center); Self { height, @@ -99,17 +96,18 @@ impl FractalImage { .find(|&(_i, rw, rh)| img_w as i32 <= rw && img_h as i32 <= rh) .unwrap() .0 - -1 + - 1 } - fn find_center(depth: usize, variant: [Coord; 30]) -> Coord { - variant[0..depth] - .iter() - .fold(Coord { x: 0, y: 0 }, |accum, value| Coord { - x: accum.x - cmp::min(0, value.x), - y: accum.y - cmp::min(0, value.y), - }) - } + // TODO: Implement valid find center algorithm + // fn find_center(depth: usize, variant: [Coord; 30]) -> Coord { + // variant[0..depth] + // .iter() + // .fold(Coord { x: 0, y: 0 }, |accum, value| Coord { + // x: accum.x - cmp::min(0, value.x), + // y: accum.y - cmp::min(0, value.y), + // }) + // } #[inline] pub fn get_pixel(&self, x: i32, y: i32) -> Option { @@ -140,6 +138,6 @@ pub fn get_quantization_matrix_soft() -> Vec { #[must_use] pub fn get_quantization_matrix() -> Vec { vec![ - 1, 1, 1,1,1,1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 10, 10, 10, 10, 16, 9, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 10, 10, 10, 10, 16, 9, 2, ] } diff --git a/src/fractal/mod.rs b/src/fractal/mod.rs index d8916f8..93e2908 100644 --- a/src/fractal/mod.rs +++ b/src/fractal/mod.rs @@ -1,3 +1,2 @@ -pub mod haar_tree; pub mod image; pub mod variants; diff --git a/utils.rs b/utils.rs deleted file mode 100644 index 726e63d..0000000 --- a/utils.rs +++ /dev/null @@ -1,17 +0,0 @@ -use std::ops; - -#[derive(Clone, Copy, Debug)] -pub struct Coord { - pub x: i32, - pub y: i32, -} - -impl ops::Add for Coord { - type Output = Self; - fn add(self, rhs: Self) -> Self::Output { - Self { - x: self.x + rhs.x, - y: self.y + rhs.y, - } - } -}