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
37
38
39
40
41
42
43
44
45
use super::*;

// PowerPC
impl BCJFilter {
    pub fn new_power_pc(start_pos: usize, encoder: bool) -> Self {
        Self {
            is_encoder: encoder,
            pos: start_pos,
            prev_mask: 0,
            filter: Self::ppc_code,
        }
    }

    fn ppc_code(&mut self, buf: &mut [u8]) -> usize {
        if buf.len() < 4 {
            return 0;
        }
        let end = buf.len() - 4;
        let mut i = 0;
        while i <= end {
            let b3 = buf[i + 3] as i32;
            let b0 = buf[i] as i32;

            if (b0 & 0xFC) == 0x48 && (b3 & 0x03) == 0x01 {
                let b2 = buf[i + 2] as i32;
                let b1 = buf[i + 1] as i32;

                let src =
                    ((b0 & 0x03) << 24) | ((b1 & 0xff) << 16) | ((b2 & 0xff) << 8) | (b3 & 0xFC);

                let p = (self.pos + i) as i32;
                let dest = if self.is_encoder { src + p } else { src - p };

                buf[i] = (0x48 | ((dest >> 24) & 0x03)) as u8;
                buf[i + 1] = (dest >> 16) as u8;
                buf[i + 2] = (dest >> 8) as u8;
                buf[i + 3] = ((b3 & 0x03) | dest) as u8;
            }
            i += 4;
        }

        self.pos += i;
        i
    }
}