blues/bb/unpack.c

50 lines
1.1 KiB
C
Raw Permalink Normal View History

2018-07-08 16:08:53 +02:00
#include "unpack.h"
#include "util.h"
struct unpack_t {
uint8_t dict_buf[0x200 * 2];
};
static struct unpack_t g_unpack;
2019-06-01 16:25:06 +02:00
int unpack(FILE *in, uint8_t *dst) {
2021-12-19 01:09:02 +01:00
uint8_t buf[6];
fread(buf, 1, 6, in);
const int uncompressed_size = (READ_LE_UINT16(buf) << 16) + READ_LE_UINT16(buf + 2);
const int dict_len = READ_LE_UINT16(buf + 4);
2019-06-01 16:25:06 +02:00
print_debug(DBG_UNPACK, "SQV uncompressed size %d dict_len %d", uncompressed_size, dict_len);
fread(g_unpack.dict_buf, 1, dict_len, in);
2018-07-08 16:08:53 +02:00
2019-06-01 16:25:06 +02:00
const uint8_t *start = dst;
2021-12-19 01:09:02 +01:00
int bits_count = 1;
2018-07-08 16:08:53 +02:00
uint16_t bits = 0;
uint16_t val = 0;
2019-06-01 16:25:06 +02:00
while ((dst - start) < uncompressed_size) {
2021-12-19 01:09:02 +01:00
--bits_count;
if (bits_count == 0) {
if (fread(buf, 1, 2, in) == 0) {
break;
2018-07-08 16:08:53 +02:00
}
2021-12-19 01:09:02 +01:00
bits = READ_BE_UINT16(buf);
bits_count = 16;
2018-07-08 16:08:53 +02:00
}
2021-12-19 01:09:02 +01:00
const bool carry = (bits & 0x8000) != 0;
2018-07-08 16:08:53 +02:00
bits <<= 1;
if (carry) {
val += 2;
}
2021-12-19 01:09:02 +01:00
assert((val & 1) == 0);
assert(val < dict_len);
2018-07-08 16:08:53 +02:00
val = READ_LE_UINT16(g_unpack.dict_buf + val);
if ((val & 0x8000) == 0) {
continue;
}
2021-12-19 01:09:02 +01:00
assert((val & 0x7F00) == 0);
2018-07-08 16:08:53 +02:00
*dst++ = val & 255;
val = 0;
}
2019-06-01 16:25:06 +02:00
assert((dst - start) == uncompressed_size);
return uncompressed_size;
2018-07-08 16:08:53 +02:00
}