Add block processing function to compressors

Signed-off-by: David Oberhollenzer <goliath@infraroot.at>
This commit is contained in:
David Oberhollenzer 2019-04-17 19:21:57 +02:00
parent 765c836c3d
commit 26b3683f7a
4 changed files with 119 additions and 0 deletions

View File

@ -16,6 +16,10 @@ typedef struct compressor_stream_t {
void (*flush)(struct compressor_stream_t *stream);
ssize_t (*do_block)(struct compressor_stream_t *stream,
const uint8_t *in, uint8_t *out,
size_t insize, size_t outsize);
void (*destroy)(struct compressor_stream_t *stream);
} compressor_stream_t;

View File

@ -92,6 +92,62 @@ static void lzma_flush(compressor_stream_t *base)
lzma->action = LZMA_FINISH;
}
static ssize_t lzma_comp_block(compressor_stream_t *base,
const uint8_t *in, uint8_t *out,
size_t insize, size_t outsize)
{
lzma_filter filters[5];
lzma_options_lzma opt;
size_t written = 0;
lzma_ret ret;
(void)base;
if (lzma_lzma_preset(&opt, LZMA_PRESET_DEFAULT)) {
fputs("error initializing LZMA options\n", stderr);
return -1;
}
filters[0].id = LZMA_FILTER_LZMA2;
filters[0].options = &opt;
filters[1].id = LZMA_VLI_UNKNOWN;
filters[1].options = NULL;
ret = lzma_stream_buffer_encode(filters, LZMA_CHECK_CRC32, NULL,
in, insize, out, &written, outsize);
if (ret == LZMA_OK)
return written;
if (ret != LZMA_BUF_ERROR) {
fputs("lzma block compress failed\n", stderr);
return -1;
}
return 0;
}
static ssize_t lzma_uncomp_block(compressor_stream_t *base,
const uint8_t *in, uint8_t *out,
size_t insize, size_t outsize)
{
uint64_t memlimit = 32 * 1024 * 1024;
size_t dest_pos = 0;
size_t src_pos = 0;
lzma_ret ret;
(void)base;
ret = lzma_stream_buffer_decode(&memlimit, 0, NULL,
in, &src_pos, insize,
out, &dest_pos, outsize);
if (ret == LZMA_OK && insize == src_pos)
return (ssize_t)dest_pos;
fputs("lzma block extract failed\n", stderr);
return -1;
}
static void lzma_destroy(compressor_stream_t *base)
{
lzma_stream_t *lzma = (lzma_stream_t *)base;
@ -134,8 +190,12 @@ static compressor_stream_t *create_stream(bool compress)
ret = lzma_stream_encoder(&lzma->strm, filters,
LZMA_CHECK_CRC32);
base->do_block = lzma_comp_block;
} else {
ret = lzma_stream_decoder(&lzma->strm, UINT64_MAX, 0);
base->do_block = lzma_uncomp_block;
}
if (ret != LZMA_OK)

View File

@ -52,6 +52,19 @@ static ssize_t dummy_read(compressor_stream_t *base,
return size;
}
static ssize_t dummy_do_block(compressor_stream_t *base,
const uint8_t *in, uint8_t *out,
size_t insize, size_t outsize)
{
(void)base;
if (outsize < insize)
return 0;
memcpy(out, in, insize);
return insize;
}
static void dummy_flush(compressor_stream_t *base)
{
(void)base;
@ -77,6 +90,7 @@ static compressor_stream_t *create_dummy_stream(compressor_t *cmp)
base->write = dummy_write;
base->read = dummy_read;
base->flush = dummy_flush;
base->do_block = dummy_do_block;
base->destroy = dummy_destroy;
return base;
}

View File

@ -112,6 +112,46 @@ static void zlib_destroy(compressor_stream_t *base)
free(zlib);
}
static ssize_t zlib_do_block(compressor_stream_t *base,
const uint8_t *in, uint8_t *out,
size_t insize, size_t outsize)
{
zlib_stream_t *zlib = (zlib_stream_t *)base;
int ret;
if (zlib->compress) {
ret = deflateReset(&zlib->strm);
} else {
ret = inflateReset(&zlib->strm);
}
if (ret != Z_OK) {
fputs("resetting zlib stream failed\n", stderr);
return -1;
}
zlib->strm.next_in = (void *)in;
zlib->strm.avail_in = insize;
zlib->strm.next_out = out;
zlib->strm.avail_out = outsize;
if (zlib->compress) {
ret = deflate(&zlib->strm, Z_FINISH);
} else {
ret = inflate(&zlib->strm, Z_FINISH);
}
if (ret == Z_STREAM_END)
return (ssize_t)zlib->strm.total_out;
if (ret != Z_OK) {
fputs("zlib block processing failed\n", stderr);
return -1;
}
return 0;
}
static compressor_stream_t *create_stream(bool compress)
{
zlib_stream_t *zlib = calloc(1, sizeof(*zlib));
@ -130,6 +170,7 @@ static compressor_stream_t *create_stream(bool compress)
base->write = zlib_write;
base->read = zlib_read;
base->flush = zlib_flush;
base->do_block = zlib_do_block;
base->destroy = zlib_destroy;
if (compress) {