11macro_rules! impl_byte_readers {
22 ( $( $t: ty) ,* ) => { paste:: paste! { $(
3- fn [ <read_ $t _field >] ( & self , offset: usize , name : & ' static str ) -> Result <$t, String > {
4- Ok ( $t:: from_le_bytes( self . get( offset..offset + size_of:: <$t>( ) ) . ok_or_else( #[ cold] || format!( "could not read {name} " ) ) ?. try_into( ) . unwrap( ) ) )
3+ fn [ <read_ $t>] ( & self , offset: usize ) -> Result <$t, String > {
4+ Ok ( $t:: from_le_bytes( self . get( offset..offset + size_of:: <$t>( ) ) . ok_or_else( #[ cold] || format!( "error reading field " ) ) ?. try_into( ) . unwrap( ) ) )
55 }
6- fn [ <read_ $t _field_be >] ( & self , offset: usize , name : & ' static str ) -> Result <$t, String > {
7- Ok ( $t:: from_be_bytes( self . get( offset..offset + size_of:: <$t>( ) ) . ok_or_else( #[ cold] || format!( "could not read {name} " ) ) ?. try_into( ) . unwrap( ) ) )
6+ fn [ <read_ $t _be >] ( & self , offset: usize ) -> Result <$t, String > {
7+ Ok ( $t:: from_be_bytes( self . get( offset..offset + size_of:: <$t>( ) ) . ok_or_else( #[ cold] || format!( "error reading field " ) ) ?. try_into( ) . unwrap( ) ) )
88 }
99 fn [ <get_ $t _at>] ( & self , offset: usize ) -> Option <$t> {
1010 Some ( $t:: from_le_bytes( self . get( offset..offset + size_of:: <$t>( ) ) ?. try_into( ) . unwrap( ) ) )
@@ -16,26 +16,28 @@ macro_rules! impl_byte_readers {
1616}
1717
1818pub trait ByteSlice {
19- fn read_u8_field ( & self , offset : usize , name : & ' static str ) -> Result < u8 , String > ;
20- fn read_u16_field ( & self , offset : usize , name : & ' static str ) -> Result < u16 , String > ;
21- fn read_u32_field ( & self , offset : usize , name : & ' static str ) -> Result < u32 , String > ;
22- fn read_u64_field ( & self , offset : usize , name : & ' static str ) -> Result < u64 , String > ;
23- fn read_usize_field ( & self , offset : usize , name : & ' static str ) -> Result < usize , String > ;
24- fn read_i8_field ( & self , offset : usize , name : & ' static str ) -> Result < i8 , String > ;
25- fn read_i16_field ( & self , offset : usize , name : & ' static str ) -> Result < i16 , String > ;
26- fn read_i32_field ( & self , offset : usize , name : & ' static str ) -> Result < i32 , String > ;
27- fn read_i64_field ( & self , offset : usize , name : & ' static str ) -> Result < i64 , String > ;
28- fn read_isize_field ( & self , offset : usize , name : & ' static str ) -> Result < isize , String > ;
29- fn read_u8_field_be ( & self , offset : usize , name : & ' static str ) -> Result < u8 , String > ;
30- fn read_u16_field_be ( & self , offset : usize , name : & ' static str ) -> Result < u16 , String > ;
31- fn read_u32_field_be ( & self , offset : usize , name : & ' static str ) -> Result < u32 , String > ;
32- fn read_u64_field_be ( & self , offset : usize , name : & ' static str ) -> Result < u64 , String > ;
33- fn read_usize_field_be ( & self , offset : usize , name : & ' static str ) -> Result < usize , String > ;
34- fn read_i8_field_be ( & self , offset : usize , name : & ' static str ) -> Result < i8 , String > ;
35- fn read_i16_field_be ( & self , offset : usize , name : & ' static str ) -> Result < i16 , String > ;
36- fn read_i32_field_be ( & self , offset : usize , name : & ' static str ) -> Result < i32 , String > ;
37- fn read_i64_field_be ( & self , offset : usize , name : & ' static str ) -> Result < i64 , String > ;
38- fn read_isize_field_be ( & self , offset : usize , name : & ' static str ) -> Result < isize , String > ;
19+ fn starts_with_at ( & self , needle : & [ u8 ] , offset : usize ) -> bool ;
20+ fn read_bytes ( & self , offset : usize , len : usize , name : & str ) -> Result < & [ u8 ] , String > ;
21+ fn read_u8 ( & self , offset : usize ) -> Result < u8 , String > ;
22+ fn read_u16 ( & self , offset : usize ) -> Result < u16 , String > ;
23+ fn read_u32 ( & self , offset : usize ) -> Result < u32 , String > ;
24+ fn read_u64 ( & self , offset : usize ) -> Result < u64 , String > ;
25+ fn read_usize ( & self , offset : usize ) -> Result < usize , String > ;
26+ fn read_i8 ( & self , offset : usize ) -> Result < i8 , String > ;
27+ fn read_i16 ( & self , offset : usize ) -> Result < i16 , String > ;
28+ fn read_i32 ( & self , offset : usize ) -> Result < i32 , String > ;
29+ fn read_i64 ( & self , offset : usize ) -> Result < i64 , String > ;
30+ fn read_isize ( & self , offset : usize ) -> Result < isize , String > ;
31+ fn read_u8_be ( & self , offset : usize ) -> Result < u8 , String > ;
32+ fn read_u16_be ( & self , offset : usize ) -> Result < u16 , String > ;
33+ fn read_u32_be ( & self , offset : usize ) -> Result < u32 , String > ;
34+ fn read_u64_be ( & self , offset : usize ) -> Result < u64 , String > ;
35+ fn read_usize_be ( & self , offset : usize ) -> Result < usize , String > ;
36+ fn read_i8_be ( & self , offset : usize ) -> Result < i8 , String > ;
37+ fn read_i16_be ( & self , offset : usize ) -> Result < i16 , String > ;
38+ fn read_i32_be ( & self , offset : usize ) -> Result < i32 , String > ;
39+ fn read_i64_be ( & self , offset : usize ) -> Result < i64 , String > ;
40+ fn read_isize_be ( & self , offset : usize ) -> Result < isize , String > ;
3941 fn get_u8_at ( & self , offset : usize ) -> Option < u8 > ;
4042 fn get_u16_at ( & self , offset : usize ) -> Option < u16 > ;
4143 fn get_u32_at ( & self , offset : usize ) -> Option < u32 > ;
@@ -56,8 +58,34 @@ pub trait ByteSlice {
5658 fn get_i32_at_be ( & self , offset : usize ) -> Option < i32 > ;
5759 fn get_i64_at_be ( & self , offset : usize ) -> Option < i64 > ;
5860 fn get_isize_at_be ( & self , offset : usize ) -> Option < isize > ;
61+ fn unswizzled_psp ( & self , width : u32 , height : u32 ) -> Vec < u8 > ;
5962}
6063
61- impl ByteSlice for & [ u8 ] {
64+ impl ByteSlice for [ u8 ] {
65+ fn starts_with_at ( & self , needle : & [ u8 ] , offset : usize ) -> bool {
66+ self . get ( offset..offset + needle. len ( ) ) . map_or ( false , |x| x. starts_with ( needle) )
67+ }
68+
69+ fn read_bytes ( & self , offset : usize , len : usize , name : & str ) -> Result < & [ u8 ] , String > {
70+ Ok ( self . get ( offset..offset + len) . ok_or_else ( #[ cold] || format ! ( "error reading {name}" ) ) ?. try_into ( ) . unwrap ( ) )
71+ }
72+
6273 impl_byte_readers ! ( u8 , u16 , u32 , u64 , usize , i8 , i16 , i32 , i64 , isize ) ;
74+
75+ fn unswizzled_psp ( & self , width_bytes : u32 , height : u32 ) -> Vec < u8 > {
76+ let mut pixels = Vec :: with_capacity ( self . len ( ) ) ;
77+ let blocks_per_row = width_bytes / 16 ;
78+ for y in 0 ..height {
79+ for x in 0 ..width_bytes {
80+ let block_idx_x = x / 16 ;
81+ let block_idx_y = y / 8 ;
82+ let x_in_block = x % 16 ;
83+ let y_in_block = y % 8 ;
84+ let block_start = ( block_idx_y * blocks_per_row + block_idx_x) * ( 16 * 8 ) ;
85+ let swizzled_idx = block_start + y_in_block * 16 + x_in_block;
86+ pixels. push ( self . get ( swizzled_idx as usize ) . cloned ( ) . unwrap_or_default ( ) ) ;
87+ }
88+ }
89+ pixels
90+ }
6391}
0 commit comments