]>
cvs.zerfleddert.de Git - rsbs2/blob - src/rsb-lz.c
10 #include "filesystem.h"
12 void err_exit(const char *fname
)
14 fprintf(stderr
,"%s: error extracting...\n", fname
);
30 uint8_t get_next_in_byte(struct data_in_s
*data_in
)
34 if (data_in
->stop
< data_in
->start
)
37 byte
= *(data_in
->start
);
43 uint8_t get_next_bit(struct data_in_s
*data_in
)
47 if (data_in
->bitpos
== 0x80) {
48 data_in
->byte
= get_next_in_byte(data_in
);
51 bitval
= data_in
->bitpos
& data_in
->byte
;
53 data_in
->bitpos
>>= 1;
54 if (data_in
->bitpos
== 0) {
55 data_in
->bitpos
= 0x80;
64 uint32_t get_next_bits(struct data_in_s
*data_in
, uint32_t bits
)
69 bit
= 1 << (bits
- 1);
73 if (data_in
->bitpos
== 0x80) {
74 data_in
->byte
= get_next_in_byte(data_in
);
77 if ((data_in
->bitpos
& data_in
->byte
) != 0)
78 next_bits
= next_bits
| bit
;
82 data_in
->bitpos
>>= 1;
84 if(data_in
->bitpos
== 0) {
85 data_in
->bitpos
= 0x80;
92 void write_byte(uint8_t byte
, struct data_out_s
*data_out
)
94 if (data_out
->pos
> data_out
->end
) {
98 *(data_out
->pos
) = byte
;
102 void lz_expand(struct data_in_s
*data_in
, struct data_out_s
*data_out
)
115 /* Compressed/uncompressed? */
116 if (get_next_bit(data_in
) == 0)
119 /* Uncompressed byte */
120 byte
= get_next_bits(data_in
, 8);
122 write_byte(byte
, data_out
);
124 /* Save byte in buffer, to be reused later */
126 pos
= (pos
+ 1) & 0x3ff;
129 /* offset for start of dictionary word */
130 wordoffset
= get_next_bits(data_in
, 0x0a);
134 /* length of dictionary word used */
135 wordlen
= get_next_bits(data_in
, 0x04) + 1;
136 for (i
= 0; i
<= wordlen
; i
++) {
137 /* lookup dictionary byte */
138 byte
= buf
[(wordoffset
+ i
) & 0x3ff];
139 write_byte(byte
, data_out
);
140 /* Save byte in buffer, to be reused later */
142 pos
= (pos
+ 1) & 0x3ff;
147 void set_next_bit(uint8_t *buf
, uint32_t set
, uint32_t *currbit
) {
152 pos
= buf
+ ((*currbit
) / 8);
153 bitpos
= 0x80 >> ((*currbit
) % 8);
157 *currbit
= *currbit
+ 1;
160 void write_bits(uint8_t *buf
, uint32_t data
, uint32_t bits
, uint32_t *currbit
) {
164 bitpos
= 1 << (bits
- 1);
166 for (i
= 0; i
< bits
; i
++) {
167 set_next_bit(buf
, data
& bitpos
, currbit
);
172 uint8_t *compress_lz(uint8_t *inbuf
, int32_t inlen
, int32_t *outlen
)
174 uint8_t *end
= inbuf
+ inlen
;
176 uint8_t window
[1024];
179 uint32_t currbit
= 0;
185 if ((outbuf
= malloc((inlen
* 2) + 4)) == NULL
) {
189 *((uint32_t*)outbuf
) = LZ_MAGIC
;
194 for (wordlen
= 17; wordlen
> 1; wordlen
--) {
195 for (offset
= 1; offset
< ((fill
< 1023) ? fill
: 1023); offset
++) {
197 (wordlen
+ offset
> fill
))
200 for (i
= 0; i
< wordlen
; i
++) {
201 if (inbuf
[i
] != window
[(offset
+ i
) & 0x3ff]) {
213 write_bits(outbuf
, 0x00, 0x01, &currbit
);
214 write_bits(outbuf
, offset
, 0x0a, &currbit
);
215 write_bits(outbuf
, wordlen
- 1, 0x04, &currbit
);
216 for (i
= 0; i
< wordlen
; i
++) {
217 window
[pos
] = *(inbuf
+ i
);
218 pos
= (pos
+ 1) & 0x3ff;
222 if (fill
< sizeof(window
))
225 write_bits(outbuf
, 0x01, 0x01, &currbit
);
226 write_bits(outbuf
, *inbuf
, 0x08, &currbit
);
227 window
[pos
] = *inbuf
;
228 pos
= (pos
+ 1) & 0x3ff;
230 if (fill
< sizeof(window
))
235 write_bits(outbuf
, 0x00, 0x01, &currbit
);
236 write_bits(outbuf
, 0x00, 0x0a, &currbit
);
238 *outlen
= (currbit
/ 8) + 1;
240 *((uint32_t*)(outbuf
+ 4)) = *outlen
;
245 /* Checksum is only used for the compressed firmware in 'firmware' */
246 uint32_t crc_check(uint8_t *buf
, uint32_t len
, uint32_t magic
)
253 my_len
= *((uint32_t*)(buf
+ 0x20));
254 my_magic
= *((uint32_t*)(buf
+ 0x24));
256 if (my_magic
!= magic
) {
257 printf("\nmagic: 0x%08x <-> 0x%08x\n", my_magic
, magic
);
264 crc
= ~rsb_crc(~0x00, buf
, len
);
265 file_crc
= *((uint32_t*)(buf
+ len
));
267 if (file_crc
!= crc
) {
268 printf("\nChecksums: 0x%08x <-> 0x%08x!\n", crc
, file_crc
);
275 uint8_t *extract_lz_file(uint8_t *inbuf
, uint32_t *outlen
, uint8_t check_crc
)
278 struct data_in_s data_in
;
279 struct data_out_s data_out
;
281 if (*((uint32_t*)inbuf
) != LZ_MAGIC
)
284 *outlen
= *((uint32_t*)(inbuf
+ 4));
285 printf(", length: %d", *outlen
);
287 if ((outbuf
= malloc(*outlen
)) == NULL
) {
292 bzero(outbuf
, *outlen
);
294 data_in
.start
= inbuf
+ 8;
295 data_in
.stop
= inbuf
+ *outlen
;
297 data_in
.bitpos
= 0x80;
299 data_out
.pos
= outbuf
;
300 data_out
.end
= outbuf
+ *outlen
;
302 lz_expand(&data_in
, &data_out
);
308 crclen
= *((uint32_t*)(outbuf
+ 0x20));
310 if ((ret
= crc_check(outbuf
, crclen
, 0x46335053)) != 0) {
311 printf("crc_check return: %d\n", ret
);