4 * A compressor for the LZMS compression format.
8 * Copyright (C) 2013 Eric Biggers
10 * This file is part of wimlib, a library for working with WIM files.
12 * wimlib is free software; you can redistribute it and/or modify it under the
13 * terms of the GNU General Public License as published by the Free
14 * Software Foundation; either version 3 of the License, or (at your option)
17 * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
18 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
19 * A PARTICULAR PURPOSE. See the GNU General Public License for more
22 * You should have received a copy of the GNU General Public License
23 * along with wimlib; if not, see http://www.gnu.org/licenses/.
26 /* This a compressor for the LZMS compression format. More details about this
27 * format can be found in lzms-decompress.c. */
34 #include "wimlib/assert.h"
35 #include "wimlib/compressor_ops.h"
36 #include "wimlib/compress_common.h"
37 #include "wimlib/endianness.h"
38 #include "wimlib/error.h"
39 #include "wimlib/lzms.h"
40 #include "wimlib/util.h"
44 struct lzms_compressor {
48 s32 *last_target_usages;
52 lzms_compress(const void *uncompressed_data, size_t uncompressed_size,
53 void *compressed_data, size_t compressed_size_avail, void *_ctx)
55 struct lzms_compressor *ctx = _ctx;
57 if (uncompressed_size > ctx->max_block_size) {
58 LZMS_DEBUG("Can't compress %su bytes: LZMS context "
59 "only supports %u bytes",
60 uncompressed_size, ctx->max_block_size);
64 memcpy(ctx->window, uncompressed_data, uncompressed_size);
65 ctx->window_size = uncompressed_size;
67 lzms_x86_filter(ctx->window, ctx->window_size,
68 ctx->last_target_usages, false);
74 lzms_free_compressor(void *_ctx)
76 struct lzms_compressor *ctx = _ctx;
80 FREE(ctx->last_target_usages);
86 lzms_create_compressor(size_t max_block_size,
87 const struct wimlib_compressor_params_header *params,
90 struct lzms_compressor *ctx;
92 if (max_block_size == 0 || max_block_size > 1U << 26) {
93 LZMS_DEBUG("Invalid max_block_size (%u)", max_block_size);
94 return WIMLIB_ERR_INVALID_PARAM;
97 ctx = CALLOC(1, sizeof(struct lzms_compressor));
101 ctx->window = MALLOC(max_block_size);
102 if (ctx->window == NULL)
104 ctx->max_block_size = max_block_size;
106 ctx->last_target_usages = MALLOC(65536 * sizeof(ctx->last_target_usages[0]));
107 if (ctx->last_target_usages == NULL)
114 lzms_free_compressor(ctx);
115 return WIMLIB_ERR_NOMEM;
118 const struct compressor_ops lzms_compressor_ops = {
119 .create_compressor = lzms_create_compressor,
120 .compress = lzms_compress,
121 .free_compressor = lzms_free_compressor,