1 ///////////////////////////////////////////////////////////////////////////////
3 /// \file memory_usage.c
4 /// \brief Calculate rough amount of memory required by filters
6 // Copyright (C) 2007 Lasse Collin
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
18 ///////////////////////////////////////////////////////////////////////////////
21 #include "lz_encoder.h"
22 #include "lzma_literal.h"
26 get_usage(const lzma_options_filter *filter, bool is_encoder)
32 case LZMA_FILTER_POWERPC:
33 case LZMA_FILTER_IA64:
35 case LZMA_FILTER_ARMTHUMB:
36 case LZMA_FILTER_SPARC:
37 case LZMA_FILTER_DELTA:
38 // These don't require any significant amount of memory.
42 case LZMA_FILTER_SUBBLOCK:
44 const lzma_options_subblock *options = filter->options;
45 ret = options->subblock_data_size;
51 #ifdef HAVE_FILTER_LZMA
52 case LZMA_FILTER_LZMA: {
53 const lzma_options_lzma *options = filter->options;
55 // Literal coder - this can be signficant if both values are
56 // big, or if sizeof(probability) is big.
57 ret = literal_states(options->literal_context_bits,
58 options->literal_pos_bits) * LIT_SIZE
59 * sizeof(probability);
61 // Dictionary base size
62 ret += options->dictionary_size;
66 // This is rough, but should be accurate enough
68 ret += options->dictionary_size / 2;
73 if (lzma_lz_encoder_hash_properties(
74 options->match_finder,
75 options->dictionary_size,
76 &dummy1, &dummy2, &num_items))
79 ret += (uint64_t)(num_items) * sizeof(uint32_t);
97 extern LZMA_API uint32_t
98 lzma_memory_usage(const lzma_options_filter *filters, lzma_bool is_encoder)
102 for (size_t i = 0; filters[i].id != UINT64_MAX; ++i) {
103 const uint64_t ret = get_usage(filters + i, is_encoder);
104 if (ret == UINT64_MAX)
110 // Convert to mebibytes with rounding.
111 return usage / (1024 * 1024) + (usage % (1024 * 1024) >= 512 ? 1 : 0);