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}