diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2023-01-31 11:21:30 +0100 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2023-01-31 13:51:49 +0100 |
commit | cdccc69c62579b0c13b35fad0728079652b8f3c9 (patch) | |
tree | 9fa54c710f73c5e08a9c8466e7a712eb63ee07ac /lib/sqfs/comp | |
parent | 2182129c8f359c4fa1390eaba7a65b595ccd4182 (diff) |
Move library source into src sub-directory
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/sqfs/comp')
-rw-r--r-- | lib/sqfs/comp/compressor.c | 218 | ||||
-rw-r--r-- | lib/sqfs/comp/gzip.c | 307 | ||||
-rw-r--r-- | lib/sqfs/comp/internal.h | 46 | ||||
-rw-r--r-- | lib/sqfs/comp/lz4.c | 172 | ||||
-rw-r--r-- | lib/sqfs/comp/lzma.c | 281 | ||||
-rw-r--r-- | lib/sqfs/comp/xz.c | 324 | ||||
-rw-r--r-- | lib/sqfs/comp/zstd.c | 172 |
7 files changed, 0 insertions, 1520 deletions
diff --git a/lib/sqfs/comp/compressor.c b/lib/sqfs/comp/compressor.c deleted file mode 100644 index 4c4d73c..0000000 --- a/lib/sqfs/comp/compressor.c +++ /dev/null @@ -1,218 +0,0 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ -/* - * compressor.c - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#define SQFS_BUILDING_DLL -#include "config.h" - -#include <string.h> -#include <stdlib.h> - -#include "internal.h" - -typedef int (*compressor_fun_t)(const sqfs_compressor_config_t *cfg, - sqfs_compressor_t **out); - -static compressor_fun_t compressors[SQFS_COMP_MAX + 1] = { -#ifdef WITH_GZIP - [SQFS_COMP_GZIP] = gzip_compressor_create, -#endif -#ifdef WITH_XZ - [SQFS_COMP_XZ] = xz_compressor_create, - [SQFS_COMP_LZMA] = lzma_compressor_create, -#endif -#ifdef WITH_LZ4 - [SQFS_COMP_LZ4] = lz4_compressor_create, -#endif -#ifdef WITH_ZSTD - [SQFS_COMP_ZSTD] = zstd_compressor_create, -#endif -}; - -static const char *names[] = { - [SQFS_COMP_GZIP] = "gzip", - [SQFS_COMP_LZMA] = "lzma", - [SQFS_COMP_LZO] = "lzo", - [SQFS_COMP_XZ] = "xz", - [SQFS_COMP_LZ4] = "lz4", - [SQFS_COMP_ZSTD] = "zstd", -}; - -int sqfs_generic_write_options(sqfs_file_t *file, const void *data, size_t size) -{ - sqfs_u8 buffer[64]; - sqfs_u16 header; - int ret; - - /* XXX: options for all known compressors should fit into this */ - if (size >= (sizeof(buffer) - sizeof(header))) - return SQFS_ERROR_INTERNAL; - - header = htole16(0x8000 | size); - memcpy(buffer, &header, sizeof(header)); - memcpy(buffer + sizeof(header), data, size); - - ret = file->write_at(file, sizeof(sqfs_super_t), - buffer, sizeof(header) + size); - if (ret) - return ret; - - return sizeof(header) + size; -} - -int sqfs_generic_read_options(sqfs_file_t *file, void *data, size_t size) -{ - sqfs_u8 buffer[64]; - sqfs_u16 header; - int ret; - - /* XXX: options for all known compressors should fit into this */ - if (size >= (sizeof(buffer) - sizeof(header))) - return SQFS_ERROR_INTERNAL; - - ret = file->read_at(file, sizeof(sqfs_super_t), - buffer, sizeof(header) + size); - if (ret) - return ret; - - memcpy(&header, buffer, sizeof(header)); - - if (le16toh(header) != (0x8000 | size)) - return SQFS_ERROR_CORRUPTED; - - memcpy(data, buffer + 2, size); - return 0; -} - -int sqfs_compressor_create(const sqfs_compressor_config_t *cfg, - sqfs_compressor_t **out) -{ - sqfs_u8 padd0[sizeof(cfg->opt)]; - int ret; - - *out = NULL; - - /* check compressor ID */ - if (cfg == NULL) - return SQFS_ERROR_ARG_INVALID; - - if (cfg->id < SQFS_COMP_MIN || cfg->id > SQFS_COMP_MAX) - return SQFS_ERROR_UNSUPPORTED; - - if (compressors[cfg->id] == NULL) - return SQFS_ERROR_UNSUPPORTED; - - /* make sure the padding bytes are cleared, so we could theoretically - turn them into option fields in the future and remain compatible */ - memset(padd0, 0, sizeof(padd0)); - - switch (cfg->id) { - case SQFS_COMP_XZ: - ret = memcmp(cfg->opt.xz.padd0, padd0, - sizeof(cfg->opt.xz.padd0)); - break; - case SQFS_COMP_LZMA: - ret = memcmp(cfg->opt.lzma.padd0, padd0, - sizeof(cfg->opt.lzma.padd0)); - break; - case SQFS_COMP_LZO: - ret = memcmp(cfg->opt.lzo.padd0, padd0, - sizeof(cfg->opt.lzo.padd0)); - break; - case SQFS_COMP_GZIP: - ret = memcmp(cfg->opt.gzip.padd0, padd0, - sizeof(cfg->opt.gzip.padd0)); - break; - default: - ret = memcmp(cfg->opt.padd0, padd0, sizeof(cfg->opt.padd0)); - break; - } - - if (ret != 0) - return SQFS_ERROR_ARG_INVALID; - - return compressors[cfg->id](cfg, out); -} - -const char *sqfs_compressor_name_from_id(SQFS_COMPRESSOR id) -{ - if (id < 0 || (size_t)id >= sizeof(names) / sizeof(names[0])) - return NULL; - - return names[id]; -} - -int sqfs_compressor_id_from_name(const char *name) -{ - size_t i; - - for (i = 0; i < sizeof(names) / sizeof(names[0]); ++i) { - if (names[i] != NULL && strcmp(names[i], name) == 0) - return i; - } - - return SQFS_ERROR_UNSUPPORTED; -} - -int sqfs_compressor_config_init(sqfs_compressor_config_t *cfg, - SQFS_COMPRESSOR id, - size_t block_size, sqfs_u16 flags) -{ - sqfs_u32 flag_mask = SQFS_COMP_FLAG_GENERIC_ALL; - - memset(cfg, 0, sizeof(*cfg)); - - switch (id) { - case SQFS_COMP_GZIP: - flag_mask |= SQFS_COMP_FLAG_GZIP_ALL; - cfg->level = SQFS_GZIP_DEFAULT_LEVEL; - cfg->opt.gzip.window_size = SQFS_GZIP_DEFAULT_WINDOW; - break; - case SQFS_COMP_LZO: - cfg->opt.lzo.algorithm = SQFS_LZO_DEFAULT_ALG; - cfg->level = SQFS_LZO_DEFAULT_LEVEL; - break; - case SQFS_COMP_ZSTD: - cfg->level = SQFS_ZSTD_DEFAULT_LEVEL; - break; - case SQFS_COMP_XZ: - flag_mask |= SQFS_COMP_FLAG_XZ_ALL; - cfg->level = SQFS_XZ_DEFAULT_LEVEL; - cfg->opt.xz.dict_size = block_size; - cfg->opt.xz.lc = SQFS_XZ_DEFAULT_LC; - cfg->opt.xz.lp = SQFS_XZ_DEFAULT_LP; - cfg->opt.xz.pb = SQFS_XZ_DEFAULT_PB; - - if (block_size < SQFS_XZ_MIN_DICT_SIZE) - cfg->opt.xz.dict_size = SQFS_XZ_MIN_DICT_SIZE; - break; - case SQFS_COMP_LZMA: - flag_mask |= SQFS_COMP_FLAG_LZMA_ALL; - cfg->level = SQFS_LZMA_DEFAULT_LEVEL; - cfg->opt.lzma.dict_size = block_size; - cfg->opt.lzma.lc = SQFS_LZMA_DEFAULT_LC; - cfg->opt.lzma.lp = SQFS_LZMA_DEFAULT_LP; - cfg->opt.lzma.pb = SQFS_LZMA_DEFAULT_PB; - - if (block_size < SQFS_LZMA_MIN_DICT_SIZE) - cfg->opt.lzma.dict_size = SQFS_LZMA_MIN_DICT_SIZE; - break; - case SQFS_COMP_LZ4: - flag_mask |= SQFS_COMP_FLAG_LZ4_ALL; - break; - default: - return SQFS_ERROR_UNSUPPORTED; - } - - if (flags & ~flag_mask) { - memset(cfg, 0, sizeof(*cfg)); - return SQFS_ERROR_UNSUPPORTED; - } - - cfg->id = id; - cfg->flags = flags; - cfg->block_size = block_size; - return 0; -} diff --git a/lib/sqfs/comp/gzip.c b/lib/sqfs/comp/gzip.c deleted file mode 100644 index beacfb8..0000000 --- a/lib/sqfs/comp/gzip.c +++ /dev/null @@ -1,307 +0,0 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ -/* - * gzip.c - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#define SQFS_BUILDING_DLL -#include "config.h" - -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <zlib.h> - -#include "internal.h" - -typedef struct { - sqfs_u32 level; - sqfs_u16 window; - sqfs_u16 strategies; -} gzip_options_t; - -typedef struct { - sqfs_compressor_t base; - - z_stream strm; - bool compress; - - size_t block_size; - gzip_options_t opt; -} gzip_compressor_t; - -static void gzip_destroy(sqfs_object_t *base) -{ - gzip_compressor_t *gzip = (gzip_compressor_t *)base; - - if (gzip->compress) { - deflateEnd(&gzip->strm); - } else { - inflateEnd(&gzip->strm); - } - - free(gzip); -} - -static void gzip_get_configuration(const sqfs_compressor_t *base, - sqfs_compressor_config_t *cfg) -{ - const gzip_compressor_t *gzip = (const gzip_compressor_t *)base; - - memset(cfg, 0, sizeof(*cfg)); - cfg->id = SQFS_COMP_GZIP; - cfg->flags = gzip->opt.strategies; - cfg->block_size = gzip->block_size; - cfg->level = gzip->opt.level; - cfg->opt.gzip.window_size = gzip->opt.window; - - if (!gzip->compress) - cfg->flags |= SQFS_COMP_FLAG_UNCOMPRESS; -} - -static int gzip_write_options(sqfs_compressor_t *base, sqfs_file_t *file) -{ - gzip_compressor_t *gzip = (gzip_compressor_t *)base; - gzip_options_t opt; - - if (gzip->opt.level == SQFS_GZIP_DEFAULT_LEVEL && - gzip->opt.window == SQFS_GZIP_DEFAULT_WINDOW && - gzip->opt.strategies == 0) { - return 0; - } - - opt.level = htole32(gzip->opt.level); - opt.window = htole16(gzip->opt.window); - opt.strategies = htole16(gzip->opt.strategies); - - return sqfs_generic_write_options(file, &opt, sizeof(opt)); -} - -static int gzip_read_options(sqfs_compressor_t *base, sqfs_file_t *file) -{ - gzip_compressor_t *gzip = (gzip_compressor_t *)base; - gzip_options_t opt; - int ret; - - ret = sqfs_generic_read_options(file, &opt, sizeof(opt)); - if (ret) - return ret; - - gzip->opt.level = le32toh(opt.level); - gzip->opt.window = le16toh(opt.window); - gzip->opt.strategies = le16toh(opt.strategies); - - if (gzip->opt.level < 1 || gzip->opt.level > 9) - return SQFS_ERROR_UNSUPPORTED; - - if (gzip->opt.window < 8 || gzip->opt.window > 15) - return SQFS_ERROR_UNSUPPORTED; - - if (gzip->opt.strategies & ~SQFS_COMP_FLAG_GZIP_ALL) - return SQFS_ERROR_UNSUPPORTED; - - return 0; -} - -static int flag_to_zlib_strategy(int flag) -{ - switch (flag) { - case SQFS_COMP_FLAG_GZIP_DEFAULT: - return Z_DEFAULT_STRATEGY; - case SQFS_COMP_FLAG_GZIP_FILTERED: - return Z_FILTERED; - case SQFS_COMP_FLAG_GZIP_HUFFMAN: - return Z_HUFFMAN_ONLY; - case SQFS_COMP_FLAG_GZIP_RLE: - return Z_RLE; - case SQFS_COMP_FLAG_GZIP_FIXED: - return Z_FIXED; - default: - break; - } - - return 0; -} - -static int find_strategy(gzip_compressor_t *gzip, const sqfs_u8 *in, - sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) -{ - int ret, strategy, selected = Z_DEFAULT_STRATEGY; - size_t i, length, minlength = 0; - - for (i = 0x01; i & SQFS_COMP_FLAG_GZIP_ALL; i <<= 1) { - if ((gzip->opt.strategies & i) == 0) - continue; - - ret = deflateReset(&gzip->strm); - if (ret != Z_OK) - return SQFS_ERROR_COMPRESSOR; - - strategy = flag_to_zlib_strategy(i); - - gzip->strm.next_in = (z_const Bytef *)in; - gzip->strm.avail_in = size; - gzip->strm.next_out = out; - gzip->strm.avail_out = outsize; - - ret = deflateParams(&gzip->strm, gzip->opt.level, strategy); - if (ret != Z_OK) - return SQFS_ERROR_COMPRESSOR; - - ret = deflate(&gzip->strm, Z_FINISH); - - if (ret == Z_STREAM_END) { - length = gzip->strm.total_out; - - if (minlength == 0 || length < minlength) { - minlength = length; - selected = strategy; - } - } else if (ret != Z_OK && ret != Z_BUF_ERROR) { - return SQFS_ERROR_COMPRESSOR; - } - } - - return selected; -} - -static sqfs_s32 gzip_do_block(sqfs_compressor_t *base, const sqfs_u8 *in, - sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) -{ - gzip_compressor_t *gzip = (gzip_compressor_t *)base; - int ret, strategy = 0; - size_t written; - - if (size >= 0x7FFFFFFF) - return SQFS_ERROR_ARG_INVALID; - - if (gzip->compress && gzip->opt.strategies != 0) { - strategy = find_strategy(gzip, in, size, out, outsize); - if (strategy < 0) - return strategy; - } - - if (gzip->compress) { - ret = deflateReset(&gzip->strm); - } else { - ret = inflateReset(&gzip->strm); - } - - if (ret != Z_OK) - return SQFS_ERROR_COMPRESSOR; - - gzip->strm.next_in = (const void *)in; - gzip->strm.avail_in = size; - gzip->strm.next_out = out; - gzip->strm.avail_out = outsize; - - if (gzip->compress && gzip->opt.strategies != 0) { - ret = deflateParams(&gzip->strm, gzip->opt.level, strategy); - if (ret != Z_OK) - return SQFS_ERROR_COMPRESSOR; - } - - if (gzip->compress) { - ret = deflate(&gzip->strm, Z_FINISH); - } else { - ret = inflate(&gzip->strm, Z_FINISH); - } - - if (ret == Z_STREAM_END) { - written = gzip->strm.total_out; - - if (gzip->compress && written >= size) - return 0; - - return written; - } - - if (ret != Z_OK && ret != Z_BUF_ERROR) - return SQFS_ERROR_COMPRESSOR; - - return 0; -} - -static sqfs_object_t *gzip_create_copy(const sqfs_object_t *cmp) -{ - gzip_compressor_t *gzip = malloc(sizeof(*gzip)); - int ret; - - if (gzip == NULL) - return NULL; - - memcpy(gzip, cmp, sizeof(*gzip)); - memset(&gzip->strm, 0, sizeof(gzip->strm)); - - if (gzip->compress) { - ret = deflateInit2(&gzip->strm, gzip->opt.level, Z_DEFLATED, - gzip->opt.window, 8, Z_DEFAULT_STRATEGY); - } else { - ret = inflateInit(&gzip->strm); - } - - if (ret != Z_OK) { - free(gzip); - return NULL; - } - - return (sqfs_object_t *)gzip; -} - -int gzip_compressor_create(const sqfs_compressor_config_t *cfg, - sqfs_compressor_t **out) -{ - gzip_compressor_t *gzip; - sqfs_compressor_t *base; - int ret; - - if (cfg->flags & ~(SQFS_COMP_FLAG_GZIP_ALL | - SQFS_COMP_FLAG_GENERIC_ALL)) { - return SQFS_ERROR_UNSUPPORTED; - } - - if (cfg->level < SQFS_GZIP_MIN_LEVEL || - cfg->level > SQFS_GZIP_MAX_LEVEL) { - return SQFS_ERROR_UNSUPPORTED; - } - - if (cfg->opt.gzip.window_size < SQFS_GZIP_MIN_WINDOW || - cfg->opt.gzip.window_size > SQFS_GZIP_MAX_WINDOW) { - return SQFS_ERROR_UNSUPPORTED; - } - - gzip = calloc(1, sizeof(*gzip)); - base = (sqfs_compressor_t *)gzip; - - if (gzip == NULL) - return SQFS_ERROR_ALLOC; - - sqfs_object_init(gzip, gzip_destroy, gzip_create_copy); - - gzip->opt.level = cfg->level; - gzip->opt.window = cfg->opt.gzip.window_size; - gzip->opt.strategies = cfg->flags & SQFS_COMP_FLAG_GZIP_ALL; - gzip->compress = (cfg->flags & SQFS_COMP_FLAG_UNCOMPRESS) == 0; - gzip->block_size = cfg->block_size; - base->get_configuration = gzip_get_configuration; - base->do_block = gzip_do_block; - base->write_options = gzip_write_options; - base->read_options = gzip_read_options; - - if (gzip->compress) { - ret = deflateInit2(&gzip->strm, cfg->level, - Z_DEFLATED, cfg->opt.gzip.window_size, 8, - Z_DEFAULT_STRATEGY); - } else { - ret = inflateInit(&gzip->strm); - } - - if (ret != Z_OK) { - free(gzip); - return SQFS_ERROR_COMPRESSOR; - } - - *out = base; - return 0; -} diff --git a/lib/sqfs/comp/internal.h b/lib/sqfs/comp/internal.h deleted file mode 100644 index e4c3dd8..0000000 --- a/lib/sqfs/comp/internal.h +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ -/* - * internal.h - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#ifndef INTERNAL_H -#define INTERNAL_H - -#include "config.h" - -#include "sqfs/predef.h" -#include "sqfs/compressor.h" -#include "sqfs/error.h" -#include "sqfs/block.h" -#include "sqfs/io.h" -#include "util/util.h" - -SQFS_INTERNAL -int sqfs_generic_write_options(sqfs_file_t *file, const void *data, - size_t size); - -SQFS_INTERNAL -int sqfs_generic_read_options(sqfs_file_t *file, void *data, size_t size); - -SQFS_INTERNAL -int xz_compressor_create(const sqfs_compressor_config_t *cfg, - sqfs_compressor_t **out); - -SQFS_INTERNAL -int gzip_compressor_create(const sqfs_compressor_config_t *cfg, - sqfs_compressor_t **out); - -SQFS_INTERNAL -int lz4_compressor_create(const sqfs_compressor_config_t *cfg, - sqfs_compressor_t **out); - -SQFS_INTERNAL -int zstd_compressor_create(const sqfs_compressor_config_t *cfg, - sqfs_compressor_t **out); - -SQFS_INTERNAL -int lzma_compressor_create(const sqfs_compressor_config_t *cfg, - sqfs_compressor_t **out); - -#endif /* INTERNAL_H */ diff --git a/lib/sqfs/comp/lz4.c b/lib/sqfs/comp/lz4.c deleted file mode 100644 index 77f4a6e..0000000 --- a/lib/sqfs/comp/lz4.c +++ /dev/null @@ -1,172 +0,0 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ -/* - * lz4.c - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#define SQFS_BUILDING_DLL -#include "config.h" - -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> - -#include <lz4.h> -#include <lz4hc.h> - -#include "internal.h" - -typedef struct { - sqfs_compressor_t base; - size_t block_size; - bool high_compression; -} lz4_compressor_t; - -typedef struct { - sqfs_u32 version; - sqfs_u32 flags; -} lz4_options; - -#define LZ4LEGACY 1 - -/* old verions of liblz4 don't have this */ -#ifndef LZ4HC_CLEVEL_MAX -#define LZ4HC_CLEVEL_MAX 12 -#endif - -static int lz4_write_options(sqfs_compressor_t *base, sqfs_file_t *file) -{ - lz4_compressor_t *lz4 = (lz4_compressor_t *)base; - lz4_options opt = { - .version = htole32(LZ4LEGACY), - .flags = htole32(lz4->high_compression ? - SQFS_COMP_FLAG_LZ4_HC : 0), - }; - - return sqfs_generic_write_options(file, &opt, sizeof(opt)); -} - -static int lz4_read_options(sqfs_compressor_t *base, sqfs_file_t *file) -{ - lz4_options opt; - int ret; - (void)base; - - ret = sqfs_generic_read_options(file, &opt, sizeof(opt)); - if (ret) - return ret; - - opt.version = le32toh(opt.version); - opt.flags = le32toh(opt.flags); - - if (opt.version != LZ4LEGACY) - return SQFS_ERROR_UNSUPPORTED; - - return 0; -} - -static sqfs_s32 lz4_comp_block(sqfs_compressor_t *base, const sqfs_u8 *in, - sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) -{ - lz4_compressor_t *lz4 = (lz4_compressor_t *)base; - int ret; - - if (size >= 0x7FFFFFFF) - return SQFS_ERROR_ARG_INVALID; - - if (lz4->high_compression) { - ret = LZ4_compress_HC((const void *)in, (void *)out, - size, outsize, LZ4HC_CLEVEL_MAX); - } else { - ret = LZ4_compress_default((const void *)in, (void *)out, - size, outsize); - } - - if (ret < 0) - return SQFS_ERROR_COMPRESSOR; - - return ret; -} - -static sqfs_s32 lz4_uncomp_block(sqfs_compressor_t *base, const sqfs_u8 *in, - sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) -{ - int ret; - (void)base; - - if (outsize >= 0x7FFFFFFF) - return SQFS_ERROR_ARG_INVALID; - - ret = LZ4_decompress_safe((const void *)in, (void *)out, size, outsize); - - if (ret < 0) - return SQFS_ERROR_COMPRESSOR; - - return ret; -} - -static void lz4_get_configuration(const sqfs_compressor_t *base, - sqfs_compressor_config_t *cfg) -{ - const lz4_compressor_t *lz4 = (const lz4_compressor_t *)base; - - memset(cfg, 0, sizeof(*cfg)); - cfg->id = SQFS_COMP_LZ4; - cfg->block_size = lz4->block_size; - - if (lz4->high_compression) - cfg->flags |= SQFS_COMP_FLAG_LZ4_HC; - - if (base->do_block == lz4_uncomp_block) - cfg->flags |= SQFS_COMP_FLAG_UNCOMPRESS; -} - -static sqfs_object_t *lz4_create_copy(const sqfs_object_t *cmp) -{ - lz4_compressor_t *lz4 = malloc(sizeof(*lz4)); - - if (lz4 == NULL) - return NULL; - - memcpy(lz4, cmp, sizeof(*lz4)); - return (sqfs_object_t *)lz4; -} - -static void lz4_destroy(sqfs_object_t *base) -{ - free(base); -} - -int lz4_compressor_create(const sqfs_compressor_config_t *cfg, - sqfs_compressor_t **out) -{ - sqfs_compressor_t *base; - lz4_compressor_t *lz4; - - if (cfg->flags & ~(SQFS_COMP_FLAG_LZ4_ALL | - SQFS_COMP_FLAG_GENERIC_ALL)) { - return SQFS_ERROR_UNSUPPORTED; - } - - if (cfg->level != 0) - return SQFS_ERROR_UNSUPPORTED; - - lz4 = calloc(1, sizeof(*lz4)); - base = (sqfs_compressor_t *)lz4; - if (lz4 == NULL) - return SQFS_ERROR_ALLOC; - - sqfs_object_init(lz4, lz4_destroy, lz4_create_copy); - - lz4->high_compression = (cfg->flags & SQFS_COMP_FLAG_LZ4_HC) != 0; - lz4->block_size = cfg->block_size; - - base->get_configuration = lz4_get_configuration; - base->do_block = (cfg->flags & SQFS_COMP_FLAG_UNCOMPRESS) ? - lz4_uncomp_block : lz4_comp_block; - base->write_options = lz4_write_options; - base->read_options = lz4_read_options; - - *out = base; - return 0; -} diff --git a/lib/sqfs/comp/lzma.c b/lib/sqfs/comp/lzma.c deleted file mode 100644 index 5456603..0000000 --- a/lib/sqfs/comp/lzma.c +++ /dev/null @@ -1,281 +0,0 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ -/* - * lzma.c - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#define SQFS_BUILDING_DLL -#include "config.h" - -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> -#include <lzma.h> - -#include "internal.h" - -#define LZMA_SIZE_OFFSET (5) -#define LZMA_SIZE_BYTES (8) -#define LZMA_HEADER_SIZE (13) - -#define MEMLIMIT (64 * 1024 * 1024) - -typedef struct { - sqfs_compressor_t base; - size_t block_size; - size_t dict_size; - - sqfs_u32 flags; - sqfs_u8 level; - sqfs_u8 lc; - sqfs_u8 lp; - sqfs_u8 pb; -} lzma_compressor_t; - -static int lzma_write_options(sqfs_compressor_t *base, sqfs_file_t *file) -{ - (void)base; (void)file; - return 0; -} - -static int lzma_read_options(sqfs_compressor_t *base, sqfs_file_t *file) -{ - (void)base; - (void)file; - return SQFS_ERROR_UNSUPPORTED; -} - -static sqfs_s32 try_compress(lzma_compressor_t *lzma, sqfs_u32 preset, - const sqfs_u8 *in, size_t size, - sqfs_u8 *out, size_t outsize) -{ - lzma_stream strm = LZMA_STREAM_INIT; - lzma_options_lzma opt; - int ret; - - lzma_lzma_preset(&opt, preset); - opt.dict_size = lzma->block_size; - opt.lc = lzma->lc; - opt.lp = lzma->lp; - opt.pb = lzma->pb; - - if (lzma_alone_encoder(&strm, &opt) != LZMA_OK) { - lzma_end(&strm); - return SQFS_ERROR_COMPRESSOR; - } - - strm.next_out = out; - strm.avail_out = outsize; - strm.next_in = in; - strm.avail_in = size; - - ret = lzma_code(&strm, LZMA_FINISH); - lzma_end(&strm); - - if (ret != LZMA_STREAM_END) - return ret == LZMA_OK ? 0 : SQFS_ERROR_COMPRESSOR; - - if (strm.total_out > size) - return 0; - - out[LZMA_SIZE_OFFSET ] = size & 0xFF; - out[LZMA_SIZE_OFFSET + 1] = (size >> 8) & 0xFF; - out[LZMA_SIZE_OFFSET + 2] = (size >> 16) & 0xFF; - out[LZMA_SIZE_OFFSET + 3] = (size >> 24) & 0xFF; - out[LZMA_SIZE_OFFSET + 4] = 0; - out[LZMA_SIZE_OFFSET + 5] = 0; - out[LZMA_SIZE_OFFSET + 6] = 0; - out[LZMA_SIZE_OFFSET + 7] = 0; - return strm.total_out; -} - -static sqfs_s32 lzma_comp_block(sqfs_compressor_t *base, const sqfs_u8 *in, - sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) -{ - lzma_compressor_t *lzma = (lzma_compressor_t *)base; - sqfs_s32 ret, smallest; - sqfs_u32 preset; - - if (outsize < LZMA_HEADER_SIZE || size >= 0x7FFFFFFF) - return SQFS_ERROR_ARG_INVALID; - - preset = lzma->level; - ret = try_compress(lzma, preset, in, size, out, outsize); - if (ret < 0 || !(lzma->flags & SQFS_COMP_FLAG_LZMA_EXTREME)) - return ret; - - preset |= LZMA_PRESET_EXTREME; - smallest = ret; - - ret = try_compress(lzma, preset, in, size, out, outsize); - if (ret < 0 || (ret > 0 && (smallest == 0 || ret < smallest))) - return ret; - - preset &= ~LZMA_PRESET_EXTREME; - return smallest == 0 ? 0 : - try_compress(lzma, preset, in, size, out, outsize); -} - -static sqfs_s32 lzma_uncomp_block(sqfs_compressor_t *base, const sqfs_u8 *in, - sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) -{ - sqfs_u8 lzma_header[LZMA_HEADER_SIZE]; - lzma_stream strm = LZMA_STREAM_INIT; - size_t hdrsize; - int ret; - (void)base; - - if (size >= 0x7FFFFFFF) - return SQFS_ERROR_ARG_INVALID; - - if (size < sizeof(lzma_header)) - return SQFS_ERROR_CORRUPTED; - - hdrsize = (size_t)in[LZMA_SIZE_OFFSET] | - ((size_t)in[LZMA_SIZE_OFFSET + 1] << 8) | - ((size_t)in[LZMA_SIZE_OFFSET + 2] << 16) | - ((size_t)in[LZMA_SIZE_OFFSET + 3] << 24); - - if (hdrsize > outsize) - return 0; - - if (lzma_alone_decoder(&strm, MEMLIMIT) != LZMA_OK) { - lzma_end(&strm); - return SQFS_ERROR_COMPRESSOR; - } - - memcpy(lzma_header, in, sizeof(lzma_header)); - memset(lzma_header + LZMA_SIZE_OFFSET, 0xFF, LZMA_SIZE_BYTES); - - strm.next_out = out; - strm.avail_out = outsize; - strm.next_in = lzma_header; - strm.avail_in = sizeof(lzma_header); - - ret = lzma_code(&strm, LZMA_RUN); - - if (ret != LZMA_OK || strm.avail_in != 0) { - lzma_end(&strm); - return SQFS_ERROR_COMPRESSOR; - } - - strm.next_in = in + sizeof(lzma_header); - strm.avail_in = size - sizeof(lzma_header); - - ret = lzma_code(&strm, LZMA_FINISH); - lzma_end(&strm); - - if (ret != LZMA_STREAM_END && ret != LZMA_OK) - return SQFS_ERROR_COMPRESSOR; - - if (ret == LZMA_OK) { - if (strm.total_out < hdrsize || strm.avail_in != 0) - return 0; - } - - return hdrsize; -} - -static void lzma_get_configuration(const sqfs_compressor_t *base, - sqfs_compressor_config_t *cfg) -{ - const lzma_compressor_t *lzma = (const lzma_compressor_t *)base; - - memset(cfg, 0, sizeof(*cfg)); - cfg->id = SQFS_COMP_LZMA; - cfg->block_size = lzma->block_size; - cfg->flags = lzma->flags; - cfg->level = lzma->level; - cfg->opt.lzma.dict_size = lzma->dict_size; - cfg->opt.lzma.lc = lzma->lc; - cfg->opt.lzma.lp = lzma->lp; - cfg->opt.lzma.pb = lzma->pb; -} - -static sqfs_object_t *lzma_create_copy(const sqfs_object_t *cmp) -{ - lzma_compressor_t *copy = malloc(sizeof(*copy)); - - if (copy != NULL) - memcpy(copy, cmp, sizeof(*copy)); - - return (sqfs_object_t *)copy; -} - -static void lzma_destroy(sqfs_object_t *base) -{ - free(base); -} - -int lzma_compressor_create(const sqfs_compressor_config_t *cfg, - sqfs_compressor_t **out) -{ - sqfs_compressor_t *base; - lzma_compressor_t *lzma; - sqfs_u32 mask; - - mask = SQFS_COMP_FLAG_GENERIC_ALL | SQFS_COMP_FLAG_LZMA_ALL; - - if (cfg->flags & ~mask) - return SQFS_ERROR_UNSUPPORTED; - - /* XXX: values are unsigned and minimum is 0 */ - if (cfg->level > SQFS_LZMA_MAX_LEVEL) - return SQFS_ERROR_UNSUPPORTED; - - if (cfg->opt.lzma.lc > SQFS_LZMA_MAX_LC) - return SQFS_ERROR_UNSUPPORTED; - - if (cfg->opt.lzma.lp > SQFS_LZMA_MAX_LP) - return SQFS_ERROR_UNSUPPORTED; - - if (cfg->opt.lzma.pb > SQFS_LZMA_MAX_PB) - return SQFS_ERROR_UNSUPPORTED; - - if (cfg->opt.lzma.lc + cfg->opt.lzma.lp > 4) - return SQFS_ERROR_UNSUPPORTED; - - if (cfg->opt.lzma.dict_size == 0) - return SQFS_ERROR_UNSUPPORTED; - - if (cfg->opt.lzma.dict_size < SQFS_LZMA_MIN_DICT_SIZE) - return SQFS_ERROR_UNSUPPORTED; - - if (cfg->opt.lzma.dict_size > SQFS_LZMA_MAX_DICT_SIZE) - return SQFS_ERROR_UNSUPPORTED; - - mask = cfg->opt.lzma.dict_size; - mask &= mask - 1; - - if (mask != 0) { - if ((mask & (mask - 1)) != 0) - return SQFS_ERROR_UNSUPPORTED; - - if (cfg->opt.lzma.dict_size != (mask | mask >> 1)) - return SQFS_ERROR_UNSUPPORTED; - } - - lzma = calloc(1, sizeof(*lzma)); - base = (sqfs_compressor_t *)lzma; - if (lzma == NULL) - return SQFS_ERROR_ALLOC; - - sqfs_object_init(lzma, lzma_destroy, lzma_create_copy); - - lzma->block_size = cfg->block_size; - lzma->flags = cfg->flags; - lzma->level = cfg->level; - lzma->dict_size = cfg->opt.lzma.dict_size; - lzma->lc = cfg->opt.lzma.lc; - lzma->lp = cfg->opt.lzma.lp; - lzma->pb = cfg->opt.lzma.pb; - - base->get_configuration = lzma_get_configuration; - base->do_block = (cfg->flags & SQFS_COMP_FLAG_UNCOMPRESS) ? - lzma_uncomp_block : lzma_comp_block; - base->write_options = lzma_write_options; - base->read_options = lzma_read_options; - - *out = base; - return 0; -} diff --git a/lib/sqfs/comp/xz.c b/lib/sqfs/comp/xz.c deleted file mode 100644 index 13545ed..0000000 --- a/lib/sqfs/comp/xz.c +++ /dev/null @@ -1,324 +0,0 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ -/* - * xz.c - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#define SQFS_BUILDING_DLL -#include "config.h" - -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> -#include <lzma.h> - -#include "internal.h" - -typedef struct { - sqfs_compressor_t base; - size_t block_size; - size_t dict_size; - - sqfs_u8 level; - sqfs_u8 lc; - sqfs_u8 lp; - sqfs_u8 pb; - - int flags; -} xz_compressor_t; - -typedef struct { - sqfs_u32 dict_size; - sqfs_u32 flags; -} xz_options_t; - -static bool is_dict_size_valid(size_t size) -{ - size_t x = size & (size - 1); - - if (x == 0) - return true; - - return size == (x | (x >> 1)); -} - -static int xz_write_options(sqfs_compressor_t *base, sqfs_file_t *file) -{ - xz_compressor_t *xz = (xz_compressor_t *)base; - xz_options_t opt; - sqfs_u32 flags; - - if (xz->flags == 0 && xz->dict_size == xz->block_size) - return 0; - - flags = xz->flags & SQFS_COMP_FLAG_XZ_ALL; - flags &= ~SQFS_COMP_FLAG_XZ_EXTREME; - - opt.dict_size = htole32(xz->dict_size); - opt.flags = htole32(flags); - - return sqfs_generic_write_options(file, &opt, sizeof(opt)); -} - -static int xz_read_options(sqfs_compressor_t *base, sqfs_file_t *file) -{ - xz_compressor_t *xz = (xz_compressor_t *)base; - xz_options_t opt; - int ret; - - ret = sqfs_generic_read_options(file, &opt, sizeof(opt)); - if (ret) - return ret; - - opt.dict_size = le32toh(opt.dict_size); - opt.flags = le32toh(opt.flags); - - if (!is_dict_size_valid(opt.dict_size)) - return SQFS_ERROR_CORRUPTED; - - if (opt.flags & ~SQFS_COMP_FLAG_XZ_ALL) - return SQFS_ERROR_UNSUPPORTED; - - xz->flags = opt.flags; - xz->dict_size = opt.dict_size; - return 0; -} - -static sqfs_s32 compress(xz_compressor_t *xz, lzma_vli filter, - const sqfs_u8 *in, sqfs_u32 size, - sqfs_u8 *out, sqfs_u32 outsize, - sqfs_u32 presets) -{ - lzma_filter filters[5]; - lzma_options_lzma opt; - size_t written = 0; - lzma_ret ret; - int i = 0; - - if (lzma_lzma_preset(&opt, presets)) - return SQFS_ERROR_COMPRESSOR; - - opt.lc = xz->lc; - opt.lp = xz->lp; - opt.pb = xz->pb; - opt.dict_size = xz->dict_size; - - if (filter != LZMA_VLI_UNKNOWN) { - filters[i].id = filter; - filters[i].options = NULL; - ++i; - } - - filters[i].id = LZMA_FILTER_LZMA2; - filters[i].options = &opt; - ++i; - - filters[i].id = LZMA_VLI_UNKNOWN; - filters[i].options = NULL; - ++i; - - ret = lzma_stream_buffer_encode(filters, LZMA_CHECK_CRC32, NULL, - in, size, out, &written, outsize); - - if (ret == LZMA_OK) - return (written >= size) ? 0 : written; - - if (ret != LZMA_BUF_ERROR) - return SQFS_ERROR_COMPRESSOR; - - return 0; -} - -static lzma_vli flag_to_vli(int flag) -{ - switch (flag) { - case SQFS_COMP_FLAG_XZ_X86: - return LZMA_FILTER_X86; - case SQFS_COMP_FLAG_XZ_POWERPC: - return LZMA_FILTER_POWERPC; - case SQFS_COMP_FLAG_XZ_IA64: - return LZMA_FILTER_IA64; - case SQFS_COMP_FLAG_XZ_ARM: - return LZMA_FILTER_ARM; - case SQFS_COMP_FLAG_XZ_ARMTHUMB: - return LZMA_FILTER_ARMTHUMB; - case SQFS_COMP_FLAG_XZ_SPARC: - return LZMA_FILTER_SPARC; - default: - break; - } - - return LZMA_VLI_UNKNOWN; -} - -static sqfs_s32 xz_comp_block(sqfs_compressor_t *base, const sqfs_u8 *in, - sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) -{ - xz_compressor_t *xz = (xz_compressor_t *)base; - lzma_vli filter, selected = LZMA_VLI_UNKNOWN; - sqfs_s32 ret, smallest; - bool extreme; - size_t i; - - if (size >= 0x7FFFFFFF) - return SQFS_ERROR_ARG_INVALID; - - ret = compress(xz, LZMA_VLI_UNKNOWN, in, size, out, - outsize, xz->level); - if (ret < 0 || xz->flags == 0) - return ret; - - smallest = ret; - extreme = false; - - if (xz->flags & SQFS_COMP_FLAG_XZ_EXTREME) { - ret = compress(xz, LZMA_VLI_UNKNOWN, in, size, out, outsize, - xz->level | LZMA_PRESET_EXTREME); - - if (ret > 0 && (smallest == 0 || ret < smallest)) { - smallest = ret; - extreme = true; - } - } - - for (i = 1; i & SQFS_COMP_FLAG_XZ_ALL; i <<= 1) { - if ((i & SQFS_COMP_FLAG_XZ_EXTREME) || (xz->flags & i) == 0) - continue; - - filter = flag_to_vli(i); - - ret = compress(xz, filter, in, size, out, outsize, xz->level); - if (ret > 0 && (smallest == 0 || ret < smallest)) { - smallest = ret; - selected = filter; - extreme = false; - } - - if (xz->flags & SQFS_COMP_FLAG_XZ_EXTREME) { - ret = compress(xz, filter, in, size, out, outsize, - xz->level | LZMA_PRESET_EXTREME); - - if (ret > 0 && (smallest == 0 || ret < smallest)) { - smallest = ret; - selected = filter; - extreme = true; - } - } - } - - if (smallest == 0) - return 0; - - return compress(xz, selected, in, size, out, outsize, - xz->level | (extreme ? LZMA_PRESET_EXTREME : 0)); -} - -static sqfs_s32 xz_uncomp_block(sqfs_compressor_t *base, const sqfs_u8 *in, - sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) -{ - sqfs_u64 memlimit = 65 * 1024 * 1024; - size_t dest_pos = 0; - size_t src_pos = 0; - lzma_ret ret; - (void)base; - - if (outsize >= 0x7FFFFFFF) - return SQFS_ERROR_ARG_INVALID; - - ret = lzma_stream_buffer_decode(&memlimit, 0, NULL, - in, &src_pos, size, - out, &dest_pos, outsize); - - if (ret == LZMA_OK && size == src_pos) - return dest_pos; - - return SQFS_ERROR_COMPRESSOR; -} - -static void xz_get_configuration(const sqfs_compressor_t *base, - sqfs_compressor_config_t *cfg) -{ - const xz_compressor_t *xz = (const xz_compressor_t *)base; - - memset(cfg, 0, sizeof(*cfg)); - cfg->id = SQFS_COMP_XZ; - cfg->flags = xz->flags; - cfg->block_size = xz->block_size; - cfg->level = xz->level; - cfg->opt.xz.dict_size = xz->dict_size; - cfg->opt.xz.lc = xz->lc; - cfg->opt.xz.lp = xz->lp; - cfg->opt.xz.pb = xz->pb; - - if (base->do_block == xz_uncomp_block) - cfg->flags |= SQFS_COMP_FLAG_UNCOMPRESS; -} - -static sqfs_object_t *xz_create_copy(const sqfs_object_t *cmp) -{ - xz_compressor_t *xz = malloc(sizeof(*xz)); - - if (xz == NULL) - return NULL; - - memcpy(xz, cmp, sizeof(*xz)); - return (sqfs_object_t *)xz; -} - -static void xz_destroy(sqfs_object_t *base) -{ - free(base); -} - -int xz_compressor_create(const sqfs_compressor_config_t *cfg, - sqfs_compressor_t **out) -{ - sqfs_compressor_t *base; - xz_compressor_t *xz; - - if (cfg->flags & ~(SQFS_COMP_FLAG_GENERIC_ALL | - SQFS_COMP_FLAG_XZ_ALL)) { - return SQFS_ERROR_UNSUPPORTED; - } - - if (!is_dict_size_valid(cfg->opt.xz.dict_size)) - return SQFS_ERROR_UNSUPPORTED; - - if (cfg->opt.xz.lc + cfg->opt.xz.lp > 4) - return SQFS_ERROR_UNSUPPORTED; - - if (cfg->opt.xz.pb > SQFS_XZ_MAX_PB) - return SQFS_ERROR_UNSUPPORTED; - - if (cfg->level > SQFS_XZ_MAX_LEVEL) - return SQFS_ERROR_UNSUPPORTED; - - if (cfg->opt.xz.dict_size < SQFS_XZ_MIN_DICT_SIZE) - return SQFS_ERROR_UNSUPPORTED; - - if (cfg->opt.xz.dict_size > SQFS_XZ_MAX_DICT_SIZE) - return SQFS_ERROR_UNSUPPORTED; - - xz = calloc(1, sizeof(*xz)); - base = (sqfs_compressor_t *)xz; - if (xz == NULL) - return SQFS_ERROR_ALLOC; - - sqfs_object_init(xz, xz_destroy, xz_create_copy); - - xz->flags = cfg->flags; - xz->dict_size = cfg->opt.xz.dict_size; - xz->block_size = cfg->block_size; - xz->lc = cfg->opt.xz.lc; - xz->lp = cfg->opt.xz.lp; - xz->pb = cfg->opt.xz.pb; - xz->level = cfg->level; - base->get_configuration = xz_get_configuration; - base->do_block = (cfg->flags & SQFS_COMP_FLAG_UNCOMPRESS) ? - xz_uncomp_block : xz_comp_block; - base->write_options = xz_write_options; - base->read_options = xz_read_options; - - *out = base; - return 0; -} diff --git a/lib/sqfs/comp/zstd.c b/lib/sqfs/comp/zstd.c deleted file mode 100644 index a6d7975..0000000 --- a/lib/sqfs/comp/zstd.c +++ /dev/null @@ -1,172 +0,0 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ -/* - * zstd.c - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#define SQFS_BUILDING_DLL -#include "config.h" - -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> - -#include <zstd.h> -#include <zstd_errors.h> - -#include "internal.h" - -typedef struct { - sqfs_compressor_t base; - size_t block_size; - ZSTD_CCtx *zctx; - int level; -} zstd_compressor_t; - -typedef struct { - sqfs_u32 level; -} zstd_options_t; - -static int zstd_write_options(sqfs_compressor_t *base, sqfs_file_t *file) -{ - zstd_compressor_t *zstd = (zstd_compressor_t *)base; - zstd_options_t opt; - - if (zstd->level == SQFS_ZSTD_DEFAULT_LEVEL) - return 0; - - opt.level = htole32(zstd->level); - return sqfs_generic_write_options(file, &opt, sizeof(opt)); -} - -static int zstd_read_options(sqfs_compressor_t *base, sqfs_file_t *file) -{ - zstd_options_t opt; - int ret; - (void)base; - - ret = sqfs_generic_read_options(file, &opt, sizeof(opt)); - if (ret) - return ret; - - opt.level = le32toh(opt.level); - return 0; -} - -static sqfs_s32 zstd_comp_block(sqfs_compressor_t *base, const sqfs_u8 *in, - sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) -{ - zstd_compressor_t *zstd = (zstd_compressor_t *)base; - size_t ret; - - if (size >= 0x7FFFFFFF) - return SQFS_ERROR_ARG_INVALID; - - ret = ZSTD_compressCCtx(zstd->zctx, out, outsize, in, size, - zstd->level); - - if (ZSTD_isError(ret)) { - if (ZSTD_getErrorCode(ret) == ZSTD_error_dstSize_tooSmall) - return 0; - - return SQFS_ERROR_COMPRESSOR; - } - - return ret < size ? ret : 0; -} - -static sqfs_s32 zstd_uncomp_block(sqfs_compressor_t *base, const sqfs_u8 *in, - sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) -{ - size_t ret; - (void)base; - - if (outsize >= 0x7FFFFFFF) - return SQFS_ERROR_ARG_INVALID; - - ret = ZSTD_decompress(out, outsize, in, size); - - if (ZSTD_isError(ret)) - return SQFS_ERROR_COMPRESSOR; - - return ret; -} - -static void zstd_get_configuration(const sqfs_compressor_t *base, - sqfs_compressor_config_t *cfg) -{ - const zstd_compressor_t *zstd = (const zstd_compressor_t *)base; - - memset(cfg, 0, sizeof(*cfg)); - cfg->id = SQFS_COMP_ZSTD; - - cfg->block_size = zstd->block_size; - cfg->level = zstd->level; - - if (base->do_block == zstd_uncomp_block) - cfg->flags |= SQFS_COMP_FLAG_UNCOMPRESS; -} - -static sqfs_object_t *zstd_create_copy(const sqfs_object_t *cmp) -{ - zstd_compressor_t *zstd = malloc(sizeof(*zstd)); - - if (zstd == NULL) - return NULL; - - memcpy(zstd, cmp, sizeof(*zstd)); - - zstd->zctx = ZSTD_createCCtx(); - - if (zstd->zctx == NULL) { - free(zstd); - return NULL; - } - - return (sqfs_object_t *)zstd; -} - -static void zstd_destroy(sqfs_object_t *base) -{ - zstd_compressor_t *zstd = (zstd_compressor_t *)base; - - ZSTD_freeCCtx(zstd->zctx); - free(zstd); -} - -int zstd_compressor_create(const sqfs_compressor_config_t *cfg, - sqfs_compressor_t **out) -{ - zstd_compressor_t *zstd; - sqfs_compressor_t *base; - - if (cfg->flags & ~SQFS_COMP_FLAG_GENERIC_ALL) - return SQFS_ERROR_UNSUPPORTED; - - if (cfg->level < 1 || cfg->level > (unsigned int)ZSTD_maxCLevel()) - return SQFS_ERROR_UNSUPPORTED; - - zstd = calloc(1, sizeof(*zstd)); - base = (sqfs_compressor_t *)zstd; - if (zstd == NULL) - return SQFS_ERROR_ALLOC; - - sqfs_object_init(zstd, zstd_destroy, zstd_create_copy); - - zstd->block_size = cfg->block_size; - zstd->level = cfg->level; - zstd->zctx = ZSTD_createCCtx(); - if (zstd->zctx == NULL) { - free(zstd); - return SQFS_ERROR_COMPRESSOR; - } - - base->get_configuration = zstd_get_configuration; - base->do_block = cfg->flags & SQFS_COMP_FLAG_UNCOMPRESS ? - zstd_uncomp_block : zstd_comp_block; - base->write_options = zstd_write_options; - base->read_options = zstd_read_options; - - *out = base; - return 0; -} |