@@ -2,10 +2,10 @@ use crate::{byte_iter::ByteIter, file_data::FileData, Certainty, Decoder};
22
33// thanks to BoilingTeapot for reverse engineering the compression
44
5- pub const ENTRY_LZSS_DC : Decoder < Box < [ u8 ] > > = Decoder {
6- id : "lzss-dc " ,
7- desc : "LZSS variant used in N7 DC" ,
8- detect : |buf| Certainty :: possible_if ( decode_header ( buf) . is_some ( ) ) ,
5+ pub const ENTRY_LZSS_BE : Decoder < Box < [ u8 ] > > = Decoder {
6+ id : "lzss-be " ,
7+ desc : "LZSS-like used in N7 DC and 12R PS2 " ,
8+ detect : |buf| Certainty :: certain_if ( decode_header ( buf) . is_some ( ) ) ,
99 decode
1010} ;
1111
@@ -20,21 +20,21 @@ fn decode_header(data: &mut FileData) -> Option<usize> {
2020
2121fn decode ( data : & mut FileData ) -> Result < Box < [ u8 ] > , String > {
2222 if let Some ( expected_size) = decode_header ( data) {
23- match decompress_lzss_dc ( & data. read ( ) [ 4 ..] , expected_size) {
23+ match decompress_lzss_be ( & data. read ( ) [ 4 ..] , expected_size) {
2424 Ok ( decompressed) => Ok ( decompressed) ,
25- Err ( Some ( actual_size) ) => Err ( format ! ( "expected {expected_size} bytes when decompressing, got only {actual_size}" ) ) ,
25+ Err ( Some ( actual_size) ) => Err ( format ! ( "expected {expected_size} bytes when decompressing, got {actual_size}" ) ) ,
2626 Err ( None ) => Err ( format ! ( "error while decompressing" ) )
2727 }
2828 } else {
2929 Err ( String :: new ( ) )
3030 }
3131}
3232
33- fn decompress_lzss_dc ( inp : & [ u8 ] , expected_size : usize ) -> Result < Box < [ u8 ] > , Option < usize > > {
33+ fn decompress_lzss_be ( inp : & [ u8 ] , expected_size : usize ) -> Result < Box < [ u8 ] > , Option < usize > > {
3434 let mut out = Vec :: with_capacity ( expected_size) ;
3535 let mut src = inp. iter ( ) . cloned ( ) ;
3636 while out. len ( ) < expected_size {
37- let chunk_size = src. next_u16_be ( ) . ok_or ( out. len ( ) ) ? as usize ;
37+ let chunk_size = src. next_u16_be ( ) . ok_or ( Some ( out. len ( ) ) ) ? as usize ;
3838 let mut chunk = src. by_ref ( ) . take ( chunk_size) ;
3939 let chunk_out_start = out. len ( ) ;
4040 // the flags byte determines whether the next 8 tokens are literals or references
@@ -43,25 +43,21 @@ fn decompress_lzss_dc(inp: &[u8], expected_size: usize) -> Result<Box<[u8]>, Opt
4343 if flags & ( 1 << i) == 0 { // literal token
4444 if let Some ( byte) = chunk. next ( ) {
4545 if out. len ( ) >= expected_size {
46- return Err ( None ) ;
46+ break ;
4747 }
4848 out. push ( byte) ;
4949 } else {
5050 break ;
5151 }
52- } else { // reference token
53- let ref_value = chunk . next_u16_be ( ) . ok_or ( None ) ? as usize ;
54- let ref_off = ( ref_value >> 5 ) + 1 ;
55- let ref_len = ( ref_value & 0b11111 ) + 3 ;
56- if ref_off >= out. len ( ) {
52+ } else if let Some ( ref_value ) = chunk . next_u16_be ( ) { // reference token
53+ let ref_off = ( ref_value as usize >> 5 ) + 1 ;
54+ let ref_len = ( ref_value as usize & 0b11111 ) + 3 ;
55+ let start = out . len ( ) as isize - ref_off as isize ;
56+ if ref_len > expected_size - out. len ( ) {
5757 return Err ( None ) ;
5858 }
59- let start = out. len ( ) - ref_off;
60- if out. len ( ) + ref_len > expected_size {
61- return Err ( None ) ;
62- }
63- for i in start..start + ref_len {
64- out. push ( * out. get ( i. max ( chunk_out_start) ) . ok_or ( None ) ?) ;
59+ for i in start..start + ref_len as isize {
60+ out. push ( * out. get ( i. max ( chunk_out_start as isize ) as usize ) . ok_or ( None ) ?) ;
6561 }
6662 }
6763 }
0 commit comments