Skip to content

Commit

Permalink
Restructurize folders
Browse files Browse the repository at this point in the history
  • Loading branch information
pagmerek committed Nov 12, 2023
1 parent a8908ad commit a997614
Show file tree
Hide file tree
Showing 15 changed files with 304 additions and 320 deletions.
22 changes: 11 additions & 11 deletions src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
use std::fs::File;
use std::path::PathBuf;

use crate::decoder::Decoder;
use crate::encoder::Encoder;
use crate::frave_image::{get_quantization_matrix, FraveImage, Frv};
use crate::variants::Variant;
use crate::compression::decoder::Decoder;
use crate::compression::encoder::Encoder;
use crate::fractal::image::{get_quantization_matrix, FractalImage, Frv};
use crate::fractal::variants::Variant;

pub fn encode(path: PathBuf, var: Variant, output: String) {
let img = image::open(path).unwrap_or_else(|e| {
panic!("Failed to open: {}", e);
panic!("Failed to open: {e}");
});

let mut enc = FraveImage::new_from_img(img.into_luma8(), var);
let mut enc = FractalImage::new_from_img(img.into_luma8(), var);
enc.find_coef();
// enc.quantizate(&get_quantization_matrix());
let (coef, contexts) = enc.ans_encode();
let compressed = Frv::new(enc.height, enc.width, contexts, var, coef);
let mut f = File::create(output).unwrap();
let mut f = File::create(output).unwrap_or_else(|e| panic!("Failed to encode frv image: {e}"));
bincode::serialize_into(&mut f, &compressed).unwrap();
}

pub fn decode(path: PathBuf, output: String) {
let img = File::open(path).unwrap_or_else(|e| {
panic!("Failed to open: {}", e);
panic!("Failed to open: {e}");
});
let frv_img: Frv = bincode::deserialize_from(img).unwrap();
let mut dec = FraveImage::new_from_frv(&frv_img);
dec.ans_decode(frv_img.compressed_coef, frv_img.ans_contexts);
let mut dec = FractalImage::new_from_frv(&frv_img);
dec.ans_decode(frv_img.data, frv_img.ans_contexts);
// dec.unquantizate(&get_quantization_matrix());
dec.find_val();
dec.image.save(output).unwrap_or_else(|e| {
panic!("Failed to save: {}", e);
panic!("Failed to decode frv image: {e}");
});
}
9 changes: 7 additions & 2 deletions src/utils/ans.rs → src/compression/ans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct AnsContext {
pub symbols: Vec<Option<i32>>,
pub symbols: Vec<i32>,
pub freq: Vec<u32>,
}

