Coverage Report

Created: 2026-09-14 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibCompress/Lzma.cpp
Line
Count
Source
1
/*
2
 * Copyright (c) 2023, Tim Schumacher <timschumi@gmx.de>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#include <AK/Debug.h>
8
#include <AK/IntegralMath.h>
9
#include <LibCompress/Lzma.h>
10
11
namespace Compress {
12
13
u32 LzmaHeader::dictionary_size() const
14
6.18k
{
15
    // "If the value of dictionary size in properties is smaller than (1 << 12),
16
    //  the LZMA decoder must set the dictionary size variable to (1 << 12)."
17
6.18k
    constexpr u32 minimum_dictionary_size = (1 << 12);
18
6.18k
    if (unchecked_dictionary_size < minimum_dictionary_size)
19
624
        return minimum_dictionary_size;
20
21
5.56k
    return unchecked_dictionary_size;
22
6.18k
}
23
24
Optional<u64> LzmaHeader::uncompressed_size() const
25
4.48k
{
26
    // We are making a copy of the packed field here because we would otherwise
27
    // pass an unaligned reference to the constructor of Optional, which is
28
    // undefined behavior.
29
4.48k
    auto uncompressed_size = encoded_uncompressed_size;
30
31
    // "If "Uncompressed size" field contains ones in all 64 bits, it means that
32
    //  uncompressed size is unknown and there is the "end marker" in stream,
33
    //  that indicates the end of decoding point."
34
4.48k
    if (uncompressed_size == placeholder_for_unknown_uncompressed_size)
35
2.91k
        return {};
36
37
    // "In opposite case, if the value from "Uncompressed size" field is not
38
    //  equal to ((2^64) - 1), the LZMA stream decoding must be finished after
39
    //  specified number of bytes (Uncompressed size) is decoded. And if there
40
    //  is the "end marker", the LZMA decoder must read that marker also."
41
1.57k
    return uncompressed_size;
42
4.48k
}
43
44
ErrorOr<LzmaModelProperties> LzmaHeader::decode_model_properties(u8 input_bits)
45
4.48k
{
46
    // "Decodes the following values from the encoded model properties field:
47
    //
48
    //     name  Range          Description
49
    //       lc  [0, 8]         the number of "literal context" bits
50
    //       lp  [0, 4]         the number of "literal pos" bits
51
    //       pb  [0, 4]         the number of "pos" bits
52
    //
53
    //  Encoded using `((pb * 5 + lp) * 9 + lc)`."
54
55
4.48k
    if (input_bits >= (9 * 5 * 5))
56
2
        return Error::from_string_literal("Encoded model properties value is larger than the highest possible value");
57
58
4.48k
    u8 literal_context_bits = input_bits % 9;
59
4.48k
    input_bits /= 9;
60
4.48k
    VERIFY(literal_context_bits >= 0 && literal_context_bits <= 8);
61
62
4.48k
    u8 literal_position_bits = input_bits % 5;
63
4.48k
    input_bits /= 5;
64
4.48k
    VERIFY(literal_position_bits >= 0 && literal_position_bits <= 4);
65
66
4.48k
    u8 position_bits = input_bits;
67
4.48k
    VERIFY(position_bits >= 0 && position_bits <= 4);
68
69
4.48k
    return LzmaModelProperties {
70
4.48k
        .literal_context_bits = literal_context_bits,
71
4.48k
        .literal_position_bits = literal_position_bits,
72
4.48k
        .position_bits = position_bits,
73
4.48k
    };
74
4.48k
}
75
76
ErrorOr<u8> LzmaHeader::encode_model_properties(LzmaModelProperties const& model_properties)
77
2.81k
{
78
2.81k
    if (model_properties.literal_context_bits > 8)
79
0
        return Error::from_string_literal("LZMA literal context bits are too large to encode");
80
81
2.81k
    if (model_properties.literal_position_bits > 4)
82
0
        return Error::from_string_literal("LZMA literal position bits are too large to encode");
83
84
2.81k
    if (model_properties.position_bits > 4)
85
0
        return Error::from_string_literal("LZMA position bits are too large to encode");
86
87
2.81k
    return (model_properties.position_bits * 5 + model_properties.literal_position_bits) * 9 + model_properties.literal_context_bits;
88
2.81k
}
89
90
ErrorOr<LzmaDecompressorOptions> LzmaHeader::as_decompressor_options() const
91
4.48k
{
92
4.48k
    auto model_properties = TRY(decode_model_properties(encoded_model_properties));
93
94
4.48k
    return Compress::LzmaDecompressorOptions {
95
4.48k
        .literal_context_bits = model_properties.literal_context_bits,
96
4.48k
        .literal_position_bits = model_properties.literal_position_bits,
97
4.48k
        .position_bits = model_properties.position_bits,
98
4.48k
        .dictionary_size = dictionary_size(),
99
4.48k
        .uncompressed_size = uncompressed_size(),
100
4.48k
        .reject_end_of_stream_marker = false,
101
4.48k
    };
102
4.48k
}
103
104
ErrorOr<LzmaHeader> LzmaHeader::from_compressor_options(LzmaCompressorOptions const& options)
105
2.81k
{
106
2.81k
    auto encoded_model_properties = TRY(encode_model_properties({
107
2.81k
        .literal_context_bits = options.literal_context_bits,
108
2.81k
        .literal_position_bits = options.literal_position_bits,
109
2.81k
        .position_bits = options.position_bits,
110
2.81k
    }));
111
112
2.81k
    return LzmaHeader {
113
2.81k
        .encoded_model_properties = encoded_model_properties,
114
2.81k
        .unchecked_dictionary_size = options.dictionary_size,
115
2.81k
        .encoded_uncompressed_size = options.uncompressed_size.value_or(placeholder_for_unknown_uncompressed_size),
116
2.81k
    };
117
2.81k
}
118
119
void LzmaState::initialize_to_default_probability(Span<Probability> span)
120
642k
{
121
642k
    for (auto& entry : span)
122
380M
        entry = default_probability;
123
642k
}
124
125
ErrorOr<NonnullOwnPtr<LzmaDecompressor>> LzmaDecompressor::create_from_container(MaybeOwned<Stream> stream, Optional<MaybeOwned<CircularBuffer>> dictionary)
126
4.49k
{
127
4.49k
    auto header = TRY(stream->read_value<LzmaHeader>());
128
129
4.48k
    return TRY(LzmaDecompressor::create_from_raw_stream(move(stream), TRY(header.as_decompressor_options()), move(dictionary)));
130
4.48k
}
131
132
ErrorOr<NonnullOwnPtr<LzmaDecompressor>> LzmaDecompressor::create_from_raw_stream(MaybeOwned<Stream> stream, LzmaDecompressorOptions const& options, Optional<MaybeOwned<CircularBuffer>> dictionary)
133
4.48k
{
134
4.48k
    if (!dictionary.has_value()) {
135
4.48k
        auto new_dictionary = TRY(CircularBuffer::create_empty(options.dictionary_size));
136
4.48k
        dictionary = TRY(try_make<CircularBuffer>(move(new_dictionary)));
137
4.48k
    }
138
139
4.48k
    VERIFY((*dictionary)->capacity() >= options.dictionary_size);
140
141
    // "The LZMA Decoder uses (1 << (lc + lp)) tables with CProb values, where each table contains 0x300 CProb values."
142
4.48k
    auto literal_probabilities = TRY(FixedArray<Probability>::create(literal_probability_table_size * (1 << (options.literal_context_bits + options.literal_position_bits))));
143
144
4.48k
    auto decompressor = TRY(adopt_nonnull_own_or_enomem(new (nothrow) LzmaDecompressor(move(stream), options, dictionary.release_value(), move(literal_probabilities))));
145
146
4.48k
    TRY(decompressor->initialize_range_decoder());
147
148
4.34k
    return decompressor;
149
4.48k
}
150
151
LzmaState::LzmaState(FixedArray<Probability> literal_probabilities)
152
7.29k
    : m_literal_probabilities(move(literal_probabilities))
153
7.29k
{
154
7.29k
    initialize_to_default_probability(m_literal_probabilities.span());
155
156
7.29k
    for (auto& array : m_length_to_position_states)
157
29.1k
        initialize_to_default_probability(array);
158
159
7.29k
    for (auto& array : m_binary_tree_distance_probabilities)
160
72.9k
        initialize_to_default_probability(array);
161
162
7.29k
    initialize_to_default_probability(m_alignment_bit_probabilities);
163
164
7.29k
    initialize_to_default_probability(m_is_match_probabilities);
165
7.29k
    initialize_to_default_probability(m_is_rep_probabilities);
166
7.29k
    initialize_to_default_probability(m_is_rep_g0_probabilities);
167
7.29k
    initialize_to_default_probability(m_is_rep_g1_probabilities);
168
7.29k
    initialize_to_default_probability(m_is_rep_g2_probabilities);
169
7.29k
    initialize_to_default_probability(m_is_rep0_long_probabilities);
170
7.29k
}
171
172
LzmaDecompressor::LzmaDecompressor(MaybeOwned<Stream> stream, LzmaDecompressorOptions options, MaybeOwned<CircularBuffer> dictionary, FixedArray<Probability> literal_probabilities)
173
4.48k
    : LzmaState(move(literal_probabilities))
174
4.48k
    , m_stream(move(stream))
175
4.48k
    , m_options(move(options))
176
4.48k
    , m_dictionary(move(dictionary))
177
4.48k
{
178
4.48k
}
179
180
bool LzmaDecompressor::is_range_decoder_in_clean_state() const
181
2.98k
{
182
2.98k
    return m_range_decoder_code == 0;
183
2.98k
}
184
185
bool LzmaDecompressor::has_reached_expected_data_size() const
186
42.9M
{
187
42.9M
    if (!m_options.uncompressed_size.has_value())
188
10.3M
        return false;
189
190
32.5M
    return m_total_processed_bytes >= m_options.uncompressed_size.value();
191
42.9M
}
192
193
ErrorOr<void> LzmaDecompressor::initialize_range_decoder()
194
4.48k
{
195
    // "The LZMA Encoder always writes ZERO in initial byte of compressed stream.
196
    //  That scheme allows to simplify the code of the Range Encoder in the
197
    //  LZMA Encoder. If initial byte is not equal to ZERO, the LZMA Decoder must
198
    //  stop decoding and report error."
199
4.48k
    {
200
4.48k
        auto byte = TRY(m_stream->read_value<u8>());
201
4.36k
        if (byte != 0)
202
17
            return Error::from_string_literal("Initial byte of data stream is not zero");
203
4.36k
    }
204
205
    // Read the initial bytes into the range decoder.
206
4.34k
    m_range_decoder_code = 0;
207
21.7k
    for (size_t i = 0; i < 4; i++) {
208
17.3k
        auto byte = TRY(m_stream->read_value<u8>());
209
17.3k
        m_range_decoder_code = m_range_decoder_code << 8 | byte;
210
17.3k
    }
211
212
4.34k
    m_range_decoder_range = 0xFFFFFFFF;
213
214
4.34k
    return {};
215
4.34k
}
216
217
ErrorOr<void> LzmaDecompressor::append_input_stream(MaybeOwned<Stream> stream, Optional<u64> uncompressed_size)
218
0
{
219
0
    m_stream = move(stream);
220
221
0
    TRY(initialize_range_decoder());
222
223
0
    if (m_options.uncompressed_size.has_value() != uncompressed_size.has_value())
224
0
        return Error::from_string_literal("Appending LZMA streams with mismatching uncompressed size status");
225
226
0
    if (uncompressed_size.has_value())
227
0
        *m_options.uncompressed_size += *uncompressed_size;
228
229
0
    return {};
230
0
}
231
232
ErrorOr<void> LzmaDecompressor::normalize_range_decoder()
233
256M
{
234
    // "The Normalize() function keeps the "Range" value in described range."
235
236
256M
    if (m_range_decoder_range >= minimum_range_value)
237
252M
        return {};
238
239
4.00M
    m_range_decoder_range <<= 8;
240
4.00M
    m_range_decoder_code <<= 8;
241
242
4.00M
    m_range_decoder_code |= TRY(m_stream->read_value<u8>());
243
244
4.00M
    VERIFY(m_range_decoder_range >= minimum_range_value);
245
246
4.00M
    return {};
247
4.00M
}
248
249
ErrorOr<void> LzmaCompressor::shift_range_encoder()
250
3.39M
{
251
3.39M
    if ((m_range_encoder_code >> 32) == 0x01) {
252
        // If there is an overflow, we can finalize the chain we were previously building.
253
        // This includes incrementing both the cached byte and all the 0xFF bytes that we generate.
254
1.17M
        VERIFY(m_range_encoder_cached_byte != 0xFF);
255
2.34M
        TRY(m_stream->write_value<u8>(m_range_encoder_cached_byte + 1));
256
2.34M
        for (size_t i = 0; i < m_range_encoder_ff_chain_length; i++)
257
4.64k
            TRY(m_stream->write_value<u8>(0x00));
258
2.34M
        m_range_encoder_ff_chain_length = 0;
259
1.17M
        m_range_encoder_cached_byte = (m_range_encoder_code >> 24);
260
2.22M
    } else if ((m_range_encoder_code >> 24) == 0xFF) {
261
        // If the byte to flush is 0xFF, it can potentially propagate an overflow and needs to be added to the chain.
262
17.1k
        m_range_encoder_ff_chain_length++;
263
2.20M
    } else {
264
        // If the byte to flush isn't 0xFF, any future overflows will not be propagated beyond this point,
265
        // so we can be sure that the built chain doesn't change anymore.
266
2.20M
        TRY(m_stream->write_value<u8>(m_range_encoder_cached_byte));
267
2.21M
        for (size_t i = 0; i < m_range_encoder_ff_chain_length; i++)
268
12.4k
            TRY(m_stream->write_value<u8>(0xFF));
269
2.20M
        m_range_encoder_ff_chain_length = 0;
270
2.20M
        m_range_encoder_cached_byte = (m_range_encoder_code >> 24);
271
2.20M
    }
272
273
    // In all three cases we now recorded the highest byte in some way, so we can shift it away and shift in a null byte as the lowest byte.
274
3.39M
    m_range_encoder_range <<= 8;
275
3.39M
    m_range_encoder_code <<= 8;
276
277
    // Since we are working with a 64-bit code, we need to limit it to 32 bits artificially.
278
3.39M
    m_range_encoder_code &= 0xFFFFFFFF;
279
280
3.39M
    return {};
281
3.39M
}
282
283
ErrorOr<void> LzmaCompressor::normalize_range_encoder()
284
55.4M
{
285
55.4M
    u64 const maximum_range_value = m_range_encoder_code + m_range_encoder_range;
286
287
    // Logically, we should only ever build up an overflow that is smaller than or equal to 0x01.
288
55.4M
    VERIFY((maximum_range_value >> 32) <= 0x01);
289
290
55.4M
    if (m_range_encoder_range >= minimum_range_value)
291
52.0M
        return {};
292
293
55.4M
    TRY(shift_range_encoder());
294
295
6.78M
    VERIFY(m_range_encoder_range >= minimum_range_value);
296
297
3.39M
    return {};
298
6.78M
}
299
300
ErrorOr<u8> LzmaDecompressor::decode_direct_bit()
301
6.72M
{
302
6.72M
    dbgln_if(LZMA_DEBUG, "Decoding direct bit {} with code = {:#x}, range = {:#x}", 1 - ((m_range_decoder_code - (m_range_decoder_range >> 1)) >> 31), m_range_decoder_code, m_range_decoder_range);
303
304
6.72M
    m_range_decoder_range >>= 1;
305
6.72M
    m_range_decoder_code -= m_range_decoder_range;
306
307
6.72M
    u32 temp = 0 - (m_range_decoder_code >> 31);
308
309
6.72M
    m_range_decoder_code += m_range_decoder_range & temp;
310
311
6.72M
    if (m_range_decoder_code == m_range_decoder_range)
312
1
        return Error::from_string_literal("Reached an invalid state while decoding LZMA stream");
313
314
6.72M
    TRY(normalize_range_decoder());
315
316
6.72M
    return temp + 1;
317
6.72M
}
318
319
ErrorOr<void> LzmaCompressor::encode_direct_bit(u8 value)
320
6.70M
{
321
6.70M
    dbgln_if(LZMA_DEBUG, "Encoding direct bit {} with code = {:#x}, range = {:#x}", value, m_range_encoder_code, m_range_encoder_range);
322
323
6.70M
    m_range_encoder_range >>= 1;
324
325
6.70M
    if (value != 0)
326
3.30M
        m_range_encoder_code += m_range_encoder_range;
327
328
6.70M
    TRY(normalize_range_encoder());
329
330
6.70M
    return {};
331
6.70M
}
332
333
ErrorOr<u8> LzmaDecompressor::decode_bit_with_probability(Probability& probability)
334
250M
{
335
    // "The LZMA decoder provides the pointer to CProb variable that contains
336
    //  information about estimated probability for symbol 0 and the Range Decoder
337
    //  updates that CProb variable after decoding."
338
339
250M
    u32 bound = (m_range_decoder_range >> probability_bit_count) * probability;
340
341
250M
    dbgln_if(LZMA_DEBUG, "Decoding bit {} with probability = {:#x}, bound = {:#x}, code = {:#x}, range = {:#x}", m_range_decoder_code < bound ? 0 : 1, probability, bound, m_range_decoder_code, m_range_decoder_range);
342
343
250M
    if (m_range_decoder_code < bound) {
344
78.9M
        probability += ((1 << probability_bit_count) - probability) >> probability_shift_width;
345
78.9M
        m_range_decoder_range = bound;
346
78.9M
        TRY(normalize_range_decoder());
347
78.9M
        return 0;
348
171M
    } else {
349
171M
        probability -= probability >> probability_shift_width;
350
171M
        m_range_decoder_code -= bound;
351
171M
        m_range_decoder_range -= bound;
352
171M
        TRY(normalize_range_decoder());
353
171M
        return 1;
354
171M
    }
355
250M
}
356
357
ErrorOr<void> LzmaCompressor::encode_bit_with_probability(Probability& probability, u8 value)
358
48.7M
{
359
48.7M
    u32 bound = (m_range_encoder_range >> probability_bit_count) * probability;
360
361
48.7M
    dbgln_if(LZMA_DEBUG, "Encoding bit {} with probability = {:#x}, bound = {:#x}, code = {:#x}, range = {:#x}", value, probability, bound, m_range_encoder_code, m_range_encoder_range);
362
363
48.7M
    if (value == 0) {
364
25.8M
        probability += ((1 << probability_bit_count) - probability) >> probability_shift_width;
365
25.8M
        m_range_encoder_range = bound;
366
25.8M
    } else {
367
22.9M
        probability -= probability >> probability_shift_width;
368
22.9M
        m_range_encoder_code += bound;
369
22.9M
        m_range_encoder_range -= bound;
370
22.9M
    }
371
372
48.7M
    TRY(normalize_range_encoder());
373
48.7M
    return {};
374
48.7M
}
375
376
ErrorOr<u16> LzmaDecompressor::decode_symbol_using_bit_tree(size_t bit_count, Span<Probability> probability_tree)
377
14.6M
{
378
14.6M
    VERIFY(bit_count <= sizeof(u16) * 8);
379
14.6M
    VERIFY(probability_tree.size() >= 1ul << bit_count);
380
381
    // This has been modified from the reference implementation to unlink the result and the tree index,
382
    // which should allow for better readability.
383
384
14.6M
    u16 result = 0;
385
14.6M
    size_t tree_index = 1;
386
387
113M
    for (size_t i = 0; i < bit_count; i++) {
388
98.3M
        u16 next_bit = TRY(decode_bit_with_probability(probability_tree[tree_index]));
389
98.3M
        result = (result << 1) | next_bit;
390
98.3M
        tree_index = (tree_index << 1) | next_bit;
391
98.3M
    }
392
393
14.6M
    dbgln_if(LZMA_DEBUG, "Decoded value {:#x} with {} bits using bit tree", result, bit_count);
394
395
14.6M
    return result;
396
14.6M
}
397
398
ErrorOr<void> LzmaCompressor::encode_symbol_using_bit_tree(size_t bit_count, Span<Probability> probability_tree, u16 value)
399
4.77M
{
400
4.77M
    VERIFY(bit_count <= sizeof(u16) * 8);
401
4.77M
    VERIFY(probability_tree.size() >= 1ul << bit_count);
402
4.77M
    VERIFY(value <= (1 << bit_count) - 1);
403
404
4.77M
    auto original_value = value;
405
406
    // Shift value to make the first sent byte the most significant bit. This makes the shifting logic a lot easier to read.
407
4.77M
    value <<= sizeof(u16) * 8 - bit_count;
408
409
4.77M
    size_t tree_index = 1;
410
411
24.1M
    for (size_t i = 0; i < bit_count; i++) {
412
19.3M
        u8 const next_bit = (value & 0x8000) >> (sizeof(u16) * 8 - 1);
413
19.3M
        value <<= 1;
414
19.3M
        TRY(encode_bit_with_probability(probability_tree[tree_index], next_bit));
415
19.3M
        tree_index = (tree_index << 1) | next_bit;
416
19.3M
    }
417
418
4.77M
    dbgln_if(LZMA_DEBUG, "Encoded value {:#x} with {} bits using bit tree", original_value, bit_count);
419
420
4.77M
    return {};
421
4.77M
}
422
423
ErrorOr<u16> LzmaDecompressor::decode_symbol_using_reverse_bit_tree(size_t bit_count, Span<Probability> probability_tree)
424
1.09M
{
425
1.09M
    VERIFY(bit_count <= sizeof(u16) * 8);
426
1.09M
    VERIFY(probability_tree.size() >= 1ul << bit_count);
427
428
1.09M
    u16 result = 0;
429
1.09M
    size_t tree_index = 1;
430
431
5.42M
    for (size_t i = 0; i < bit_count; i++) {
432
4.33M
        u16 next_bit = TRY(decode_bit_with_probability(probability_tree[tree_index]));
433
4.33M
        result |= next_bit << i;
434
4.33M
        tree_index = (tree_index << 1) | next_bit;
435
4.33M
    }
436
437
1.09M
    dbgln_if(LZMA_DEBUG, "Decoded value {:#x} with {} bits using reverse bit tree", result, bit_count);
438
439
1.09M
    return result;
440
1.09M
}
441
442
ErrorOr<void> LzmaCompressor::encode_symbol_using_reverse_bit_tree(size_t bit_count, Span<Probability> probability_tree, u16 value)
443
1.08M
{
444
1.08M
    VERIFY(bit_count <= sizeof(u16) * 8);
445
1.08M
    VERIFY(probability_tree.size() >= 1ul << bit_count);
446
1.08M
    VERIFY(value <= (1 << bit_count) - 1);
447
448
1.08M
    auto original_value = value;
449
450
1.08M
    size_t tree_index = 1;
451
452
5.40M
    for (size_t i = 0; i < bit_count; i++) {
453
4.31M
        u8 const next_bit = value & 1;
454
4.31M
        value >>= 1;
455
4.31M
        TRY(encode_bit_with_probability(probability_tree[tree_index], next_bit));
456
4.31M
        tree_index = (tree_index << 1) | next_bit;
457
4.31M
    }
458
459
1.08M
    dbgln_if(LZMA_DEBUG, "Encoded value {:#x} with {} bits using reverse bit tree", original_value, bit_count);
460
461
1.08M
    return {};
462
1.08M
}
463
464
ErrorOr<void> LzmaDecompressor::decode_literal_to_output_buffer()
465
6.83M
{
466
6.83M
    u8 previous_byte = 0;
467
6.83M
    if (m_dictionary->seekback_limit() > 0) {
468
6.83M
        auto read_bytes = MUST(m_dictionary->read_with_seekback({ &previous_byte, sizeof(previous_byte) }, 1));
469
6.83M
        VERIFY(read_bytes.size() == sizeof(previous_byte));
470
6.83M
    }
471
472
    // "To select the table for decoding it uses the context that consists of
473
    //  (lc) high bits from previous literal and (lp) low bits from value that
474
    //  represents current position in outputStream."
475
6.83M
    u16 literal_state_bits_from_position = m_total_processed_bytes & ((1 << m_options.literal_position_bits) - 1);
476
6.83M
    u16 literal_state_bits_from_output = previous_byte >> (8 - m_options.literal_context_bits);
477
6.83M
    u16 literal_state = literal_state_bits_from_position << m_options.literal_context_bits | literal_state_bits_from_output;
478
479
6.83M
    Span<Probability> selected_probability_table = m_literal_probabilities.span().slice(literal_probability_table_size * literal_state, literal_probability_table_size);
480
481
    // The result is defined as u16 here and initialized to 1, but we will cut off the top bits before queueing them into the output buffer.
482
    // The top bit is only used to track how much we have decoded already, and to select the correct probability table.
483
6.83M
    u16 result = 1;
484
485
    // "If (State > 7), the Literal Decoder also uses "matchByte" that represents
486
    //  the byte in OutputStream at position the is the DISTANCE bytes before
487
    //  current position, where the DISTANCE is the distance in DISTANCE-LENGTH pair
488
    //  of latest decoded match."
489
    // Note: The specification says `(State > 7)`, but the reference implementation does `(State >= 7)`, which is a mismatch.
490
    //       Testing `(State > 7)` with actual test files yields errors, so the reference implementation appears to be the correct one.
491
6.83M
    if (m_state >= 7) {
492
169k
        u8 matched_byte = 0;
493
169k
        auto read_bytes = TRY(m_dictionary->read_with_seekback({ &matched_byte, sizeof(matched_byte) }, current_repetition_offset()));
494
169k
        VERIFY(read_bytes.size() == sizeof(matched_byte));
495
496
169k
        dbgln_if(LZMA_DEBUG, "Decoding literal using match byte {:#x}", matched_byte);
497
498
703k
        do {
499
703k
            u8 match_bit = (matched_byte >> 7) & 1;
500
703k
            matched_byte <<= 1;
501
502
703k
            u8 decoded_bit = TRY(decode_bit_with_probability(selected_probability_table[((1 + match_bit) << 8) + result]));
503
703k
            result = result << 1 | decoded_bit;
504
505
703k
            if (match_bit != decoded_bit)
506
165k
                break;
507
703k
        } while (result < 0x100);
508
169k
    }
509
510
60.8M
    while (result < 0x100)
511
53.9M
        result = (result << 1) | TRY(decode_bit_with_probability(selected_probability_table[result]));
512
513
6.83M
    u8 actual_result = result - 0x100;
514
515
6.83M
    size_t written_bytes = m_dictionary->write({ &actual_result, sizeof(actual_result) });
516
6.83M
    VERIFY(written_bytes == sizeof(actual_result));
517
6.83M
    m_total_processed_bytes += sizeof(actual_result);
518
519
6.83M
    dbgln_if(LZMA_DEBUG, "Decoded literal {:#x} in state {} using literal state {:#x} (previous byte is {:#x})", actual_result, m_state, literal_state, previous_byte);
520
521
6.83M
    return {};
522
6.83M
}
523
524
ErrorOr<void> LzmaCompressor::encode_literal(u8 literal)
525
933k
{
526
    // This function largely mirrors `decode_literal_to_output_buffer`, so specification comments have been omitted.
527
528
933k
    TRY(encode_match_type(MatchType::Literal));
529
530
    // Note: We have already read the next byte from the input buffer, so it's now in the seekback buffer, shifting all seekback offsets by one.
531
933k
    u8 previous_byte = 0;
532
933k
    if (m_dictionary->seekback_limit() - m_dictionary->used_space() > 1) {
533
930k
        auto read_bytes = MUST(m_dictionary->read_with_seekback({ &previous_byte, sizeof(previous_byte) }, 2 + m_dictionary->used_space()));
534
930k
        VERIFY(read_bytes.size() == sizeof(previous_byte));
535
930k
    }
536
933k
    u16 const literal_state_bits_from_position = m_total_processed_bytes & ((1 << m_options.literal_position_bits) - 1);
537
933k
    u16 const literal_state_bits_from_output = previous_byte >> (8 - m_options.literal_context_bits);
538
933k
    u16 const literal_state = literal_state_bits_from_position << m_options.literal_context_bits | literal_state_bits_from_output;
539
540
933k
    Span<Probability> selected_probability_table = m_literal_probabilities.span().slice(literal_probability_table_size * literal_state, literal_probability_table_size);
541
542
933k
    auto original_literal = literal;
543
933k
    u16 result = 1;
544
545
933k
    if (m_state >= 7) {
546
161k
        u8 matched_byte = 0;
547
161k
        auto read_bytes = TRY(m_dictionary->read_with_seekback({ &matched_byte, sizeof(matched_byte) }, current_repetition_offset() + m_dictionary->used_space() + 1));
548
161k
        VERIFY(read_bytes.size() == sizeof(matched_byte));
549
550
161k
        dbgln_if(LZMA_DEBUG, "Encoding literal using match byte {:#x}", matched_byte);
551
552
683k
        do {
553
683k
            u8 const match_bit = (matched_byte >> 7) & 1;
554
683k
            matched_byte <<= 1;
555
556
683k
            u8 const encoded_bit = (literal & 0x80) >> 7;
557
683k
            literal <<= 1;
558
559
683k
            TRY(encode_bit_with_probability(selected_probability_table[((1 + match_bit) << 8) + result], encoded_bit));
560
683k
            result = result << 1 | encoded_bit;
561
562
683k
            if (match_bit != encoded_bit)
563
158k
                break;
564
683k
        } while (result < 0x100);
565
161k
    }
566
567
7.71M
    while (result < 0x100) {
568
6.78M
        u8 const encoded_bit = (literal & 0x80) >> 7;
569
6.78M
        literal <<= 1;
570
571
6.78M
        TRY(encode_bit_with_probability(selected_probability_table[result], encoded_bit));
572
573
6.78M
        result = (result << 1) | encoded_bit;
574
6.78M
    }
575
576
933k
    m_total_processed_bytes += sizeof(literal);
577
578
933k
    dbgln_if(LZMA_DEBUG, "Encoded literal {:#x} in state {} using literal state {:#x} (previous byte is {:#x})", original_literal, m_state, literal_state, previous_byte);
579
580
933k
    update_state_after_literal();
581
582
933k
    return {};
583
933k
}
584
585
ErrorOr<void> LzmaCompressor::encode_existing_match(size_t real_distance, size_t real_length)
586
2.58M
{
587
2.58M
    VERIFY(real_distance >= normalized_to_real_match_distance_offset);
588
2.58M
    u32 const normalized_distance = real_distance - normalized_to_real_match_distance_offset;
589
590
2.58M
    VERIFY(real_length >= normalized_to_real_match_length_offset);
591
2.58M
    u16 const normalized_length = real_length - normalized_to_real_match_length_offset;
592
593
2.58M
    if (normalized_distance == m_rep0) {
594
2.46M
        TRY(encode_match_type(MatchType::RepMatch0));
595
2.46M
    } else if (normalized_distance == m_rep1) {
596
66.0k
        TRY(encode_match_type(MatchType::RepMatch1));
597
598
66.0k
        u32 const distance = m_rep1;
599
66.0k
        m_rep1 = m_rep0;
600
66.0k
        m_rep0 = distance;
601
66.0k
    } else if (normalized_distance == m_rep2) {
602
33.2k
        TRY(encode_match_type(MatchType::RepMatch2));
603
604
33.2k
        u32 const distance = m_rep2;
605
33.2k
        m_rep2 = m_rep1;
606
33.2k
        m_rep1 = m_rep0;
607
33.2k
        m_rep0 = distance;
608
33.2k
    } else if (normalized_distance == m_rep3) {
609
22.6k
        TRY(encode_match_type(MatchType::RepMatch3));
610
611
22.6k
        u32 const distance = m_rep3;
612
22.6k
        m_rep3 = m_rep2;
613
22.6k
        m_rep2 = m_rep1;
614
22.6k
        m_rep1 = m_rep0;
615
22.6k
        m_rep0 = distance;
616
22.6k
    } else {
617
0
        VERIFY_NOT_REACHED();
618
0
    }
619
620
5.16M
    TRY(encode_normalized_match_length(m_rep_length_coder, normalized_length));
621
5.16M
    update_state_after_rep();
622
5.16M
    MUST(m_dictionary->discard(real_length));
623
2.58M
    m_total_processed_bytes += real_length;
624
625
2.58M
    return {};
626
5.16M
}
627
628
ErrorOr<void> LzmaCompressor::encode_new_match(size_t real_distance, size_t real_length)
629
1.09M
{
630
1.09M
    VERIFY(real_distance >= normalized_to_real_match_distance_offset);
631
1.09M
    u32 const normalized_distance = real_distance - normalized_to_real_match_distance_offset;
632
633
1.09M
    VERIFY(real_length >= normalized_to_real_match_length_offset);
634
1.09M
    u16 const normalized_length = real_length - normalized_to_real_match_length_offset;
635
636
1.09M
    TRY(encode_normalized_simple_match(normalized_distance, normalized_length));
637
638
1.09M
    MUST(m_dictionary->discard(real_length));
639
1.09M
    m_total_processed_bytes += real_length;
640
641
1.09M
    return {};
642
1.09M
}
643
644
ErrorOr<void> LzmaCompressor::encode_normalized_simple_match(u32 normalized_distance, u16 normalized_length)
645
1.09M
{
646
1.09M
    TRY(encode_match_type(MatchType::SimpleMatch));
647
648
1.09M
    m_rep3 = m_rep2;
649
1.09M
    m_rep2 = m_rep1;
650
1.09M
    m_rep1 = m_rep0;
651
652
1.09M
    TRY(encode_normalized_match_length(m_length_coder, normalized_length));
653
654
1.09M
    update_state_after_match();
655
656
1.09M
    TRY(encode_normalized_match_distance(normalized_length, normalized_distance));
657
1.09M
    m_rep0 = normalized_distance;
658
659
1.09M
    return {};
660
1.09M
}
661
662
LzmaState::LzmaLengthCoderState::LzmaLengthCoderState()
663
14.5k
{
664
14.5k
    for (auto& array : m_low_length_probabilities)
665
233k
        initialize_to_default_probability(array);
666
667
14.5k
    for (auto& array : m_medium_length_probabilities)
668
233k
        initialize_to_default_probability(array);
669
670
14.5k
    initialize_to_default_probability(m_high_length_probabilities);
671
14.5k
}
672
673
ErrorOr<u16> LzmaDecompressor::decode_normalized_match_length(LzmaLengthCoderState& length_decoder_state)
674
13.5M
{
675
    // "LZMA uses "posState" value as context to select the binary tree
676
    //  from LowCoder and MidCoder binary tree arrays:"
677
13.5M
    u16 position_state = m_total_processed_bytes & ((1 << m_options.position_bits) - 1);
678
679
    // "The following scheme is used for the match length encoding:
680
    //
681
    //   Binary encoding    Binary Tree structure    Zero-based match length
682
    //   sequence                                    (binary + decimal):
683
    //
684
    //   0 xxx              LowCoder[posState]       xxx
685
27.1M
    if (TRY(decode_bit_with_probability(length_decoder_state.m_first_choice_probability)) == 0)
686
13.5M
        return TRY(decode_symbol_using_bit_tree(3, length_decoder_state.m_low_length_probabilities[position_state].span()));
687
688
    //   1 0 yyy            MidCoder[posState]       yyy + 8
689
20.5M
    if (TRY(decode_bit_with_probability(length_decoder_state.m_second_choice_probability)) == 0)
690
72.7k
        return TRY(decode_symbol_using_bit_tree(3, length_decoder_state.m_medium_length_probabilities[position_state].span())) + 8;
691
692
    //   1 1 zzzzzzzz       HighCoder                zzzzzzzz + 16"
693
10.2M
    return TRY(decode_symbol_using_bit_tree(8, length_decoder_state.m_high_length_probabilities.span())) + 16;
694
10.2M
}
695
696
ErrorOr<void> LzmaCompressor::encode_normalized_match_length(LzmaLengthCoderState& length_coder_state, u16 normalized_length)
697
3.68M
{
698
3.68M
    u16 const position_state = m_total_processed_bytes & ((1 << m_options.position_bits) - 1);
699
700
3.68M
    if (normalized_length < 8) {
701
3.25M
        TRY(encode_bit_with_probability(length_coder_state.m_first_choice_probability, 0));
702
3.25M
        TRY(encode_symbol_using_bit_tree(3, length_coder_state.m_low_length_probabilities[position_state].span(), normalized_length));
703
3.25M
        return {};
704
3.25M
    }
705
706
3.68M
    TRY(encode_bit_with_probability(length_coder_state.m_first_choice_probability, 1));
707
708
841k
    if (normalized_length < 16) {
709
68.7k
        TRY(encode_bit_with_probability(length_coder_state.m_second_choice_probability, 0));
710
68.7k
        TRY(encode_symbol_using_bit_tree(3, length_coder_state.m_medium_length_probabilities[position_state].span(), normalized_length - 8));
711
68.7k
        return {};
712
68.7k
    }
713
714
704k
    TRY(encode_bit_with_probability(length_coder_state.m_second_choice_probability, 1));
715
704k
    TRY(encode_symbol_using_bit_tree(8, length_coder_state.m_high_length_probabilities.span(), normalized_length - 16));
716
352k
    return {};
717
704k
}
718
719
ErrorOr<u32> LzmaDecompressor::decode_normalized_match_distance(u16 normalized_match_length)
720
1.10M
{
721
    // "LZMA uses normalized match length (zero-based length)
722
    //  to calculate the context state "lenState" do decode the distance value."
723
1.10M
    u16 length_state = min(normalized_match_length, number_of_length_to_position_states - 1);
724
725
    // "At first stage the distance decoder decodes 6-bit "posSlot" value with bit
726
    //  tree decoder from PosSlotDecoder array."
727
1.10M
    u16 position_slot = TRY(decode_symbol_using_bit_tree(6, m_length_to_position_states[length_state].span()));
728
729
    // "The encoding scheme for distance value is shown in the following table:
730
    //
731
    //  posSlot (decimal) /
732
    //       zero-based distance (binary)
733
    //  0    0
734
    //  1    1
735
    //  2    10
736
    //  3    11
737
    //
738
    //  4    10 x
739
    //  5    11 x
740
    //  6    10 xx
741
    //  7    11 xx
742
    //  8    10 xxx
743
    //  9    11 xxx
744
    //  10    10 xxxx
745
    //  11    11 xxxx
746
    //  12    10 xxxxx
747
    //  13    11 xxxxx
748
    //
749
    //  14    10 yy zzzz
750
    //  15    11 yy zzzz
751
    //  16    10 yyy zzzz
752
    //  17    11 yyy zzzz
753
    //  ...
754
    //  62    10 yyyyyyyyyyyyyyyyyyyyyyyyyy zzzz
755
    //  63    11 yyyyyyyyyyyyyyyyyyyyyyyyyy zzzz
756
    //
757
    //  where
758
    //   "x ... x" means the sequence of binary symbols encoded with binary tree and
759
    //       "Reverse" scheme. It uses separated binary tree for each posSlot from 4 to 13.
760
    //   "y" means direct bit encoded with range coder.
761
    //   "zzzz" means the sequence of four binary symbols encoded with binary
762
    //       tree with "Reverse" scheme, where one common binary tree "AlignDecoder"
763
    //       is used for all posSlot values."
764
765
    // "If (posSlot < 4), the "dist" value is equal to posSlot value."
766
1.10M
    if (position_slot < first_position_slot_with_binary_tree_bits)
767
12.4k
        return position_slot;
768
769
    // From here on, the first bit of the distance is always set and the second bit is set if the last bit of the position slot is set.
770
1.09M
    u32 distance_prefix = ((1 << 1) | ((position_slot & 1) << 0));
771
772
    // "If (posSlot >= 4), the decoder uses "posSlot" value to calculate the value of
773
    //   the high bits of "dist" value and the number of the low bits.
774
    //   If (4 <= posSlot < kEndPosModelIndex), the decoder uses bit tree decoders.
775
    //     (one separated bit tree decoder per one posSlot value) and "Reverse" scheme."
776
1.09M
    if (position_slot < first_position_slot_with_direct_encoded_bits) {
777
98.7k
        size_t number_of_bits_to_decode = (position_slot / 2) - 1;
778
98.7k
        auto& selected_probability_tree = m_binary_tree_distance_probabilities[position_slot - first_position_slot_with_binary_tree_bits];
779
98.7k
        return (distance_prefix << number_of_bits_to_decode) | TRY(decode_symbol_using_reverse_bit_tree(number_of_bits_to_decode, selected_probability_tree));
780
98.7k
    }
781
782
    // "  if (posSlot >= kEndPosModelIndex), the middle bits are decoded as direct
783
    //     bits from RangeDecoder and the low 4 bits are decoded with a bit tree
784
    //     decoder "AlignDecoder" with "Reverse" scheme."
785
993k
    size_t number_of_direct_bits_to_decode = ((position_slot - first_position_slot_with_direct_encoded_bits) / 2) + 2;
786
7.71M
    for (size_t i = 0; i < number_of_direct_bits_to_decode; i++) {
787
6.72M
        distance_prefix = (distance_prefix << 1) | TRY(decode_direct_bit());
788
6.72M
    }
789
993k
    return (distance_prefix << number_of_alignment_bits) | TRY(decode_symbol_using_reverse_bit_tree(number_of_alignment_bits, m_alignment_bit_probabilities));
790
993k
}
791
792
ErrorOr<void> LzmaCompressor::encode_normalized_match_distance(u16 normalized_match_length, u32 normalized_match_distance)
793
1.09M
{
794
1.09M
    u16 const length_state = min(normalized_match_length, number_of_length_to_position_states - 1);
795
796
1.09M
    if (normalized_match_distance < first_position_slot_with_binary_tree_bits) {
797
        // The normalized distance gets encoded as the position slot.
798
11.3k
        TRY(encode_symbol_using_bit_tree(6, m_length_to_position_states[length_state].span(), normalized_match_distance));
799
11.3k
        return {};
800
11.3k
    }
801
802
    // Note: This has been deduced, there is no immediate relation to the decoding function.
803
1.08M
    u16 const distance_log2 = AK::log2(normalized_match_distance);
804
1.08M
    u16 number_of_distance_bits = count_required_bits(normalized_match_distance);
805
1.08M
    u16 const position_slot = (distance_log2 << 1) + ((normalized_match_distance >> (distance_log2 - 1)) & 1);
806
807
1.08M
    TRY(encode_symbol_using_bit_tree(6, m_length_to_position_states[length_state].span(), position_slot));
808
809
    // Mask off the top two bits of the value, those are already encoded by the position slot.
810
1.08M
    normalized_match_distance &= (1 << (number_of_distance_bits - 2)) - 1;
811
1.08M
    number_of_distance_bits -= 2;
812
813
1.08M
    if (position_slot < first_position_slot_with_direct_encoded_bits) {
814
        // The value gets encoded using only a reverse bit tree coder.
815
96.1k
        auto& selected_probability_tree = m_binary_tree_distance_probabilities[position_slot - first_position_slot_with_binary_tree_bits];
816
96.1k
        TRY(encode_symbol_using_reverse_bit_tree(number_of_distance_bits, selected_probability_tree, normalized_match_distance));
817
96.1k
        return {};
818
96.1k
    }
819
820
    // The value is split into direct bits (everything except the last four bits) and alignment bits (last four bits).
821
990k
    auto direct_bits = normalized_match_distance & ~((1 << number_of_alignment_bits) - 1);
822
990k
    auto const alignment_bits = normalized_match_distance & ((1 << number_of_alignment_bits) - 1);
823
824
    // Shift to-be-written direct bits to the most significant position for easier access.
825
990k
    direct_bits <<= sizeof(direct_bits) * 8 - number_of_distance_bits;
826
827
7.69M
    for (auto i = 0u; i < number_of_distance_bits - number_of_alignment_bits; i++) {
828
6.70M
        TRY(encode_direct_bit((direct_bits & 0x80000000) ? 1 : 0));
829
6.70M
        direct_bits <<= 1;
830
6.70M
    }
831
832
990k
    TRY(encode_symbol_using_reverse_bit_tree(number_of_alignment_bits, m_alignment_bit_probabilities, alignment_bits));
833
834
990k
    return {};
835
990k
}
836
837
u32 LzmaState::current_repetition_offset() const
838
15.2M
{
839
    // LZMA never needs to read at offset 0 (i.e. the actual read head of the buffer).
840
    // Instead, the values are remapped so that the rep-value n starts reading n + 1 bytes back.
841
    // The special rep-value 0xFFFFFFFF is reserved for marking the end of the stream,
842
    // so this should never overflow.
843
15.2M
    VERIFY(m_rep0 <= NumericLimits<u32>::max() - normalized_to_real_match_distance_offset);
844
15.2M
    return m_rep0 + normalized_to_real_match_distance_offset;
845
15.2M
}
846
847
void LzmaState::update_state_after_literal()
848
7.76M
{
849
7.76M
    if (m_state < 4)
850
7.30M
        m_state = 0;
851
461k
    else if (m_state < 10)
852
383k
        m_state -= 3;
853
78.1k
    else
854
78.1k
        m_state -= 6;
855
7.76M
}
856
857
void LzmaState::update_state_after_match()
858
2.20M
{
859
2.20M
    if (m_state < 7)
860
170k
        m_state = 7;
861
2.03M
    else
862
2.03M
        m_state = 10;
863
2.20M
}
864
865
void LzmaState::update_state_after_rep()
866
15.0M
{
867
15.0M
    if (m_state < 7)
868
165k
        m_state = 8;
869
14.8M
    else
870
14.8M
        m_state = 11;
871
15.0M
}
872
873
void LzmaState::update_state_after_short_rep()
874
2.84k
{
875
2.84k
    if (m_state < 7)
876
1.39k
        m_state = 9;
877
1.44k
    else
878
1.44k
        m_state = 11;
879
2.84k
}
880
881
ErrorOr<LzmaDecompressor::MatchType> LzmaDecompressor::decode_match_type()
882
20.3M
{
883
    // "The decoder calculates "state2" variable value to select exact variable from
884
    //  "IsMatch" and "IsRep0Long" arrays."
885
20.3M
    u16 position_state = m_total_processed_bytes & ((1 << m_options.position_bits) - 1);
886
20.3M
    u16 state2 = (m_state << maximum_number_of_position_bits) + position_state;
887
888
    // "The decoder uses the following code flow scheme to select exact
889
    //  type of LITERAL or MATCH:
890
    //
891
    //  IsMatch[state2] decode
892
    //   0 - the Literal"
893
40.7M
    if (TRY(decode_bit_with_probability(m_is_match_probabilities[state2])) == 0) {
894
6.83M
        dbgln_if(LZMA_DEBUG, "Decoded match type 'Literal'");
895
6.83M
        return MatchType::Literal;
896
6.83M
    }
897
898
    // " 1 - the Match
899
    //     IsRep[state] decode
900
    //       0 - Simple Match"
901
27.1M
    if (TRY(decode_bit_with_probability(m_is_rep_probabilities[m_state])) == 0) {
902
1.10M
        dbgln_if(LZMA_DEBUG, "Decoded match type 'SimpleMatch'");
903
1.10M
        return MatchType::SimpleMatch;
904
1.10M
    }
905
906
    // "     1 - Rep Match
907
    //         IsRepG0[state] decode
908
    //           0 - the distance is rep0"
909
24.9M
    if (TRY(decode_bit_with_probability(m_is_rep_g0_probabilities[m_state])) == 0) {
910
        // "       IsRep0Long[state2] decode
911
        //           0 - Short Rep Match"
912
4.93M
        if (TRY(decode_bit_with_probability(m_is_rep0_long_probabilities[state2])) == 0) {
913
2.84k
            dbgln_if(LZMA_DEBUG, "Decoded match type 'ShortRepMatch'");
914
2.84k
            return MatchType::ShortRepMatch;
915
2.84k
        }
916
917
        // "         1 - Rep Match 0"
918
2.46M
        dbgln_if(LZMA_DEBUG, "Decoded match type 'RepMatch0'");
919
2.46M
        return MatchType::RepMatch0;
920
2.46M
    }
921
922
    // "         1 -
923
    //             IsRepG1[state] decode
924
    //               0 - Rep Match 1"
925
19.9M
    if (TRY(decode_bit_with_probability(m_is_rep_g1_probabilities[m_state])) == 0) {
926
68.6k
        dbgln_if(LZMA_DEBUG, "Decoded match type 'RepMatch1'");
927
68.6k
        return MatchType::RepMatch1;
928
68.6k
    }
929
930
    // "             1 -
931
    //                 IsRepG2[state] decode
932
    //                   0 - Rep Match 2"
933
19.8M
    if (TRY(decode_bit_with_probability(m_is_rep_g2_probabilities[m_state])) == 0) {
934
34.6k
        dbgln_if(LZMA_DEBUG, "Decoded match type 'RepMatch2'");
935
34.6k
        return MatchType::RepMatch2;
936
34.6k
    }
937
938
    // "                 1 - Rep Match 3"
939
9.88M
    dbgln_if(LZMA_DEBUG, "Decoded match type 'RepMatch3'");
940
9.88M
    return MatchType::RepMatch3;
941
9.92M
}
942
943
ErrorOr<void> LzmaCompressor::encode_match_type(MatchType match_type)
944
4.61M
{
945
4.61M
    u16 position_state = m_total_processed_bytes & ((1 << m_options.position_bits) - 1);
946
4.61M
    u16 state2 = (m_state << maximum_number_of_position_bits) + position_state;
947
948
4.61M
    if (match_type == MatchType::Literal) {
949
933k
        TRY(encode_bit_with_probability(m_is_match_probabilities[state2], 0));
950
933k
        dbgln_if(LZMA_DEBUG, "Encoded match type 'Literal'");
951
933k
        return {};
952
933k
    }
953
7.36M
    TRY(encode_bit_with_probability(m_is_match_probabilities[state2], 1));
954
955
7.36M
    if (match_type == MatchType::SimpleMatch) {
956
1.09M
        TRY(encode_bit_with_probability(m_is_rep_probabilities[m_state], 0));
957
1.09M
        dbgln_if(LZMA_DEBUG, "Encoded match type 'SimpleMatch'");
958
1.09M
        return {};
959
1.09M
    }
960
5.16M
    TRY(encode_bit_with_probability(m_is_rep_probabilities[m_state], 1));
961
962
5.16M
    if (match_type == MatchType::ShortRepMatch || match_type == MatchType::RepMatch0) {
963
2.46M
        TRY(encode_bit_with_probability(m_is_rep_g0_probabilities[m_state], 0));
964
2.46M
        TRY(encode_bit_with_probability(m_is_rep0_long_probabilities[state2], match_type == MatchType::RepMatch0));
965
        if constexpr (LZMA_DEBUG) {
966
            if (match_type == RepMatch0)
967
                dbgln("Encoded match type 'RepMatch0'");
968
            else
969
                dbgln("Encoded match type 'ShortRepMatch'");
970
        }
971
2.46M
        return {};
972
2.46M
    }
973
2.58M
    TRY(encode_bit_with_probability(m_is_rep_g0_probabilities[m_state], 1));
974
975
243k
    if (match_type == MatchType::RepMatch1) {
976
66.0k
        TRY(encode_bit_with_probability(m_is_rep_g1_probabilities[m_state], 0));
977
66.0k
        dbgln_if(LZMA_DEBUG, "Encoded match type 'RepMatch1'");
978
66.0k
        return {};
979
66.0k
    }
980
121k
    TRY(encode_bit_with_probability(m_is_rep_g1_probabilities[m_state], 1));
981
982
111k
    if (match_type == MatchType::RepMatch2) {
983
33.2k
        TRY(encode_bit_with_probability(m_is_rep_g2_probabilities[m_state], 0));
984
33.2k
        dbgln_if(LZMA_DEBUG, "Encoded match type 'RepMatch2'");
985
33.2k
        return {};
986
33.2k
    }
987
55.8k
    TRY(encode_bit_with_probability(m_is_rep_g2_probabilities[m_state], 1));
988
22.6k
    dbgln_if(LZMA_DEBUG, "Encoded match type 'RepMatch3'");
989
22.6k
    return {};
990
22.6k
}
991
992
ErrorOr<void> LzmaCompressor::encode_once()
993
4.61M
{
994
    // Check if any of our existing match distances are currently usable.
995
4.61M
    Vector<size_t> const existing_distances {
996
4.61M
        m_rep0 + normalized_to_real_match_distance_offset,
997
4.61M
        m_rep1 + normalized_to_real_match_distance_offset,
998
4.61M
        m_rep2 + normalized_to_real_match_distance_offset,
999
4.61M
        m_rep3 + normalized_to_real_match_distance_offset,
1000
4.61M
    };
1001
4.61M
    auto existing_distance_result = m_dictionary->find_copy_in_seekback(existing_distances, m_dictionary->used_space(), normalized_to_real_match_length_offset);
1002
1003
4.61M
    if (existing_distance_result.has_value()) {
1004
2.58M
        auto selected_match = existing_distance_result.release_value();
1005
2.58M
        TRY(encode_existing_match(selected_match.distance, selected_match.length));
1006
2.58M
        return {};
1007
2.58M
    }
1008
1009
    // If we weren't able to find any viable existing offsets, we now have to search the rest of the dictionary for possible new offsets.
1010
2.02M
    auto new_distance_result = m_dictionary->find_copy_in_seekback(m_dictionary->used_space(), normalized_to_real_match_length_offset);
1011
1012
2.02M
    if (new_distance_result.has_value()) {
1013
1.09M
        auto selected_match = new_distance_result.release_value();
1014
1.09M
        TRY(encode_new_match(selected_match.distance, selected_match.length));
1015
1.09M
        return {};
1016
1.09M
    }
1017
1018
    // If we weren't able to find any matches, we don't have any other choice than to encode the next byte as a literal.
1019
933k
    u8 next_byte { 0 };
1020
933k
    TRY(m_dictionary->read({ &next_byte, sizeof(next_byte) }));
1021
933k
    TRY(encode_literal(next_byte));
1022
933k
    return {};
1023
933k
}
1024
1025
ErrorOr<Bytes> LzmaDecompressor::read_some(Bytes bytes)
1026
684k
{
1027
21.3M
    while (m_dictionary->used_space() < bytes.size() && m_dictionary->empty_space() != 0) {
1028
20.7M
        if (m_found_end_of_stream_marker)
1029
2.95k
            break;
1030
1031
20.7M
        if (has_reached_expected_data_size()) {
1032
            // If the decoder is in a clean state, we assume that this is fine.
1033
86
            if (is_range_decoder_in_clean_state())
1034
39
                break;
1035
1036
            // Otherwise, we give it one last try to find the end marker in the remaining data.
1037
86
        }
1038
1039
20.7M
        auto copy_match_to_buffer = [&](u16 real_length) -> ErrorOr<void> {
1040
13.8M
            VERIFY(!m_leftover_match_length.has_value());
1041
1042
13.8M
            if (m_options.uncompressed_size.has_value() && m_options.uncompressed_size.value() < m_total_processed_bytes + real_length)
1043
2
                return Error::from_string_literal("Tried to copy match beyond expected uncompressed file size");
1044
1045
13.8M
            auto copied_length = TRY(m_dictionary->copy_from_seekback(current_repetition_offset(), real_length));
1046
1047
13.8M
            m_total_processed_bytes += copied_length;
1048
13.8M
            real_length -= copied_length;
1049
1050
13.8M
            if (real_length > 0)
1051
307k
                m_leftover_match_length = real_length;
1052
1053
13.8M
            return {};
1054
13.8M
        };
1055
1056
        // If we have a leftover part of a repeating match, we should finish that first.
1057
20.7M
        if (m_leftover_match_length.has_value()) {
1058
307k
            TRY(copy_match_to_buffer(m_leftover_match_length.release_value()));
1059
307k
            continue;
1060
307k
        }
1061
1062
20.3M
        auto const match_type = TRY(decode_match_type());
1063
1064
        // If we are looking for EOS, but find another match type, the stream is also corrupted.
1065
20.3M
        if (has_reached_expected_data_size() && match_type != MatchType::SimpleMatch)
1066
36
            return Error::from_string_literal("First match type after the expected uncompressed size is not a simple match");
1067
1068
20.3M
        if (match_type == MatchType::Literal) {
1069
            // "At first the LZMA decoder must check that it doesn't exceed
1070
            //  specified uncompressed size."
1071
            // This is already checked for at the beginning of the loop.
1072
1073
            // "Then it decodes literal value and puts it to sliding window."
1074
6.83M
            TRY(decode_literal_to_output_buffer());
1075
1076
            // "Then the decoder must update the "state" value."
1077
6.83M
            update_state_after_literal();
1078
6.83M
            continue;
1079
6.83M
        }
1080
1081
13.5M
        if (match_type == MatchType::SimpleMatch) {
1082
            // "The distance history table is updated with the following scheme:"
1083
1.10M
            m_rep3 = m_rep2;
1084
1.10M
            m_rep2 = m_rep1;
1085
1.10M
            m_rep1 = m_rep0;
1086
1087
            // "The zero-based length is decoded with "LenDecoder"."
1088
1.10M
            u16 normalized_length = TRY(decode_normalized_match_length(m_length_coder));
1089
1090
            // "The state is update with UpdateState_Match function."
1091
1.10M
            update_state_after_match();
1092
1093
            // "and the new "rep0" value is decoded with DecodeDistance."
1094
1.10M
            m_rep0 = TRY(decode_normalized_match_distance(normalized_length));
1095
1096
            // "If the value of "rep0" is equal to 0xFFFFFFFF, it means that we have
1097
            //  "End of stream" marker, so we can stop decoding and check finishing
1098
            //  condition in Range Decoder"
1099
1.10M
            if (m_rep0 == end_of_stream_marker) {
1100
                // If we should reject end-of-stream markers, do so now.
1101
                // Note that this is not part of LZMA, as LZMA allows end-of-stream markers in all contexts, so pure LZMA should never set this option.
1102
2.95k
                if (m_options.reject_end_of_stream_marker)
1103
0
                    return Error::from_string_literal("An end-of-stream marker was found, but the LZMA stream is configured to reject them");
1104
1105
                // The range decoder condition is checked after breaking out of the loop.
1106
2.95k
                m_found_end_of_stream_marker = true;
1107
2.95k
                continue;
1108
2.95k
            }
1109
1110
            // If we are looking for EOS, but haven't found it here, the stream is corrupted.
1111
1.10M
            if (has_reached_expected_data_size())
1112
2
                return Error::from_string_literal("First simple match after the expected uncompressed size is not the EOS marker");
1113
1114
            // "If uncompressed size is defined, LZMA decoder must check that it doesn't
1115
            //  exceed that specified uncompressed size."
1116
            // This is being checked for in the common "copy to buffer" implementation.
1117
1118
            // "Also the decoder must check that "rep0" value is not larger than dictionary size
1119
            //  and is not larger than the number of already decoded bytes."
1120
1.10M
            if (current_repetition_offset() > m_dictionary->seekback_limit())
1121
199
                return Error::from_string_literal("rep0 value is larger than the possible lookback size");
1122
1123
            // "Then the decoder must copy match bytes as described in
1124
            //  "The match symbols copying" section."
1125
1.10M
            TRY(copy_match_to_buffer(normalized_length + normalized_to_real_match_length_offset));
1126
1127
1.10M
            continue;
1128
1.10M
        }
1129
1130
12.4M
        if (match_type == MatchType::ShortRepMatch) {
1131
            // "LZMA doesn't update the distance history."
1132
1133
            // "If the subtype is "Short Rep Match", the decoder updates the state, puts
1134
            //  the one byte from window to current position in window and goes to next
1135
            //  MATCH/LITERAL symbol."
1136
2.84k
            update_state_after_short_rep();
1137
1138
2.84k
            TRY(copy_match_to_buffer(1));
1139
1140
2.80k
            continue;
1141
2.84k
        }
1142
1143
        // Note: We don't need to do anything specific for "Rep Match 0", we just need to make sure to not
1144
        //       run the detection for other match types and to not switch around the distance history.
1145
1146
12.4M
        if (match_type == MatchType::RepMatch1) {
1147
68.6k
            u32 distance = m_rep1;
1148
68.6k
            m_rep1 = m_rep0;
1149
68.6k
            m_rep0 = distance;
1150
68.6k
        }
1151
1152
12.4M
        if (match_type == MatchType::RepMatch2) {
1153
34.6k
            u32 distance = m_rep2;
1154
34.6k
            m_rep2 = m_rep1;
1155
34.6k
            m_rep1 = m_rep0;
1156
34.6k
            m_rep0 = distance;
1157
34.6k
        }
1158
1159
12.4M
        if (match_type == MatchType::RepMatch3) {
1160
9.88M
            u32 distance = m_rep3;
1161
9.88M
            m_rep3 = m_rep2;
1162
9.88M
            m_rep2 = m_rep1;
1163
9.88M
            m_rep1 = m_rep0;
1164
9.88M
            m_rep0 = distance;
1165
9.88M
        }
1166
1167
        // "In other cases (Rep Match 0/1/2/3), it decodes the zero-based
1168
        //  length of match with "RepLenDecoder" decoder."
1169
12.4M
        u16 normalized_length = TRY(decode_normalized_match_length(m_rep_length_coder));
1170
1171
        // "Then it updates the state."
1172
12.4M
        update_state_after_rep();
1173
1174
        // "Then the decoder must copy match bytes as described in
1175
        //  "The Match symbols copying" section."
1176
12.4M
        TRY(copy_match_to_buffer(normalized_length + normalized_to_real_match_length_offset));
1177
12.4M
    }
1178
1179
682k
    if (m_found_end_of_stream_marker || has_reached_expected_data_size()) {
1180
2.99k
        if (m_options.uncompressed_size.has_value() && m_total_processed_bytes < m_options.uncompressed_size.value())
1181
101
            return Error::from_string_literal("Found end-of-stream marker earlier than expected");
1182
1183
2.89k
        if (!is_range_decoder_in_clean_state())
1184
44
            return Error::from_string_literal("LZMA stream ends in an unclean state");
1185
2.89k
    }
1186
1187
682k
    return m_dictionary->read(bytes);
1188
682k
}
1189
1190
ErrorOr<size_t> LzmaDecompressor::write_some(ReadonlyBytes)
1191
0
{
1192
0
    return Error::from_errno(EBADF);
1193
0
}
1194
1195
bool LzmaDecompressor::is_eof() const
1196
1.34M
{
1197
1.34M
    if (m_dictionary->used_space() > 0)
1198
1.32M
        return false;
1199
1200
20.3k
    if (has_reached_expected_data_size())
1201
49
        return true;
1202
1203
20.2k
    return m_found_end_of_stream_marker;
1204
20.3k
}
1205
1206
bool LzmaDecompressor::is_open() const
1207
0
{
1208
0
    return true;
1209
0
}
1210
1211
void LzmaDecompressor::close()
1212
0
{
1213
0
}
1214
1215
ErrorOr<NonnullOwnPtr<LzmaCompressor>> LzmaCompressor::create_container(MaybeOwned<Stream> stream, LzmaCompressorOptions const& options)
1216
2.81k
{
1217
5.62k
    auto dictionary = TRY(try_make<SearchableCircularBuffer>(TRY(SearchableCircularBuffer::create_empty(options.dictionary_size + largest_real_match_length))));
1218
1219
    // "The LZMA Decoder uses (1 << (lc + lp)) tables with CProb values, where each table contains 0x300 CProb values."
1220
5.62k
    auto literal_probabilities = TRY(FixedArray<Probability>::create(literal_probability_table_size * (1 << (options.literal_context_bits + options.literal_position_bits))));
1221
1222
2.81k
    auto header = TRY(LzmaHeader::from_compressor_options(options));
1223
2.81k
    TRY(stream->write_value(header));
1224
1225
2.81k
    auto compressor = TRY(adopt_nonnull_own_or_enomem(new (nothrow) LzmaCompressor(move(stream), options, move(dictionary), move(literal_probabilities))));
1226
1227
2.81k
    return compressor;
1228
2.81k
}
1229
1230
LzmaCompressor::LzmaCompressor(MaybeOwned<AK::Stream> stream, Compress::LzmaCompressorOptions options, MaybeOwned<SearchableCircularBuffer> dictionary, FixedArray<Compress::LzmaState::Probability> literal_probabilities)
1231
2.81k
    : LzmaState(move(literal_probabilities))
1232
2.81k
    , m_stream(move(stream))
1233
2.81k
    , m_options(move(options))
1234
2.81k
    , m_dictionary(move(dictionary))
1235
2.81k
{
1236
2.81k
}
1237
1238
ErrorOr<Bytes> LzmaCompressor::read_some(Bytes)
1239
0
{
1240
0
    return Error::from_errno(EBADF);
1241
0
}
1242
1243
ErrorOr<size_t> LzmaCompressor::write_some(ReadonlyBytes bytes)
1244
4.48M
{
1245
    // Fill the input buffer until it's full or until we can't read any more data.
1246
4.48M
    size_t processed_bytes = min(bytes.size(), largest_real_match_length - m_dictionary->used_space());
1247
4.48M
    bytes = bytes.trim(processed_bytes);
1248
1249
8.96M
    while (bytes.size() > 0) {
1250
4.48M
        auto const written_bytes = m_dictionary->write(bytes);
1251
4.48M
        bytes = bytes.slice(written_bytes);
1252
4.48M
    }
1253
1254
4.48M
    VERIFY(m_dictionary->used_space() <= largest_real_match_length);
1255
1256
4.48M
    if (m_options.uncompressed_size.has_value() && m_total_processed_bytes + m_dictionary->used_space() > m_options.uncompressed_size.value())
1257
0
        return Error::from_string_literal("Tried to compress more LZMA data than announced");
1258
1259
8.96M
    TRY(encode_once());
1260
1261
    // If we read enough data to reach the final uncompressed size, flush automatically.
1262
    // Flushing will handle encoding the remaining data for us and finalize the stream.
1263
8.96M
    if (m_options.uncompressed_size.has_value() && m_total_processed_bytes + m_dictionary->used_space() >= m_options.uncompressed_size.value())
1264
0
        TRY(flush());
1265
1266
8.96M
    return processed_bytes;
1267
8.96M
}
1268
1269
ErrorOr<void> LzmaCompressor::flush()
1270
2.81k
{
1271
2.81k
    if (m_has_flushed_data)
1272
0
        return Error::from_string_literal("Flushed an LZMA stream twice");
1273
1274
132k
    while (m_dictionary->used_space() > 0)
1275
129k
        TRY(encode_once());
1276
1277
2.81k
    if (m_options.uncompressed_size.has_value() && m_total_processed_bytes < m_options.uncompressed_size.value())
1278
0
        return Error::from_string_literal("Flushing LZMA data with known but unreached uncompressed size");
1279
1280
    // The LZMA specification technically also allows both a known size and an end-of-stream marker simultaneously,
1281
    // but LZMA2 rejects them, so skip emitting the end-of-stream marker if we know the uncompressed size.
1282
2.81k
    if (!m_options.uncompressed_size.has_value())
1283
2.81k
        TRY(encode_normalized_simple_match(end_of_stream_marker, 0));
1284
1285
    // Shifting the range encoder using the normal operation handles any pending overflows.
1286
5.62k
    TRY(shift_range_encoder());
1287
1288
    // Now, the remaining bytes are the cached byte, the chain of 0xFF, and the upper 3 bytes of the current `code`.
1289
    // Incrementing the values does not have to be considered as no overflows are pending. The fourth byte is the
1290
    // null byte that we just shifted in, which should not be flushed as it would be extraneous junk data.
1291
5.62k
    TRY(m_stream->write_value<u8>(m_range_encoder_cached_byte));
1292
2.82k
    for (size_t i = 0; i < m_range_encoder_ff_chain_length; i++)
1293
14
        TRY(m_stream->write_value<u8>(0xFF));
1294
5.62k
    TRY(m_stream->write_value<u8>(m_range_encoder_code >> 24));
1295
5.62k
    TRY(m_stream->write_value<u8>(m_range_encoder_code >> 16));
1296
2.81k
    TRY(m_stream->write_value<u8>(m_range_encoder_code >> 8));
1297
1298
2.81k
    m_has_flushed_data = true;
1299
2.81k
    return {};
1300
2.81k
}
1301
1302
bool LzmaCompressor::is_eof() const
1303
0
{
1304
0
    return true;
1305
0
}
1306
1307
bool LzmaCompressor::is_open() const
1308
0
{
1309
0
    return !m_has_flushed_data;
1310
0
}
1311
1312
void LzmaCompressor::close()
1313
0
{
1314
0
    if (!m_has_flushed_data) {
1315
        // Note: We need a better API for specifying things like this.
1316
0
        flush().release_value_but_fixme_should_propagate_errors();
1317
0
    }
1318
0
}
1319
1320
LzmaCompressor::~LzmaCompressor()
1321
2.81k
{
1322
2.81k
    if (!m_has_flushed_data) {
1323
        // Note: We need a better API for specifying things like this.
1324
0
        flush().release_value_but_fixme_should_propagate_errors();
1325
0
    }
1326
2.81k
}
1327
1328
}