diff options
Diffstat (limited to 'include/sqfs/compressor.h')
-rw-r--r-- | include/sqfs/compressor.h | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/include/sqfs/compressor.h b/include/sqfs/compressor.h new file mode 100644 index 0000000..46bdf58 --- /dev/null +++ b/include/sqfs/compressor.h @@ -0,0 +1,383 @@ +/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* + * compressor.h - This file is part of libsquashfs + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ +#ifndef SQFS_COMPRESSOR_H +#define SQFS_COMPRESSOR_H + +#include "sqfs/predef.h" +#include "sqfs/super.h" + +/** + * @file compressor.h + * + * @brief Contains declarations to everything related to data compression. + */ + +/** + * @interface sqfs_compressor_t + * + * @brief Encapsultes a compressor with a simple interface to compress or + * extract chunks of data. + */ +struct sqfs_compressor_t { + /** + * @brief Destroy a compressor and free all memory used by it. + * + * @param cmp A pointer to a compressor object. + */ + void (*destroy)(sqfs_compressor_t *cmp); + + /** + * @brief Write compressor options to disk if non-default settings + * have been used. + * + * The options are stored in an uncompressed meta data block directly + * after the super block. + * + * @param cmp A pointer to a compressor object. + * @param file A file to write to. + * + * @return The number of bytes written on success, 0 means default + * settings are used. A negative value is an @ref E_SQFS_ERROR + * identifier. + */ + int (*write_options)(sqfs_compressor_t *cmp, sqfs_file_t *file); + + /** + * @brief Read compressor options from disk. + * + * @param cmp A pointer to a compressor object. + * @param file A file to read from. + * + * @return Zero on success or an @ref E_SQFS_ERROR value. + */ + int (*read_options)(sqfs_compressor_t *cmp, sqfs_file_t *file); + + /** + * @brief Compress or uncompress a chunk of data. + * + * @param cmp A pointer to a compressor object. + * @param in A pointer to the input buffer to read from. + * @param size The number of bytes to read from the input and compress. + * @param out The destination buffer to write the result to. + * @param outsize The available space in the destination buffer. + * + * @return The number of bytes written to the buffer, a negative + * value is an @ref E_SQFS_ERROR value. The value 0 means + * the output buffer was too small when extracting or that + * the result is larger than the input when compressing. + */ + sqfs_s32 (*do_block)(sqfs_compressor_t *cmp, const sqfs_u8 *in, + sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize); + + /** + * @brief Create an exact copt of agiven compressor + * + * @param cmp A pointer to a compressor object. + * + * @return A deep copy of the given compressor. + */ + sqfs_compressor_t *(*create_copy)(sqfs_compressor_t *cmp); +}; + +/** + * @struct sqfs_compressor_config_t + * + * @brief Configuration parameters for instantiating a compressor backend. + */ +struct sqfs_compressor_config_t { + /** + * @brief An @ref E_SQFS_COMPRESSOR identifier + */ + sqfs_u16 id; + + /** + * @brief A combination of @ref SQFS_COMP_FLAG flags. + */ + sqfs_u16 flags; + + /** + * @brief The intended data block size. + */ + sqfs_u32 block_size; + + /** + * @brief Backend specific options for fine tuing. + */ + union { + /** + * @brief Options for the zlib compressor. + */ + struct { + /** + * @brief Compression level. Value between 1 and 9. + * + * Default is 9, i.e. best compression. + */ + sqfs_u16 level; + + /** + * @brief Deflate window size. Value between 8 and 15. + * + * Default is 15, i.e. 32k window. + */ + sqfs_u16 window_size; + } gzip; + + /** + * @brief Options for the zstd compressor. + */ + struct { + /** + * @brief Compression level. Value between 1 and 22. + * + * Default is 15. + */ + sqfs_u16 level; + } zstd; + + /** + * @brief Options for the lzo compressor. + */ + struct { + /** + * @brief Which variant of lzo should be used. + * + * An @ref SQFS_LZO_ALGORITHM value. Default is + * @ref SQFS_LZO1X_999, i.e. best compression. + */ + sqfs_u16 algorithm; + + /** + * @brief Compression level for @ref SQFS_LZO1X_999. + * + * If the selected algorithm is @ref SQFS_LZO1X_999, + * this can be a value between 0 and 9. For all other + * algorithms it has to be 0. + * + * Defaults to 9, i.e. best compression. + */ + sqfs_u16 level; + } lzo; + + /** + * @brief Options for the xz compressor. + */ + struct { + /** + * @brief LZMA dictionary size. + * + * This value must either be a power of two or the sumo + * of two consecutive powers of two. + * + * Default is setting this to the same as the + * block size. + */ + sqfs_u32 dict_size; + } xz; + } opt; +}; + +/** + * @enum SQFS_COMP_FLAG + * + * @brief Flags for configuring the compressor. + */ +typedef enum { + /** + * @brief For LZ4, set this to use high compression mode. + */ + SQFS_COMP_FLAG_LZ4_HC = 0x0001, + SQFS_COMP_FLAG_LZ4_ALL = 0x0001, + + /** + * @brief For LZMA, set this to select the x86 BCJ filter. + */ + SQFS_COMP_FLAG_XZ_X86 = 0x0001, + + /** + * @brief For LZMA, set this to select the PowerPC BCJ filter. + */ + SQFS_COMP_FLAG_XZ_POWERPC = 0x0002, + + /** + * @brief For LZMA, set this to select the Itanium BCJ filter. + */ + SQFS_COMP_FLAG_XZ_IA64 = 0x0004, + + /** + * @brief For LZMA, set this to select the ARM BCJ filter. + */ + SQFS_COMP_FLAG_XZ_ARM = 0x0008, + + /** + * @brief For LZMA, set this to select the ARM Thumb BCJ filter. + */ + SQFS_COMP_FLAG_XZ_ARMTHUMB = 0x0010, + + /** + * @brief For LZMA, set this to select the Sparc BCJ filter. + */ + SQFS_COMP_FLAG_XZ_SPARC = 0x0020, + SQFS_COMP_FLAG_XZ_ALL = 0x003F, + + /** + * @brief For zlib deflate, set this to try the default strategy. + */ + SQFS_COMP_FLAG_GZIP_DEFAULT = 0x0001, + + /** + * @brief For zlib deflate, set this to try the "filtered" strategy. + */ + SQFS_COMP_FLAG_GZIP_FILTERED = 0x0002, + + /** + * @brief For zlib deflate, set this to try the huffman only strategy. + */ + SQFS_COMP_FLAG_GZIP_HUFFMAN = 0x0004, + + /** + * @brief For zlib deflate, set this to try the RLE strategy. + */ + SQFS_COMP_FLAG_GZIP_RLE = 0x0008, + + /** + * @brief For zlib deflate, set this to try the fixed strategy. + */ + SQFS_COMP_FLAG_GZIP_FIXED = 0x0010, + SQFS_COMP_FLAG_GZIP_ALL = 0x001F, + + /** + * @brief Set this if the compressor should actually extract + * instead of compress data. + */ + SQFS_COMP_FLAG_UNCOMPRESS = 0x8000, + SQFS_COMP_FLAG_GENERIC_ALL = 0x8000, +} SQFS_COMP_FLAG; + +/** + * @enum SQFS_LZO_ALGORITHM + * + * @brief The available LZO algorithms. + */ +typedef enum { + SQFS_LZO1X_1 = 0, + SQFS_LZO1X_1_11 = 1, + SQFS_LZO1X_1_12 = 2, + SQFS_LZO1X_1_15 = 3, + SQFS_LZO1X_999 = 4, +} SQFS_LZO_ALGORITHM; + +#define SQFS_GZIP_DEFAULT_LEVEL (9) +#define SQFS_GZIP_DEFAULT_WINDOW (15) + +#define SQFS_LZO_DEFAULT_ALG SQFS_LZO1X_999 +#define SQFS_LZO_DEFAULT_LEVEL (8) + +#define SQFS_ZSTD_DEFAULT_LEVEL (15) + +#define SQFS_GZIP_MIN_LEVEL (1) +#define SQFS_GZIP_MAX_LEVEL (9) + +#define SQFS_LZO_MIN_LEVEL (0) +#define SQFS_LZO_MAX_LEVEL (9) + +#define SQFS_ZSTD_MIN_LEVEL (1) +#define SQFS_ZSTD_MAX_LEVEL (22) + +#define SQFS_GZIP_MIN_WINDOW (8) +#define SQFS_GZIP_MAX_WINDOW (15) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize a compressor configuration + * + * The detail configuration options are all initialized to the defaults for + * the compressor in question. + * + * @param cfg A pointer to a compressor configuration to initialize + * @param id The compressor id to set. + * @param block_size The block size to set. + * @param flags The compressor flags to set. + * + * @return Zero on success, an @ref E_SQFS_ERROR value if some of the options + * don't make sense (e.g. unknown flags are used). + */ +SQFS_API int sqfs_compressor_config_init(sqfs_compressor_config_t *cfg, + E_SQFS_COMPRESSOR id, + size_t block_size, sqfs_u16 flags); + +/** + * @brief Check if a specified compressor implementation is available. + * + * @param id An @ref E_SQFS_COMPRESSOR identifier. + * + * @return true if the implementation is available and can be instantiated + * through @ref sqfs_compressor_create. + */ +SQFS_API bool sqfs_compressor_exists(E_SQFS_COMPRESSOR id); + +/** + * @brief Create an instance of a compressor implementation. + * + * @param cfg A pointer to a compressor configuration. + * + * @return A pointer to a compressor object on success, NULL on allocation + * failure or if initializing the compressor failed. + */ +SQFS_API +sqfs_compressor_t *sqfs_compressor_create(const sqfs_compressor_config_t *cfg); + +/** + * @brief Get the name of a compressor backend from its ID. + * + * This function will even resolve compressor names that are not built in, so + * use @ref sqfs_compressor_exists to check if a compressor is actually + * available. + * + * @param id An @ref E_SQFS_COMPRESSOR identifier. + * + * @return A string holding the name of the compressor, NULL if the compressor + * ID is not known. + */ +SQFS_API const char *sqfs_compressor_name_from_id(E_SQFS_COMPRESSOR id); + +/** + * @brief Get the compressor ID using just the name of the backend. + * + * This function will even resolve compressor names that are not built in, so + * use @ref sqfs_compressor_exists to check if a compressor is actually + * available. + * + * @param name The name of the compressor backend. + * @param out Returns the coresponding @ref E_SQFS_COMPRESSOR identifier. + * + * @return Zero on success, -1 if the backend is unknown. + */ +SQFS_API +int sqfs_compressor_id_from_name(const char *name, E_SQFS_COMPRESSOR *out); + +#ifdef __cplusplus +} +#endif + +#endif /* SQFS_COMPRESSOR_H */ |