1#[macro_use]
2extern crate log;
3
4#[cfg(test)]
5mod test;
6
7pub const HEADER: u8 = 0b00001111;
8const SHORTENED: u8 = 0b01000000;
9
10const DEFAULT_MIME: &'static str = "image/jpg";
11const ILLEGALS: [u8; 6] = [0, 10, 13, 34, 38, 92];
12
13pub struct Encoder<'a> {
14 data: &'a [u8],
15 bit_index: usize,
16 byte_index: usize,
17}
18
19fn is_illegal(byte: u8) -> Option<u8> {
20 for (index, illegal_byte) in ILLEGALS.iter().enumerate() {
21 if *illegal_byte == byte {
22 return Some(index as u8);
23 }
24 }
25
26 None
27}
28
29fn fmt_buf(data: &[u8]) -> String {
30 let mut s = String::with_capacity(data.len() * 8);
31 for byte in data.iter() {
32 s.push_str(&format!("{:08b}", byte));
33 }
34 s
35}
36
37impl<'a> Encoder<'a> {
38 pub fn new(data: &[u8]) -> Encoder {
39 Encoder {
40 data: data,
41 bit_index: 0,
42 byte_index: 0,
43 }
44 }
45
46 fn get7(&mut self) -> Result<u8, ()> {
47 if self.byte_index < self.data.len() {
48 let first_byte = self.data[self.byte_index];
49 let first_part = (((0b11111110 >> self.bit_index) & first_byte) << self.bit_index) >> 1;
50
51 self.bit_index += 7;
52 if self.bit_index < 8 {
53 Ok(first_part)
54 } else {
55 self.bit_index -= 8;
56 self.byte_index += 1;
57
58 if self.byte_index >= self.data.len() {
59 Ok(first_part)
60 } else {
61 let second_byte = self.data[self.byte_index];
62 let second_part = (((0xFF00u16 >> self.bit_index) as u8 & second_byte) &
63 0xFF) >>
64 8 - self.bit_index;
65
66 Ok(first_part | second_part)
67 }
68 }
69 } else {
70 Err(())
71 }
72 }
73
74 pub fn encode(&mut self) -> Vec<u8> {
75 let mut buf = Vec::new();
76 let mut header = HEADER;
77 buf.push(header);
78
79 while let Ok(bits) = self.get7() {
80 if let Some(illegal_index) = is_illegal(bits) {
81 debug!("Handle illegal sequence: {:08b}", bits);
82 let mut b1: u8 = 0b11000010 | (0b111 & illegal_index) << 2;
83 let mut b2: u8 = 0b10000000;
84 if let Ok(next_bits) = self.get7() {
85 debug!("Additional bits to two - byte character {:08b}", next_bits);
86
87 let first_bit: u8 = if (next_bits & 0b01000000) > 0 { 1 } else { 0 };
88 b1 |= first_bit;
89 b2 |= next_bits & 0b00111111;
90 } else {
91 debug!("Last seven bits are an illegal sequence, and there are no more bits \
92 left");
93
94 header |= SHORTENED;
95 }
96 debug!("Adding to buffer: {:08b}{:08b}", b1, b2);
97 buf.push(b1);
98 buf.push(b2);
99 } else {
100 debug!("Adding to buffer: {:08b}", bits);
101 buf.push(bits);
102 }
103 }
104
105 debug!("Adding header to buffer: {:08b}", header);
106 buf[0] = header;
107
108 debug!("Returning buffer: {}", fmt_buf(&buf));
109 buf
110 }
111}