diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-05-06 11:00:49 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-05-06 11:00:49 +0200 |
commit | cbcf86dde27767682483985e42f7ca49e1d3a208 (patch) | |
tree | 6abb8eabcda6e6aa64184aa24fb8c501f7c841b9 /lib/comp | |
parent | a5f604469d5cde8cb654e209f1ec30bf8e44b51e (diff) |
Add LZO compressor implementation
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/comp')
-rw-r--r-- | lib/comp/compressor.c | 3 | ||||
-rw-r--r-- | lib/comp/internal.h | 2 | ||||
-rw-r--r-- | lib/comp/lzo.c | 71 |
3 files changed, 76 insertions, 0 deletions
diff --git a/lib/comp/compressor.c b/lib/comp/compressor.c index 1ede111..42ebd8b 100644 --- a/lib/comp/compressor.c +++ b/lib/comp/compressor.c @@ -12,6 +12,9 @@ static compressor_fun_t compressors[SQFS_COMP_MAX + 1] = { #ifdef WITH_XZ [SQFS_COMP_XZ] = create_xz_compressor, #endif +#ifdef WITH_LZO + [SQFS_COMP_LZO] = create_lzo_compressor, +#endif }; bool compressor_exists(E_SQFS_COMPRESSOR id) diff --git a/lib/comp/internal.h b/lib/comp/internal.h index d1cf1f2..3b24af0 100644 --- a/lib/comp/internal.h +++ b/lib/comp/internal.h @@ -8,4 +8,6 @@ compressor_t *create_xz_compressor(bool compress, size_t block_size); compressor_t *create_gzip_compressor(bool compress, size_t block_size); +compressor_t *create_lzo_compressor(bool compress, size_t block_size); + #endif /* INTERNAL_H */ diff --git a/lib/comp/lzo.c b/lib/comp/lzo.c new file mode 100644 index 0000000..30b14cb --- /dev/null +++ b/lib/comp/lzo.c @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include <lzo/lzo1x.h> + +#include "internal.h" + +typedef struct { + compressor_t base; + + uint8_t buffer[LZO1X_999_MEM_COMPRESS]; +} lzo_compressor_t; + +static ssize_t lzo_comp_block(compressor_t *base, const uint8_t *in, + size_t size, uint8_t *out, size_t outsize) +{ + lzo_compressor_t *lzo = (lzo_compressor_t *)base; + lzo_uint len = outsize; + + if (lzo1x_999_compress(in, size, out, &len, lzo->buffer) != LZO_E_OK) { + fputs("lzo1x_999 failed. According to its " + "manual, this shouldn't happen!\n", stderr); + return -1; + } + + if (len < size) + return len; + + return 0; +} + +static ssize_t lzo_uncomp_block(compressor_t *base, const uint8_t *in, + size_t size, uint8_t *out, size_t outsize) +{ + lzo_compressor_t *lzo = (lzo_compressor_t *)base; + lzo_uint len = outsize; + int ret; + + ret = lzo1x_decompress_safe(in, size, out, &len, lzo->buffer); + + if (ret != LZO_E_OK) { + fputs("lzo decompress: input data is corrupted\n", stderr); + return -1; + } + + return len; +} + +static void lzo_destroy(compressor_t *base) +{ + free(base); +} + +compressor_t *create_lzo_compressor(bool compress, size_t block_size) +{ + lzo_compressor_t *lzo = calloc(1, sizeof(*lzo)); + compressor_t *base = (compressor_t *)lzo; + (void)block_size; + + if (lzo == NULL) { + perror("creating lzo compressor"); + return NULL; + } + + base->destroy = lzo_destroy; + base->do_block = compress ? lzo_comp_block : lzo_uncomp_block; + return base; +} |