summaryrefslogtreecommitdiffstats
path: root/src/basic/compress.h
blob: 76ffe2ad4286ccd4dd07d5333f92eee98f0bcc43 (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
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once

#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>

#if HAVE_LZ4
#include <lz4.h>
#include <lz4frame.h>
#endif

#include "dlfcn-util.h"

typedef enum Compression {
        COMPRESSION_NONE,
        COMPRESSION_XZ,
        COMPRESSION_LZ4,
        COMPRESSION_ZSTD,
        _COMPRESSION_MAX,
        _COMPRESSION_INVALID = -EINVAL,
} Compression;

const char* compression_to_string(Compression compression);
Compression compression_from_string(const char *compression);

bool compression_supported(Compression c);

int compress_blob_xz(const void *src, uint64_t src_size,
                     void *dst, size_t dst_alloc_size, size_t *dst_size);
int compress_blob_lz4(const void *src, uint64_t src_size,
                      void *dst, size_t dst_alloc_size, size_t *dst_size);
int compress_blob_zstd(const void *src, uint64_t src_size,
                       void *dst, size_t dst_alloc_size, size_t *dst_size);

int decompress_blob_xz(const void *src, uint64_t src_size,
                       void **dst, size_t* dst_size, size_t dst_max);
int decompress_blob_lz4(const void *src, uint64_t src_size,
                        void **dst, size_t* dst_size, size_t dst_max);
int decompress_blob_zstd(const void *src, uint64_t src_size,
                        void **dst, size_t* dst_size, size_t dst_max);
int decompress_blob(Compression compression,
                    const void *src, uint64_t src_size,
                    void **dst, size_t* dst_size, size_t dst_max);

int decompress_startswith_xz(const void *src, uint64_t src_size,
                             void **buffer,
                             const void *prefix, size_t prefix_len,
                             uint8_t extra);
int decompress_startswith_lz4(const void *src, uint64_t src_size,
                              void **buffer,
                              const void *prefix, size_t prefix_len,
                              uint8_t extra);
int decompress_startswith_zstd(const void *src, uint64_t src_size,
                               void **buffer,
                               const void *prefix, size_t prefix_len,
                               uint8_t extra);
int decompress_startswith(Compression compression,
                          const void *src, uint64_t src_size,
                          void **buffer,
                          const void *prefix, size_t prefix_len,
                          uint8_t extra);

int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size);
int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size);
int compress_stream_zstd(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size);

int decompress_stream_xz(int fdf, int fdt, uint64_t max_size);
int decompress_stream_lz4(int fdf, int fdt, uint64_t max_size);
int decompress_stream_zstd(int fdf, int fdt, uint64_t max_size);

#if HAVE_LZ4
DLSYM_PROTOTYPE(LZ4_compress_default);
DLSYM_PROTOTYPE(LZ4_decompress_safe);
DLSYM_PROTOTYPE(LZ4_decompress_safe_partial);
DLSYM_PROTOTYPE(LZ4_versionNumber);

int dlopen_lz4(void);
#endif

#if HAVE_ZSTD
int dlopen_zstd(void);
#endif

#if HAVE_XZ
int dlopen_lzma(void);
#endif


static inline int compress_blob(
                Compression compression,
                const void *src, uint64_t src_size,
                void *dst, size_t dst_alloc_size, size_t *dst_size) {

        switch (compression) {
        case COMPRESSION_ZSTD:
                return compress_blob_zstd(src, src_size, dst, dst_alloc_size, dst_size);
        case COMPRESSION_LZ4:
                return compress_blob_lz4(src, src_size, dst, dst_alloc_size, dst_size);
        case COMPRESSION_XZ:
                return compress_blob_xz(src, src_size, dst, dst_alloc_size, dst_size);
        default:
                return -EOPNOTSUPP;
        }
}

static inline int compress_stream(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size) {
        switch (DEFAULT_COMPRESSION) {
        case COMPRESSION_ZSTD:
                return compress_stream_zstd(fdf, fdt, max_bytes, ret_uncompressed_size);
        case COMPRESSION_LZ4:
                return compress_stream_lz4(fdf, fdt, max_bytes, ret_uncompressed_size);
        case COMPRESSION_XZ:
                return compress_stream_xz(fdf, fdt, max_bytes, ret_uncompressed_size);
        default:
                return -EOPNOTSUPP;
        }
}

static inline const char* default_compression_extension(void) {
        switch (DEFAULT_COMPRESSION) {
        case COMPRESSION_ZSTD:
                return ".zst";
        case COMPRESSION_LZ4:
                return ".lz4";
        case COMPRESSION_XZ:
                return ".xz";
        default:
                return "";
        }
}

int decompress_stream(const char *filename, int fdf, int fdt, uint64_t max_bytes);