]>
cvs.zerfleddert.de Git - rsbs2/blob - rsb-lz.c
c771b894ffa4ddc314635bf23e1677de0d3cf687
   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 void set_next_bit(unsigned char *buf
, unsigned int set
, unsigned int *currbit
) { 
 148         unsigned char bitpos
; 
 151                 pos 
= buf 
+ ((*currbit
) / 8); 
 152                 bitpos 
= 0x80 >> ((*currbit
) % 8); 
 156         *currbit 
= *currbit 
+ 1; 
 159 void write_bits(unsigned char *buf
, unsigned int data
, unsigned int bits
, unsigned int *currbit
) { 
 163         bitpos 
= 1 << (bits 
- 1); 
 165         for (i 
= 0; i 
< bits
; i
++) { 
 166                 set_next_bit(buf
, data 
& bitpos
, currbit
); 
 171 unsigned char *compress_lz(unsigned char *inbuf
, int inlen
, int *outlen
) 
 173         unsigned char *end 
= inbuf 
+ inlen
; 
 174         unsigned char *outbuf
; 
 175         unsigned char window
[1024]; 
 178         unsigned int currbit 
= 0; 
 184         if ((outbuf 
= malloc((inlen 
* 2) + 4)) == NULL
) { 
 188         *((unsigned int*)outbuf
) = LZ_MAGIC
; 
 193                 for (wordlen 
= 17; wordlen 
> 1; wordlen
--) { 
 194                         for (offset 
= 1; offset 
< ((fill 
< 1023) ? fill 
: 1023); offset
++) { 
 196                                     (wordlen 
+ offset 
> fill
)) 
 199                                 for (i 
= 0; i 
< wordlen
; i
++) { 
 200                                         if (inbuf
[i
] != window
[(offset 
+ i
) & 0x3ff]) { 
 212                         write_bits(outbuf
, 0x00, 0x01, &currbit
); 
 213                         write_bits(outbuf
, offset
, 0x0a, &currbit
); 
 214                         write_bits(outbuf
, wordlen 
- 1, 0x04, &currbit
); 
 215                         for (i 
= 0; i 
< wordlen
; i
++) { 
 216                                 window
[pos
] = *(inbuf 
+ i
); 
 217                                 pos 
= (pos 
+ 1) & 0x3ff; 
 221                         if (fill 
< sizeof(window
)) 
 224                         write_bits(outbuf
, 0x01, 0x01, &currbit
); 
 225                         write_bits(outbuf
, *inbuf
, 0x08, &currbit
); 
 226                         window
[pos
] = *inbuf
; 
 227                         pos 
= (pos 
+ 1) & 0x3ff; 
 229                         if (fill 
< sizeof(window
)) 
 234         write_bits(outbuf
, 0x00, 0x01, &currbit
); 
 235         write_bits(outbuf
, 0x00, 0x0a, &currbit
); 
 237         *outlen 
= (currbit 
/ 8) + 1; 
 239         *((unsigned int*)(outbuf 
+ 4)) = *outlen
; 
 244 /* Checksum is only used for the compressed firmware in 'firmware' */ 
 245 unsigned int crc_check(unsigned char *buf
, unsigned int len
, unsigned int magic
) 
 247         unsigned int file_crc
; 
 250         unsigned int my_magic
; 
 252         my_len 
= *((unsigned int*)(buf 
+ 0x20)); 
 253         my_magic 
= *((unsigned int*)(buf 
+ 0x24)); 
 255         if (my_magic 
!= magic
) { 
 256                 printf("\nmagic: 0x%08x <-> 0x%08x\n", my_magic
, magic
); 
 263         crc 
= ~rsb_crc(~0x00, buf
, len
); 
 264         file_crc 
= *((unsigned int*)(buf 
+ len
)); 
 266         if (file_crc 
!= crc
) { 
 267                 printf("\nChecksums: 0x%08x <-> 0x%08x!\n", crc
, file_crc
); 
 274 void extract_lz_file(unsigned char *inbuf
, unsigned char *name
, unsigned char check_crc
) 
 277         unsigned char *outbuf
; 
 278         struct data_in_s data_in
; 
 279         struct data_out_s data_out
; 
 281         if (*((unsigned int*)inbuf
) != LZ_MAGIC
) 
 284         len 
= *((unsigned int*)(inbuf 
+ 4)); 
 285         printf(", length: %d", len
); 
 287         if ((outbuf 
= malloc(len
)) == NULL
) { 
 294         data_in
.start 
= inbuf 
+ 8; 
 295         data_in
.stop 
= inbuf 
+ len
; 
 297         data_in
.bitpos 
= 0x80; 
 299         data_out
.pos 
= outbuf
; 
 300         data_out
.end 
= outbuf 
+ len
; 
 302         lz_expand(&data_in
, &data_out
); 
 308                 crclen 
= *((unsigned int*)(outbuf 
+ 0x20)); 
 310                 if ((ret 
= crc_check(outbuf
, crclen
, 0x46335053)) != 0) { 
 311                         printf("crc_check return: %d\n", ret
); 
 315         write_file(extracted_file((char*)name
), outbuf
, len
);