sevenz_rust/bcj/
arm.rs

1use super::*;
2
3impl BCJFilter {
4    pub fn new_arm(start_pos: usize, encoder: bool) -> Self {
5        Self {
6            is_encoder: encoder,
7            pos: start_pos + 8,
8            prev_mask: 0,
9            filter: Self::arm_code,
10        }
11    }
12
13    pub fn new_arm_thumb(start_pos: usize, encoder: bool) -> Self {
14        Self {
15            is_encoder: encoder,
16            pos: start_pos + 4,
17            prev_mask: 0,
18            filter: Self::arm_thumb_code,
19        }
20    }
21
22    fn arm_code(&mut self, buf: &mut [u8]) -> usize {
23        let len = buf.len();
24        if len < 4 {
25            return 0;
26        }
27        let end = len - 4;
28        let mut i = 0;
29        while i <= end {
30            let b3 = buf[i + 3];
31
32            if b3 == 0xEB {
33                let b2 = buf[i + 2] as i32;
34                let b1 = buf[i + 1] as i32;
35                let b0 = buf[i] as i32;
36
37                let src = ((b2 << 16) | (b1 << 8) | (b0)) << 2;
38                let p = (self.pos + i) as i32;
39                let dest = if self.is_encoder { src + p } else { src - p };
40                let dest = dest >> 2;
41                buf[i + 2] = ((dest >> 16) & 0xff) as u8;
42                buf[i + 1] = ((dest >> 8) & 0xff) as u8;
43                buf[i] = (dest & 0xff) as u8;
44            }
45            i += 4;
46        }
47
48        self.pos += i;
49        i
50    }
51
52    fn arm_thumb_code(&mut self, buf: &mut [u8]) -> usize {
53        let len = buf.len();
54        if len < 4 {
55            return 0;
56        }
57        let end = len - 4;
58
59        let mut i = 0;
60        while i <= end {
61            let b1 = buf[i + 1] as i32;
62            let b3 = buf[i + 3] as i32;
63
64            if (b3 & 0xF8) == 0xF8 && (b1 & 0xF8) == 0xF0 {
65                let b2 = buf[i + 2] as i32;
66                let b0 = buf[i] as i32;
67
68                let src =
69                    ((b1 & 0x07) << 19) | ((b0 & 0xFF) << 11) | ((b3 & 0x07) << 8) | (b2 & 0xFF);
70                let src = src << 1;
71
72                let dest = if self.is_encoder {
73                    src + (self.pos + i) as i32
74                } else {
75                    src - (self.pos + i) as i32
76                };
77                let dest = dest >> 1;
78                buf[i + 1] = (0xF0 | ((dest >> 19) & 0x07)) as u8;
79                buf[i] = (dest >> 11) as u8;
80                buf[i + 3] = (0xf8 | ((dest >> 8) & 0x07)) as u8;
81                buf[i + 2] = ((dest) & 0xff) as u8;
82                i += 2;
83            }
84            i += 2;
85        }
86
87        self.pos += i;
88        i
89    }
90}