File: compressor_deflate.c

package info (click to toggle)
erofs-utils 1.9-3
  • links: PTS
  • area: main
  • in suites: sid
  • size: 1,484 kB
  • sloc: ansic: 28,409; makefile: 203; sh: 33
file content (89 lines) | stat: -rw-r--r-- 2,410 bytes parent folder | download | duplicates (3)
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
// SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0
/*
 * Copyright (C) 2023, Alibaba Cloud
 * Copyright (C) 2023, Gao Xiang <xiang@kernel.org>
 */
#include "erofs/internal.h"
#include "erofs/print.h"
#include "erofs/config.h"
#include "compressor.h"
#include "erofs/atomic.h"

void *kite_deflate_init(int level, unsigned int dict_size);
void kite_deflate_end(void *s);
int kite_deflate_destsize(void *s, const u8 *in, u8 *out,
			  unsigned int *srcsize, unsigned int target_dstsize);

static int deflate_compress_destsize(const struct erofs_compress *c,
				     const void *src, unsigned int *srcsize,
				     void *dst, unsigned int dstsize)
{
	int rc = kite_deflate_destsize(c->private_data, src, dst,
				       srcsize, dstsize);

	if (rc <= 0)
		return -EFAULT;
	return rc;
}

static int compressor_deflate_exit(struct erofs_compress *c)
{
	if (!c->private_data)
		return -EINVAL;

	kite_deflate_end(c->private_data);
	return 0;
}

static int compressor_deflate_init(struct erofs_compress *c)
{
	if (c->private_data) {
		kite_deflate_end(c->private_data);
		c->private_data = NULL;
	}
	c->private_data = kite_deflate_init(c->compression_level, c->dict_size);
	if (IS_ERR_VALUE(c->private_data))
		return PTR_ERR(c->private_data);
	return 0;
}

static int erofs_compressor_deflate_setlevel(struct erofs_compress *c,
					     int compression_level)
{
	if (compression_level < 0)
		compression_level = erofs_compressor_deflate.default_level;

	if (compression_level > erofs_compressor_deflate.best_level) {
		erofs_err("invalid compression level %d", compression_level);
		return -EINVAL;
	}
	c->compression_level = compression_level;
	return 0;
}

static int erofs_compressor_deflate_setdictsize(struct erofs_compress *c,
						u32 dict_size,
						u32 pclustersize_max)
{
	if (!dict_size)
		dict_size = erofs_compressor_deflate.default_dictsize;

	if (dict_size > erofs_compressor_deflate.max_dictsize) {
		erofs_err("dictionary size %u is too large", dict_size);
		return -EINVAL;
	}
	c->dict_size = dict_size;
	return 0;
}

const struct erofs_compressor erofs_compressor_deflate = {
	.default_level = 1,
	.best_level = 9,
	.default_dictsize = 1 << 15,
	.max_dictsize = 1 << 15,
	.init = compressor_deflate_init,
	.exit = compressor_deflate_exit,
	.setlevel = erofs_compressor_deflate_setlevel,
	.setdictsize = erofs_compressor_deflate_setdictsize,
	.compress_destsize = deflate_compress_destsize,
};