aboutsummaryrefslogtreecommitdiff
path: root/evc/src/codec/decode.rs
blob: b1f6a3db4833a3eff0aaa22fb2ecf2b5d1f147eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
use super::compress::lit_decompress;
use crate::{
    block::Block, frame::Frame, helpers::threading::both_par, refsampler::Sampler, view::View,
};

pub struct DecodeConfig {}

pub fn decode_block(
    block: &Block,
    mut target: View<&mut Frame>,
    prev: View<&Frame>,
    config: &DecodeConfig,
) {
    match &block {
        Block::Literal(pixels) => target.set_pixels(pixels),
        Block::Split(box [a, b]) => {
            let [a, b] = unsafe { std::mem::transmute::<_, [&'static Block; 2]>([a, b]) };
            let [at, bt] = unsafe {
                std::mem::transmute::<_, [View<&'static mut Frame>; 2]>(target.split_mut_unsafe())
            };
            let [ap, bp] =
                unsafe { std::mem::transmute::<_, [View<&'static Frame>; 2]>(prev.split()) };
            let config = unsafe { std::mem::transmute::<_, &'static DecodeConfig>(config) };

            rayon::join(
                move || decode_block(a, at, ap, config),
                move || decode_block(b, bt, bp, config),
            );
        }
        Block::CompressedLiteral(data) => {
            lit_decompress(&data, target);
        }
        Block::Reference { translation } => target.copy_from(&prev.offset(*translation)),
        Block::AdvancedReference(r) => target.copy_from_sampler(&Sampler::from_refblock(prev, r)),
    }
}