@@ -301,6 +301,18 @@ impl Directory {
301301 } )
302302 }
303303
304+ pub fn calc_new_offset ( & self , min_offset : u32 ) -> Result < u32 , String > {
305+ if let Some ( ( offset, m) ) = self . get_huffman_mod ( ) {
306+ let b = ( m. header . addr_base & 0x00ff_ffff ) >> 8 ;
307+ let lut_offset = ( offset + LUT_HEADER_SIZE ) as u32 ;
308+ let mx = min_offset. max ( b - lut_offset) ;
309+ // NOTE: Must be aligned to 0x20.
310+ return Ok ( mx. next_multiple_of ( 0x20 ) ) ;
311+ }
312+
313+ Err ( "new offset cannot be calculated" . into ( ) )
314+ }
315+
304316 fn dump_ranges ( ranges : & Vec < Range < usize > > ) {
305317 let group_size = 4 ;
306318 for ( i, r) in ranges. iter ( ) . enumerate ( ) {
@@ -357,6 +369,40 @@ impl Directory {
357369 } )
358370 . collect :: < Vec < Range < usize > > > ( )
359371 }
372+
373+ pub fn rebase_huffman_chunks ( & mut self , offset_diff : u32 ) -> Result < ( ) , String > {
374+ if let Some ( Module :: Huffman ( Ok ( ( _, h) ) ) ) = self
375+ . modules
376+ . iter_mut ( )
377+ . find ( |m| matches ! ( m, Module :: Huffman ( Ok ( _) ) ) )
378+ {
379+ h. header . spi_base -= offset_diff;
380+ h. header . hs1 -= offset_diff;
381+ for c in & mut h. chunks {
382+ // The 3 low bytes are the actual offset.
383+ // An inactive chunk must not be changed and has offset 0.
384+ if ( * c >> 24 ) as u8 == CHUNK_INACTIVE {
385+ //
386+ } else {
387+ * c = * c - offset_diff;
388+ } ;
389+ }
390+ return Ok ( ( ) ) ;
391+ }
392+ Err ( "no Huffman chunks found" . into ( ) )
393+ }
394+
395+ pub fn get_huffman_mod ( & self ) -> Option < ( usize , & HuffmanModule ) > {
396+ if let Some ( Module :: Huffman ( Ok ( ( e, h) ) ) ) = self
397+ . modules
398+ . iter ( )
399+ . find ( |m| matches ! ( m, Module :: Huffman ( Ok ( _) ) ) )
400+ {
401+ let lut_header_offset = e. offset as usize ;
402+ return Some ( ( lut_header_offset, & h) ) ;
403+ }
404+ None
405+ }
360406}
361407
362408impl Removables for Directory {
0 commit comments