]> icculus.org git repositories - icculus/xz.git/blob - src/liblzma/lzma/lzma_encoder_init.c
Remove some redundant code from LZMA encoder.
[icculus/xz.git] / src / liblzma / lzma / lzma_encoder_init.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       lzma_encoder_init.c
4 /// \brief      Creating, resetting and destroying the LZMA encoder
5 //
6 //  Copyright (C) 1999-2006 Igor Pavlov
7 //  Copyright (C) 2007 Lasse Collin
8 //
9 //  This library is free software; you can redistribute it and/or
10 //  modify it under the terms of the GNU Lesser General Public
11 //  License as published by the Free Software Foundation; either
12 //  version 2.1 of the License, or (at your option) any later version.
13 //
14 //  This library is distributed in the hope that it will be useful,
15 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 //  Lesser General Public License for more details.
18 //
19 ///////////////////////////////////////////////////////////////////////////////
20
21 #include "lzma_encoder_private.h"
22
23
24 /// \brief      Initializes the length encoder
25 static void
26 length_encoder_reset(lzma_length_encoder *lencoder,
27                 const uint32_t num_pos_states, const uint32_t table_size)
28 {
29         // NLength::CPriceTableEncoder::SetTableSize()
30         lencoder->table_size = table_size;
31
32         // NLength::CEncoder::Init()
33         bit_reset(lencoder->choice);
34         bit_reset(lencoder->choice2);
35
36         for (size_t pos_state = 0; pos_state < num_pos_states; ++pos_state) {
37                 bittree_reset(lencoder->low[pos_state], LEN_LOW_BITS);
38                 bittree_reset(lencoder->mid[pos_state], LEN_MID_BITS);
39         }
40
41         bittree_reset(lencoder->high, LEN_HIGH_BITS);
42
43         // NLength::CPriceTableEncoder::UpdateTables()
44         for (size_t pos_state = 0; pos_state < num_pos_states; ++pos_state)
45                 lencoder->counters[pos_state] = 1;
46
47         return;
48 }
49
50
51 static void
52 lzma_lzma_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
53 {
54         lzma_lz_encoder_end(&coder->lz, allocator);
55         lzma_free(coder, allocator);
56         return;
57 }
58
59
60 extern lzma_ret
61 lzma_lzma_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
62                 const lzma_filter_info *filters)
63 {
64         if (next->coder == NULL) {
65                 next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
66                 if (next->coder == NULL)
67                         return LZMA_MEM_ERROR;
68
69                 next->coder->next = LZMA_NEXT_CODER_INIT;
70                 next->coder->lz = LZMA_LZ_ENCODER_INIT;
71         }
72
73         // Validate options that aren't validated elsewhere.
74         const lzma_options_lzma *options = filters[0].options;
75         if (options->pos_bits > LZMA_POS_BITS_MAX
76                         || options->fast_bytes < LZMA_FAST_BYTES_MIN
77                         || options->fast_bytes > LZMA_FAST_BYTES_MAX) {
78                 lzma_lzma_encoder_end(next->coder, allocator);
79                 return LZMA_HEADER_ERROR;
80         }
81
82         // Set compression mode.
83         switch (options->mode) {
84                 case LZMA_MODE_FAST:
85                         next->coder->best_compression = false;
86                         break;
87
88                 case LZMA_MODE_BEST:
89                         next->coder->best_compression = true;
90                         break;
91
92                 default:
93                         lzma_lzma_encoder_end(next->coder, allocator);
94                         return LZMA_HEADER_ERROR;
95         }
96
97         // Initialize literal coder.
98         {
99                 const lzma_ret ret = lzma_literal_init(
100                                 &next->coder->literal_coder,
101                                 options->literal_context_bits,
102                                 options->literal_pos_bits);
103                 if (ret != LZMA_OK)
104                         return ret;
105         }
106
107         // Initialize LZ encoder.
108         {
109                 const lzma_ret ret = lzma_lz_encoder_reset(
110                                 &next->coder->lz, allocator, &lzma_lzma_encode,
111                                 options->dictionary_size, OPTS,
112                                 options->fast_bytes, MATCH_MAX_LEN + 1 + OPTS,
113                                 options->match_finder,
114                                 options->match_finder_cycles,
115                                 options->preset_dictionary,
116                                 options->preset_dictionary_size);
117                 if (ret != LZMA_OK) {
118                         lzma_lzma_encoder_end(next->coder, allocator);
119                         return ret;
120                 }
121         }
122
123         // Set dist_table_size.
124         {
125                 // Round the dictionary size up to next 2^n.
126                 uint32_t log_size;
127                 for (log_size = 0; (UINT32_C(1) << log_size)
128                                 < options->dictionary_size; ++log_size) ;
129
130                 next->coder->dist_table_size = log_size * 2;
131         }
132
133         // Misc FIXME desc
134         next->coder->align_price_count = UINT32_MAX;
135         next->coder->match_price_count = UINT32_MAX;
136         next->coder->dictionary_size = options->dictionary_size;
137         next->coder->pos_mask = (1U << options->pos_bits) - 1;
138         next->coder->fast_bytes = options->fast_bytes;
139
140         // Range coder
141         rc_reset(&next->coder->rc);
142
143         // State
144         next->coder->state = 0;
145         next->coder->previous_byte = 0;
146         for (size_t i = 0; i < REP_DISTANCES; ++i)
147                 next->coder->reps[i] = 0;
148
149         // Bit encoders
150         for (size_t i = 0; i < STATES; ++i) {
151                 for (size_t j = 0; j <= next->coder->pos_mask; ++j) {
152                         bit_reset(next->coder->is_match[i][j]);
153                         bit_reset(next->coder->is_rep0_long[i][j]);
154                 }
155
156                 bit_reset(next->coder->is_rep[i]);
157                 bit_reset(next->coder->is_rep0[i]);
158                 bit_reset(next->coder->is_rep1[i]);
159                 bit_reset(next->coder->is_rep2[i]);
160         }
161
162         for (size_t i = 0; i < FULL_DISTANCES - END_POS_MODEL_INDEX; ++i)
163                 bit_reset(next->coder->pos_encoders[i]);
164
165         // Bit tree encoders
166         for (size_t i = 0; i < LEN_TO_POS_STATES; ++i)
167                 bittree_reset(next->coder->pos_slot_encoder[i], POS_SLOT_BITS);
168
169         bittree_reset(next->coder->pos_align_encoder, ALIGN_BITS);
170
171         // Length encoders
172         length_encoder_reset(&next->coder->match_len_encoder,
173                         1U << options->pos_bits,
174                         options->fast_bytes + 1 - MATCH_MIN_LEN);
175
176         length_encoder_reset(&next->coder->rep_len_encoder,
177                         1U << options->pos_bits,
178                         next->coder->fast_bytes + 1 - MATCH_MIN_LEN);
179
180         next->coder->prev_len_encoder = NULL;
181
182         // Misc
183         next->coder->longest_match_was_found = false;
184         next->coder->optimum_end_index = 0;
185         next->coder->optimum_current_index = 0;
186         next->coder->additional_offset = 0;
187
188         next->coder->now_pos = 0;
189         next->coder->is_initialized = false;
190         next->coder->is_flushed = false,
191         next->coder->write_eopm = true;
192
193         // Initialize the next decoder in the chain, if any.
194         {
195                 const lzma_ret ret = lzma_next_filter_init(&next->coder->next,
196                                 allocator, filters + 1);
197                 if (ret != LZMA_OK) {
198                         lzma_lzma_encoder_end(next->coder, allocator);
199                         return ret;
200                 }
201         }
202
203         // Initialization successful. Set the function pointers.
204         next->code = &lzma_lz_encode;
205         next->end = &lzma_lzma_encoder_end;
206
207         return LZMA_OK;
208 }
209
210
211 extern bool
212 lzma_lzma_encode_properties(const lzma_options_lzma *options, uint8_t *byte)
213 {
214         if (options->literal_context_bits > LZMA_LITERAL_CONTEXT_BITS_MAX
215                         || options->literal_pos_bits
216                                 > LZMA_LITERAL_POS_BITS_MAX
217                         || options->pos_bits > LZMA_POS_BITS_MAX
218                         || options->literal_context_bits
219                                         + options->literal_pos_bits
220                                 > LZMA_LITERAL_BITS_MAX)
221                 return true;
222
223         *byte = (options->pos_bits * 5 + options->literal_pos_bits) * 9
224                         + options->literal_context_bits;
225         assert(*byte <= (4 * 5 + 4) * 9 + 8);
226
227         return false;
228 }