#[must_use]
pub fn cum_sum(sum: &[u32]) -> Vec<u32> {
sum.iter()
.scan(0_u32, |acc, x| {
Expand All @@ -21,13 +22,16 @@ pub fn cum_sum(sum: &[u32]) -> Vec<u32> {
.collect::<Vec<u32>>()
}

// TODO: Implement Alias sampling method
#[must_use]
pub fn find_nearest_or_equal(cum_freq: u32, cum_freqs: &[u32]) -> u32 {
match cum_freqs.binary_search(&cum_freq) {
Ok(x) => cum_freqs[x],
Err(x) => cum_freqs[x - 1],
}
}

#[must_use]
pub fn freqs_to_enc_symbols(
cum_freq: &[u32],
freq: &[u32],
Expand All @@ -39,12 +43,13 @@ pub fn freqs_to_enc_symbols(
.map(|(&cum_freq, &freq)| {
(
cum_freq,
B64RansEncSymbol::new(cum_freq, freq, (depth - 1) as u32),
B64RansEncSymbol::new(cum_freq, freq, u32::try_from(depth - 1).unwrap()),
)
})
.collect::<HashMap<u32, B64RansEncSymbol>>()
}

#[must_use]
pub fn freqs_to_dec_symbols(cum_freq: &[u32], freq: &[u32]) -> HashMap<u32, B64RansDecSymbol> {
cum_freq
.iter()
Expand Down
45 changes: 20 additions & 25 deletions src/decoder.rs → src/compression/decoder.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
use std::collections::HashMap;

use image::GrayImage;
use rans::b64_decoder::B64RansDecoderMulti;
use rans::RansDecoderMulti;

use crate::coord::Coord;
use crate::frave_image::get_quantization_matrix;
use crate::frave_image::FraveImage;
use crate::utils::ans;
use crate::utils::ans::AnsContext;
use crate::compression::ans::{self, AnsContext};
use crate::fractal::image::FractalImage;
use crate::utils::bitwise;
use crate::utils::coordinate::Coord;

pub trait Decoder {
/// Entropy decoding step of decoder procedure.
Expand All @@ -31,25 +28,24 @@ pub trait Decoder {
fn fn_vl(&mut self, sum: i32, ps: usize, cn: Coord, dp: usize);
}

impl Decoder for FraveImage {
impl Decoder for FractalImage {
fn unquantizate(&mut self, quantization_matrix: &[i32]) {
self.coef = self
.coef
.iter()
.enumerate()
.map(|(i, coefficient)| {
let layer = bitwise::get_prev_power_two(i as u32 + 1).trailing_zeros();
(*coefficient).and_then(|s| Some(s * quantization_matrix[layer as usize]))
let layer = bitwise::get_prev_power_two(i + 1).trailing_zeros();
(*coefficient).map(|s| s * quantization_matrix[layer as usize])
})
.collect::<Vec<Option<i32>>>();
}

fn find_val(&mut self) {
if let Some(root) = self.coef[0] {
self.fn_vl(root, 1, self.center, self.depth - 1);
}
else {
println!("whoops")
} else {
println!("whoops");
}
}

Expand All @@ -59,11 +55,11 @@ impl Decoder for FraveImage {
let rt: i32 = ((sum + dif) * 2) >> 1;
if dp > 0 {
self.fn_vl(lt, ps << 1, cn, dp - 1);
self.fn_vl(rt, (ps << 1) + 1, cn + self.variant[dp], dp - 1)
self.fn_vl(rt, (ps << 1) + 1, cn + self.variant[dp], dp - 1);
} else {
let secondary_x = (cn.x + self.variant[0].x) as u32;
let secondary_y = (cn.y + self.variant[0].y) as u32;
self.set_pixel(cn.x as u32, cn.y as u32, lt);
let secondary_x = cn.x + self.variant[0].x;
let secondary_y = cn.y + self.variant[0].y;
self.set_pixel(cn.x, cn.y, lt);
self.set_pixel(secondary_x, secondary_y, rt);
}
}
Expand All @@ -72,7 +68,7 @@ impl Decoder for FraveImage {
fn ans_decode(&mut self, compressed_coef: Vec<u8>, ans_contexts: Vec<AnsContext>) {
let mut coef = vec![];
let depth = self.depth;
let scale_bits = (depth - 1) as u32;
let scale_bits = u32::try_from(depth - 1).unwrap();
let mut decoder: B64RansDecoderMulti<3> = B64RansDecoderMulti::new(compressed_coef);
let ctxs = ans_contexts;
let layers = vec![
Expand All @@ -81,24 +77,23 @@ impl Decoder for FraveImage {
(1 << (depth - 1))..(1 << depth),
];
for (i, layer) in layers.iter().enumerate() {
let cum_freqs = ans::cum_sum(&ctxs[2 - i].freq);
let mut cum_freqs = ans::cum_sum(&ctxs[2 - i].freq);
let cum_freq_to_symbols = ans::freqs_to_dec_symbols(&cum_freqs, &ctxs[2 - i].freq);
let symbol_map = cum_freqs
.iter()
.map(|e| e.to_owned())
.clone()
.into_iter()
.zip(ctxs[2 - i].symbols.clone())
.collect::<HashMap<u32, Option<i32>>>();
.collect::<HashMap<u32, i32>>();

let mut cum_freqs_sorted = cum_freqs.to_owned();
cum_freqs_sorted.sort();
cum_freqs.sort_unstable();

for _l in layer.clone() {
let cum_freq_decoded =
ans::find_nearest_or_equal(decoder.get_at(i, scale_bits), &cum_freqs_sorted);
ans::find_nearest_or_equal(decoder.get_at(i, scale_bits), &cum_freqs);
let symbol = symbol_map[&cum_freq_decoded];
decoder.advance_step_at(i, &cum_freq_to_symbols[&cum_freq_decoded], scale_bits);
decoder.renorm_at(i);
coef.push(symbol);
coef.push(Some(symbol));
}
}
self.coef = coef;
Expand Down
47 changes: 23 additions & 24 deletions src/encoder.rs → src/compression/encoder.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
use std::collections::HashMap;
use std::vec;

use itertools::Itertools;
use rans::b64_encoder::B64RansEncoderMulti;
use rans::RansEncoderMulti;

use crate::coord::Coord;
use crate::frave_image::FraveImage;
use crate::utils::ans;
use crate::utils::ans::AnsContext;
use crate::compression::ans::{self, AnsContext};
use crate::fractal::image::FractalImage;
use crate::utils::bitwise;
use itertools::Itertools;
use crate::utils::coordinate::Coord;

fn try_apply<T: Copy>(first: Option<T>, second: Option<T>, operation: fn(T, T) -> T) -> Option<T> {
match (first, second) {
(Some(f), Some(s)) => Some(operation(f, s)),
(Some(f), None) => Some(operation(f,f)),
(None, Some(s)) => Some(operation(s,s)),
(Some(f), None) => Some(operation(f, f)),
(None, Some(s)) => Some(operation(s, s)),
(None, None) => None,
}
}
Expand All @@ -42,11 +41,11 @@ pub trait Encoder {
/// - Haar tree pre-last layer
/// - Rest of the Haar tree
///
/// Applies rANS algorithm for coefficient compression
/// Applies `rANS` algorithm for coefficient compression
fn ans_encode(&self) -> (Vec<u8>, Vec<AnsContext>);
}

impl Encoder for FraveImage {
impl Encoder for FractalImage {
fn find_coef(&mut self) {
let lt = self.fn_cf(self.center, 2, self.depth - 2);
let rt = self.fn_cf(
Expand All @@ -65,11 +64,8 @@ impl Encoder for FraveImage {
lt = self.fn_cf(cn, ps << 1, dp - 1);
rt = self.fn_cf(cn + self.variant[dp], (ps << 1) + 1, dp - 1);
} else {
lt = self.get_pixel(cn.x as u32, cn.y as u32);
rt = self.get_pixel(
(cn.x + self.variant[0].x) as u32,
(cn.y + self.variant[0].y) as u32,
);
lt = self.get_pixel(cn.x, cn.y);
rt = self.get_pixel(cn.x + self.variant[0].x, cn.y + self.variant[0].y);
}

self.coef[ps] = try_apply(rt, lt, |r, l| (r - l) / 2);
Expand All @@ -82,37 +78,40 @@ impl Encoder for FraveImage {
.iter()
.enumerate()
.map(|(i, coefficient)| {
let layer = bitwise::get_prev_power_two(i as u32 + 1).trailing_zeros();
(*coefficient).and_then(|s| Some(s / quantization_matrix[layer as usize]))
let layer = bitwise::get_prev_power_two(i + 1).trailing_zeros();
(*coefficient).map(|s| s / quantization_matrix[layer as usize])
})
.collect::<Vec<Option<i32>>>();
}

fn ans_encode(&self) -> (Vec<u8>, Vec<AnsContext>) {
dbg!(&self.coef);
let layer1 = &self.coef[1 << (self.depth - 1)..];
let layer2 = &self.coef[1 << (self.depth - 2)..1 << (self.depth - 1)];
let layer3 = &self.coef[..1 << (self.depth - 2)];

let mut encoder: B64RansEncoderMulti<3> = B64RansEncoderMulti::new(1 << self.depth);
let mut contexts: Vec<ans::AnsContext> = vec![];

for (i, layer) in [layer1, layer2, layer3].iter().enumerate() {
let counter = layer.iter().counts();
let freq = counter.values().map(|e| *e as u32).collect::<Vec<u32>>();
let symbols = counter.keys().map(|e| **e).collect::<Vec<Option<i32>>>();
for (i, layer) in [layer1, layer2, layer3].into_iter().enumerate() {
let some_layer = layer.iter().flatten();
let counter = some_layer.clone().counts();
let freq = counter
.values()
.map(|e| u32::try_from(*e).unwrap())
.collect::<Vec<u32>>();
let symbols = counter.keys().map(|e| **e).collect::<Vec<i32>>();
let cdf = ans::cum_sum(&freq);

let symbol_map = ans::freqs_to_enc_symbols(&cdf, &freq, self.depth);

let cdf_map = counter
.clone()
.into_keys()
.map(|e| e.to_owned())
.zip(cdf.clone())
.collect::<HashMap<Option<i32>, u32>>();
.collect::<HashMap<&i32, u32>>();

layer
.iter()
some_layer
.rev()
.for_each(|s| encoder.put_at(i, &symbol_map[&cdf_map[s]]));

Expand Down
3 changes: 3 additions & 0 deletions src/compression/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod ans;
pub mod decoder;
pub mod encoder;
Loading

0 comments on commit a997614

Please sign in to comment.