summaryrefslogtreecommitdiff
path: root/include/sqfs/compressor.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/sqfs/compressor.h')
-rw-r--r--include/sqfs/compressor.h383
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 */