mirror of
https://github.com/FIX94/hbc.git
synced 2024-12-28 04:01:51 +01:00
124 lines
2.4 KiB
C
124 lines
2.4 KiB
C
|
#include <sys/types.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#include "common.h"
|
||
|
#include "lzma.h"
|
||
|
|
||
|
#include "LzmaDec.h"
|
||
|
|
||
|
static void *lz_malloc(void *p, size_t size) {
|
||
|
(void) p;
|
||
|
return malloc(size);
|
||
|
}
|
||
|
|
||
|
static void lz_free(void *p, void *address) {
|
||
|
(void) p;
|
||
|
free(address);
|
||
|
}
|
||
|
|
||
|
static ISzAlloc lz_alloc = { lz_malloc, lz_free };
|
||
|
|
||
|
static lzma_t *lzma_alloc(const u32 len) {
|
||
|
lzma_t *lzma;
|
||
|
|
||
|
lzma = (lzma_t *) calloc(1, sizeof(lzma_t));
|
||
|
|
||
|
if (!lzma)
|
||
|
die("Failed to alloc 0x%x bytes", (u32) sizeof(lzma_t));
|
||
|
|
||
|
lzma->data = calloc(1, len);
|
||
|
if (!lzma->data)
|
||
|
die("Failed to alloc 0x%x bytes", len);
|
||
|
|
||
|
return lzma;
|
||
|
}
|
||
|
|
||
|
void lzma_free(lzma_t *lzma) {
|
||
|
free(lzma->data);
|
||
|
free(lzma);
|
||
|
}
|
||
|
|
||
|
lzma_t *lzma_compress(const u8 *src, const u32 len) {
|
||
|
lzma_t *lzma;
|
||
|
CLzmaEncProps props;
|
||
|
size_t len_out;
|
||
|
size_t len_props = LZMA_PROPS_SIZE;
|
||
|
SRes res;
|
||
|
|
||
|
printf("Compressing...");
|
||
|
fflush(stdout);
|
||
|
|
||
|
lzma = lzma_alloc(2*len);
|
||
|
|
||
|
LzmaEncProps_Init(&props);
|
||
|
props.level = 7;
|
||
|
LzmaEncProps_Normalize(&props);
|
||
|
|
||
|
len_out = 2*len;
|
||
|
res = LzmaEncode(lzma->data, &len_out, src, len, &props, lzma->props,
|
||
|
&len_props, 1, NULL, &lz_alloc, &lz_alloc);
|
||
|
|
||
|
if (res != SZ_OK)
|
||
|
die(" failed (%d)", res);
|
||
|
|
||
|
if (len_props != LZMA_PROPS_SIZE)
|
||
|
die(" failed: encoder propsize %u != %u", (u32) len_props,
|
||
|
LZMA_PROPS_SIZE);
|
||
|
|
||
|
printf(" %u -> %u = %3.2f%%\n", len, (u32) len_out,
|
||
|
100.0 * (float) len_out / (float) len);
|
||
|
|
||
|
lzma->len_in = len;
|
||
|
lzma->len_out = len_out;
|
||
|
|
||
|
return lzma;
|
||
|
}
|
||
|
|
||
|
void lzma_decode(const lzma_t *lzma, u8 *dst) {
|
||
|
SizeT len_in;
|
||
|
SizeT len_out;
|
||
|
ELzmaStatus status;
|
||
|
SRes res;
|
||
|
|
||
|
len_in = lzma->len_out;
|
||
|
len_out = lzma->len_in;
|
||
|
|
||
|
res = LzmaDecode(dst, &len_out, lzma->data, &len_in, lzma->props,
|
||
|
LZMA_PROPS_SIZE, LZMA_FINISH_END, &status, &lz_alloc);
|
||
|
|
||
|
if (res != SZ_OK)
|
||
|
die("Error decoding %d (%u)\n", res, status);
|
||
|
|
||
|
*dst = len_out;
|
||
|
}
|
||
|
|
||
|
void lzma_write(const char *filename, const lzma_t *lzma) {
|
||
|
int fd;
|
||
|
int i;
|
||
|
|
||
|
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0755);
|
||
|
if (fd < 0)
|
||
|
perrordie("Could not open file");
|
||
|
|
||
|
if (write(fd, lzma->props, LZMA_PROPS_SIZE) != LZMA_PROPS_SIZE)
|
||
|
perrordie("Could not write to file");
|
||
|
|
||
|
u64 size = lzma->len_in;
|
||
|
for (i = 0; i < 8; ++i) {
|
||
|
u8 j = size & 0xff;
|
||
|
size >>= 8;
|
||
|
if (write(fd, &j, 1) != 1)
|
||
|
perrordie("Could not write to file");
|
||
|
}
|
||
|
|
||
|
if (write(fd, lzma->data, lzma->len_out) != lzma->len_out)
|
||
|
perrordie("Could not write to file");
|
||
|
|
||
|
close(fd);
|
||
|
}
|
||
|
|