2 * Copyright (c) 2004-2016 Maxim Sobolev <sobomax@FreeBSD.org>
3 * Copyright (c) 2011 Aleksandr Rybalko <ray@ddteam.net>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/param.h>
39 #include "mkuz_lzma.h"
41 #define USED_BLOCKSIZE DEV_BSIZE
44 lzma_filter filters[2];
45 lzma_options_lzma opt_lzma;
51 static struct mkuz_lzma ulzma = {.strm = LZMA_STREAM_INIT};
54 mkuz_lzma_init(uint32_t blksz)
56 if (blksz % USED_BLOCKSIZE != 0) {
57 errx(1, "cluster size should be multiple of %d",
61 if (blksz > MAXPHYS) {
62 errx(1, "cluster size is too large");
65 ulzma.obuf = mkuz_safe_malloc(blksz * 2);
67 /* Init lzma encoder */
68 if (lzma_lzma_preset(&ulzma.opt_lzma, LZMA_PRESET_DEFAULT))
69 errx(1, "Error loading LZMA preset");
71 ulzma.filters[0].id = LZMA_FILTER_LZMA2;
72 ulzma.filters[0].options = &ulzma.opt_lzma;
73 ulzma.filters[1].id = LZMA_VLI_UNKNOWN;
81 mkuz_lzma_compress(const char *ibuf, uint32_t *destlen)
85 ret = lzma_stream_encoder(&ulzma.strm, ulzma.filters, LZMA_CHECK_CRC32);
87 if (ret == LZMA_MEMLIMIT_ERROR)
88 errx(1, "can't compress data: LZMA_MEMLIMIT_ERROR");
90 errx(1, "can't compress data: LZMA compressor ERROR");
93 ulzma.strm.next_in = ibuf;
94 ulzma.strm.avail_in = ulzma.blksz;
95 ulzma.strm.next_out = ulzma.obuf;
96 ulzma.strm.avail_out = ulzma.blksz * 2;
98 ret = lzma_code(&ulzma.strm, LZMA_FINISH);
100 if (ret != LZMA_STREAM_END) {
102 errx(1, "lzma_code FINISH failed, code=%d, pos(in=%zd, "
103 "out=%zd)", ret, (ulzma.blksz - ulzma.strm.avail_in),
104 (ulzma.blksz * 2 - ulzma.strm.avail_out));
107 lzma_end(&ulzma.strm);
109 *destlen = (ulzma.blksz * 2) - ulzma.strm.avail_out;