aboutsummaryrefslogtreecommitdiff
path: root/include/sqfs/compress.h
blob: 27c603d872e2233ae43040654f35c5dfeafa1011 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/* SPDX-License-Identifier: GPL-3.0-or-later */
/*
 * compress.h
 *
 * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
 */
#ifndef SQFS_COMPRESS_H
#define SQFS_COMPRESS_H

#include "config.h"

#include <sys/types.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#include "sqfs/predef.h"
#include "sqfs/super.h"

typedef struct sqfs_compressor_t sqfs_compressor_t;

/* Encapsultes a compressor with a simple interface to compress or
   uncompress/extract blocks of data. */
struct sqfs_compressor_t {
	void (*destroy)(sqfs_compressor_t *cmp);

	/* Write compressor options to the output file if necessary.
	   Returns the number of bytes written or -1 on failure.
	   Internally prints error messages to stderr. */
	int (*write_options)(sqfs_compressor_t *cmp, int fd);

	/* Read compressor options to the input file.
	   Returns zero on success, -1 on failure.
	   Internally prints error messages to stderr. */
	int (*read_options)(sqfs_compressor_t *cmp, int fd);

	/*
	  Compress or uncompress a chunk of data.

	  Returns the number of bytes written to the output buffer, -1 on
	  failure or 0 if the output buffer was too small.
	  The compressor also returns 0 if the compressed result ends
	  up larger than the original input.

	  Internally prints compressor specific error messages to stderr.
	*/
	ssize_t (*do_block)(sqfs_compressor_t *cmp, const uint8_t *in,
			    size_t size, uint8_t *out, size_t outsize);

	/* create another compressor just like this one, i.e.
	   with the exact same settings */
	sqfs_compressor_t *(*create_copy)(sqfs_compressor_t *cmp);
};

typedef struct {
	uint16_t id;
	uint16_t flags;
	uint32_t block_size;

	union {
		struct {
			uint16_t level;
			uint16_t window_size;
		} gzip;

		struct {
			uint16_t level;
		} zstd;

		struct {
			uint16_t algorithm;
			uint16_t level;
		} lzo;

		struct {
			uint32_t dict_size;
		} xz;
	} opt;
} sqfs_compressor_config_t;

typedef enum {
	SQFS_COMP_FLAG_LZ4_HC = 0x0001,
	SQFS_COMP_FLAG_LZ4_ALL = 0x0001,

	SQFS_COMP_FLAG_XZ_X86 = 0x0001,
	SQFS_COMP_FLAG_XZ_POWERPC = 0x0002,
	SQFS_COMP_FLAG_XZ_IA64 = 0x0004,
	SQFS_COMP_FLAG_XZ_ARM = 0x0008,
	SQFS_COMP_FLAG_XZ_ARMTHUMB = 0x0010,
	SQFS_COMP_FLAG_XZ_SPARC = 0x0020,
	SQFS_COMP_FLAG_XZ_ALL = 0x003F,

	SQFS_COMP_FLAG_GZIP_DEFAULT = 0x0001,
	SQFS_COMP_FLAG_GZIP_FILTERED = 0x0002,
	SQFS_COMP_FLAG_GZIP_HUFFMAN = 0x0004,
	SQFS_COMP_FLAG_GZIP_RLE = 0x0008,
	SQFS_COMP_FLAG_GZIP_FIXED = 0x0010,
	SQFS_COMP_FLAG_GZIP_ALL = 0x001F,

	SQFS_COMP_FLAG_UNCOMPRESS = 0x8000,
	SQFS_COMP_FLAG_GENERIC_ALL = 0x8000,
} SQFS_COMP_FLAG;

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

SQFS_API int sqfs_compressor_config_init(sqfs_compressor_config_t *cfg,
					 E_SQFS_COMPRESSOR id,
					 size_t block_size, uint16_t flags);

SQFS_API bool sqfs_compressor_exists(E_SQFS_COMPRESSOR id);

SQFS_API
sqfs_compressor_t *sqfs_compressor_create(const sqfs_compressor_config_t *cfg);

SQFS_API const char *sqfs_compressor_name_from_id(E_SQFS_COMPRESSOR id);

SQFS_API
int sqfs_compressor_id_from_name(const char *name, E_SQFS_COMPRESSOR *out);

#ifdef __cplusplus
}
#endif

#endif /* SQFS_COMPRESS_H */