]>
git.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
);