stegano_core/
universal_decoder.rs1use bitstream_io::{BitWrite, BitWriter, LittleEndian};
2use enum_dispatch::enum_dispatch;
3use std::io::{BufWriter, Read, Result};
4
5use crate::media::MediaPrimitive;
6
7#[allow(unused)]
8#[enum_dispatch]
9pub enum UnveilAlgorithms {
10 OneBitUnveil,
11}
12
13#[enum_dispatch(UnveilAlgorithms)]
15pub trait UnveilAlgorithm {
16 fn decode(&self, carrier: MediaPrimitive) -> bool;
17}
18
19pub struct UniversalDecoder<I, A>
21where
22 I: Iterator<Item = MediaPrimitive>,
23 A: UnveilAlgorithm,
24{
25 pub input: I,
26 pub algorithm: A,
27 position: usize,
28}
29
30impl<I, A> UniversalDecoder<I, A>
32where
33 I: Iterator<Item = MediaPrimitive>,
34 A: UnveilAlgorithm,
35{
36 pub fn new(input: I, algorithm: A) -> Self {
37 UniversalDecoder {
38 input,
39 algorithm,
40 position: 0,
41 }
42 }
43}
44
45impl<I, A> Read for UniversalDecoder<I, A>
46where
47 I: Iterator<Item = MediaPrimitive>,
48 A: UnveilAlgorithm,
49{
50 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
51 let items_to_take = buf.len() << 3; let buf_writer = BufWriter::new(buf);
54 let mut bit_buffer = BitWriter::endian(buf_writer, LittleEndian);
55
56 let mut bit_read: usize = 0;
57 for carrier in self.input.by_ref().take(items_to_take) {
58 let bit = self.algorithm.decode(carrier);
59 bit_buffer.write_bit(bit)?;
60 bit_read += 1;
61 }
62
63 if !bit_buffer.byte_aligned() {
64 bit_buffer.byte_align()?
65 }
66
67 self.position += bit_read >> 3;
68
69 Ok(bit_read >> 3)
70 }
71}
72
73#[derive(Debug)]
75pub struct OneBitUnveil;
76impl UnveilAlgorithm for OneBitUnveil {
77 #[inline]
78 fn decode(&self, carrier: MediaPrimitive) -> bool {
79 match carrier {
80 MediaPrimitive::ImageColorChannel(b) => (b & 0x1) > 0,
81 MediaPrimitive::AudioSample(b) => (b & 0x1) > 0,
82 }
83 }
84}