]>
cvs.zerfleddert.de Git - rsbs2/blob - rsb-lz.c
4dddd9b37997d778f316472bad6cb7e736ab0d59
   9 #include "filesystem.h" 
  11 void err_exit(const char *fname
) 
  13         fprintf(stderr
,"%s: error extracting...\n", fname
); 
  29 unsigned char get_next_in_byte(struct data_in_s 
*data_in
) 
  33         if (data_in
->stop 
< data_in
->start
) 
  36         byte 
= *(data_in
->start
); 
  42 unsigned char get_next_bit(struct data_in_s 
*data_in
) 
  46         if (data_in
->bitpos 
== 0x80) { 
  47                 data_in
->byte 
= get_next_in_byte(data_in
); 
  50         bitval 
= data_in
->bitpos 
& data_in
->byte
; 
  52         data_in
->bitpos 
>>= 1; 
  53         if (data_in
->bitpos 
== 0) { 
  54                 data_in
->bitpos 
= 0x80; 
  63 unsigned int get_next_bits(struct data_in_s 
*data_in
, unsigned int bits
) 
  66         unsigned int next_bits
; 
  68         bit 
= 1 << (bits 
- 1); 
  72                 if (data_in
->bitpos 
== 0x80) { 
  73                         data_in
->byte 
= get_next_in_byte(data_in
); 
  76                 if ((data_in
->bitpos 
& data_in
->byte
) != 0) 
  77                         next_bits 
= next_bits 
| bit
; 
  81                 data_in
->bitpos 
>>= 1; 
  83                 if(data_in
->bitpos 
== 0) { 
  84                         data_in
->bitpos 
= 0x80; 
  91 void write_byte(unsigned char byte
, struct data_out_s 
*data_out
) 
  93         if (data_out
->pos 
> data_out
->end
) { 
  97         *(data_out
->pos
) = byte
; 
 101 void lz_expand(struct data_in_s 
*data_in
, struct data_out_s 
*data_out
) 
 104         unsigned int wordoffset
; 
 107         unsigned int wordlen
; 
 108         unsigned char buf
[1024]; 
 114                         /* Compressed/uncompressed? */ 
 115                         if (get_next_bit(data_in
) == 0) 
 118                         /* Uncompressed byte */ 
 119                         byte 
= get_next_bits(data_in
, 8); 
 121                         write_byte(byte
, data_out
); 
 123                         /* Save byte in buffer, to be reused later */ 
 125                         pos 
= (pos 
+ 1) & 0x3ff; 
 128                 /* offset for start of dictionary word */ 
 129                 wordoffset 
= get_next_bits(data_in
, 0x0a); 
 133                 /* length of dictionary word used */ 
 134                 wordlen 
= get_next_bits(data_in
, 0x04) + 1; 
 135                 for (i 
= 0; i 
<= wordlen 
; i
++) { 
 136                         /* lookup dictionary byte */ 
 137                         byte 
= buf
[(wordoffset 
+ i
) & 0x3ff]; 
 138                         write_byte(byte
, data_out
); 
 139                         /* Save byte in buffer, to be reused later */ 
 141                         pos 
= (pos 
+ 1) & 0x3ff; 
 146 /* Checksum is only used for the compressed firmware in 'firmware' */ 
 147 unsigned int crc_check(unsigned char *buf
, unsigned int len
, unsigned int magic
) 
 149         unsigned int file_crc
; 
 152         unsigned int my_magic
; 
 154         my_len 
= *((unsigned int*)(buf 
+ 0x20)); 
 155         my_magic 
= *((unsigned int*)(buf 
+ 0x24)); 
 157         if (my_magic 
!= magic
) { 
 158                 printf("\nmagic: 0x%08x <-> 0x%08x\n", my_magic
, magic
); 
 165         crc 
= ~rsb_crc(~0x00, buf
, len
); 
 166         file_crc 
= *((unsigned int*)(buf 
+ len
)); 
 168         if (file_crc 
!= crc
) { 
 169                 printf("\nChecksums: 0x%08x <-> 0x%08x!\n", crc
, file_crc
); 
 176 void extract_lz_file(unsigned char *inbuf
, unsigned char *name
, unsigned char check_crc
) 
 179         unsigned char *outbuf
; 
 180         struct data_in_s data_in
; 
 181         struct data_out_s data_out
; 
 183         if (*((unsigned int*)inbuf
) != LZ_MAGIC
) 
 186         len 
= *((unsigned int*)(inbuf 
+ 4)); 
 187         printf(", length: %d", len
); 
 189         if ((outbuf 
= malloc(len
)) == NULL
) { 
 196         data_in
.start 
= inbuf 
+ 8; 
 197         data_in
.stop 
= inbuf 
+ len
; 
 199         data_in
.bitpos 
= 0x80; 
 201         data_out
.pos 
= outbuf
; 
 202         data_out
.end 
= outbuf 
+ len
; 
 204         lz_expand(&data_in
, &data_out
); 
 210                 crclen 
= *((unsigned int*)(outbuf 
+ 0x20)); 
 212                 if ((ret 
= crc_check(outbuf
, crclen
, 0x46335053)) != 0) { 
 213                         printf("crc_check return: %d\n", ret
); 
 218         write_file((char*)name
, outbuf
, len
);