Serenity Operating System
1/*
2 * Copyright (c) 2020, the SerenityOS developers.
3 * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include <AK/Array.h>
9#include <AK/Assertions.h>
10#include <AK/BinaryHeap.h>
11#include <AK/BinarySearch.h>
12#include <AK/BitStream.h>
13#include <AK/MemoryStream.h>
14#include <string.h>
15
16#include <LibCompress/Deflate.h>
17
18namespace Compress {
19
20static constexpr u8 deflate_special_code_length_copy = 16;
21static constexpr u8 deflate_special_code_length_zeros = 17;
22static constexpr u8 deflate_special_code_length_long_zeros = 18;
23
24CanonicalCode const& CanonicalCode::fixed_literal_codes()
25{
26 static CanonicalCode code;
27 static bool initialized = false;
28
29 if (initialized)
30 return code;
31
32 code = CanonicalCode::from_bytes(fixed_literal_bit_lengths).value();
33 initialized = true;
34
35 return code;
36}
37
38CanonicalCode const& CanonicalCode::fixed_distance_codes()
39{
40 static CanonicalCode code;
41 static bool initialized = false;
42
43 if (initialized)
44 return code;
45
46 code = CanonicalCode::from_bytes(fixed_distance_bit_lengths).value();
47 initialized = true;
48
49 return code;
50}
51
52Optional<CanonicalCode> CanonicalCode::from_bytes(ReadonlyBytes bytes)
53{
54 // FIXME: I can't quite follow the algorithm here, but it seems to work.
55
56 CanonicalCode code;
57
58 auto non_zero_symbols = 0;
59 auto last_non_zero = -1;
60 for (size_t i = 0; i < bytes.size(); i++) {
61 if (bytes[i] != 0) {
62 non_zero_symbols++;
63 last_non_zero = i;
64 }
65 }
66 if (non_zero_symbols == 1) { // special case - only 1 symbol
67 code.m_symbol_codes.append(0b10);
68 code.m_symbol_values.append(last_non_zero);
69 code.m_bit_codes[last_non_zero] = 0;
70 code.m_bit_code_lengths[last_non_zero] = 1;
71 return code;
72 }
73
74 auto next_code = 0;
75 for (size_t code_length = 1; code_length <= 15; ++code_length) {
76 next_code <<= 1;
77 auto start_bit = 1 << code_length;
78
79 for (size_t symbol = 0; symbol < bytes.size(); ++symbol) {
80 if (bytes[symbol] != code_length)
81 continue;
82
83 if (next_code > start_bit)
84 return {};
85
86 code.m_symbol_codes.append(start_bit | next_code);
87 code.m_symbol_values.append(symbol);
88 code.m_bit_codes[symbol] = fast_reverse16(start_bit | next_code, code_length); // DEFLATE writes huffman encoded symbols as lsb-first
89 code.m_bit_code_lengths[symbol] = code_length;
90
91 next_code++;
92 }
93 }
94
95 if (next_code != (1 << 15)) {
96 return {};
97 }
98
99 return code;
100}
101
102ErrorOr<u32> CanonicalCode::read_symbol(LittleEndianInputBitStream& stream) const
103{
104 u32 code_bits = 1;
105
106 for (;;) {
107 code_bits = code_bits << 1 | TRY(stream.read_bits(1));
108 if (code_bits >= (1 << 16))
109 return Error::from_string_literal("Symbol exceeds maximum symbol number");
110
111 // FIXME: This is very inefficient and could greatly be improved by implementing this
112 // algorithm: https://www.hanshq.net/zip.html#huffdec
113 size_t index;
114 if (binary_search(m_symbol_codes.span(), code_bits, &index))
115 return m_symbol_values[index];
116 }
117}
118
119ErrorOr<void> CanonicalCode::write_symbol(LittleEndianOutputBitStream& stream, u32 symbol) const
120{
121 TRY(stream.write_bits(m_bit_codes[symbol], m_bit_code_lengths[symbol]));
122 return {};
123}
124
125DeflateDecompressor::CompressedBlock::CompressedBlock(DeflateDecompressor& decompressor, CanonicalCode literal_codes, Optional<CanonicalCode> distance_codes)
126 : m_decompressor(decompressor)
127 , m_literal_codes(literal_codes)
128 , m_distance_codes(distance_codes)
129{
130}
131
132ErrorOr<bool> DeflateDecompressor::CompressedBlock::try_read_more()
133{
134 if (m_eof == true)
135 return false;
136
137 auto const symbol = TRY(m_literal_codes.read_symbol(*m_decompressor.m_input_stream));
138
139 if (symbol >= 286)
140 return Error::from_string_literal("Invalid deflate literal/length symbol");
141
142 if (symbol < 256) {
143 u8 byte_symbol = symbol;
144 m_decompressor.m_output_buffer.write({ &byte_symbol, sizeof(byte_symbol) });
145 return true;
146 } else if (symbol == 256) {
147 m_eof = true;
148 return false;
149 } else {
150 if (!m_distance_codes.has_value())
151 return Error::from_string_literal("Distance codes have not been initialized");
152
153 auto const length = TRY(m_decompressor.decode_length(symbol));
154 auto const distance_symbol = TRY(m_distance_codes.value().read_symbol(*m_decompressor.m_input_stream));
155 if (distance_symbol >= 30)
156 return Error::from_string_literal("Invalid deflate distance symbol");
157
158 auto const distance = TRY(m_decompressor.decode_distance(distance_symbol));
159
160 for (size_t idx = 0; idx < length; ++idx) {
161 u8 byte = 0;
162 TRY(m_decompressor.m_output_buffer.read_with_seekback({ &byte, sizeof(byte) }, distance));
163
164 m_decompressor.m_output_buffer.write({ &byte, sizeof(byte) });
165 }
166
167 return true;
168 }
169}
170
171DeflateDecompressor::UncompressedBlock::UncompressedBlock(DeflateDecompressor& decompressor, size_t length)
172 : m_decompressor(decompressor)
173 , m_bytes_remaining(length)
174{
175}
176
177ErrorOr<bool> DeflateDecompressor::UncompressedBlock::try_read_more()
178{
179 if (m_bytes_remaining == 0)
180 return false;
181
182 Array<u8, 4096> temporary_buffer;
183 auto readable_bytes = temporary_buffer.span().trim(min(m_bytes_remaining, m_decompressor.m_output_buffer.empty_space()));
184 auto read_bytes = TRY(m_decompressor.m_input_stream->read_some(readable_bytes));
185 auto written_bytes = m_decompressor.m_output_buffer.write(read_bytes);
186 VERIFY(read_bytes.size() == written_bytes);
187
188 m_bytes_remaining -= written_bytes;
189 return true;
190}
191
192ErrorOr<NonnullOwnPtr<DeflateDecompressor>> DeflateDecompressor::construct(MaybeOwned<Stream> stream)
193{
194 auto output_buffer = TRY(CircularBuffer::create_empty(32 * KiB));
195 return TRY(adopt_nonnull_own_or_enomem(new (nothrow) DeflateDecompressor(move(stream), move(output_buffer))));
196}
197
198DeflateDecompressor::DeflateDecompressor(MaybeOwned<Stream> stream, CircularBuffer output_buffer)
199 : m_input_stream(make<LittleEndianInputBitStream>(move(stream)))
200 , m_output_buffer(move(output_buffer))
201{
202}
203
204DeflateDecompressor::~DeflateDecompressor()
205{
206 if (m_state == State::ReadingCompressedBlock)
207 m_compressed_block.~CompressedBlock();
208 if (m_state == State::ReadingUncompressedBlock)
209 m_uncompressed_block.~UncompressedBlock();
210}
211
212ErrorOr<Bytes> DeflateDecompressor::read_some(Bytes bytes)
213{
214 size_t total_read = 0;
215 while (total_read < bytes.size()) {
216 auto slice = bytes.slice(total_read);
217
218 if (m_state == State::Idle) {
219 if (m_read_final_bock)
220 break;
221
222 m_read_final_bock = TRY(m_input_stream->read_bit());
223 auto const block_type = TRY(m_input_stream->read_bits(2));
224
225 if (block_type == 0b00) {
226 m_input_stream->align_to_byte_boundary();
227
228 u16 length = TRY(m_input_stream->read_value<LittleEndian<u16>>());
229 u16 negated_length = TRY(m_input_stream->read_value<LittleEndian<u16>>());
230
231 if ((length ^ 0xffff) != negated_length)
232 return Error::from_string_literal("Calculated negated length does not equal stored negated length");
233
234 m_state = State::ReadingUncompressedBlock;
235 new (&m_uncompressed_block) UncompressedBlock(*this, length);
236
237 continue;
238 }
239
240 if (block_type == 0b01) {
241 m_state = State::ReadingCompressedBlock;
242 new (&m_compressed_block) CompressedBlock(*this, CanonicalCode::fixed_literal_codes(), CanonicalCode::fixed_distance_codes());
243
244 continue;
245 }
246
247 if (block_type == 0b10) {
248 CanonicalCode literal_codes;
249 Optional<CanonicalCode> distance_codes;
250 TRY(decode_codes(literal_codes, distance_codes));
251
252 m_state = State::ReadingCompressedBlock;
253 new (&m_compressed_block) CompressedBlock(*this, literal_codes, distance_codes);
254
255 continue;
256 }
257
258 return Error::from_string_literal("Unhandled block type for Idle state");
259 }
260
261 if (m_state == State::ReadingCompressedBlock) {
262 auto nread = m_output_buffer.read(slice).size();
263
264 while (nread < slice.size() && TRY(m_compressed_block.try_read_more())) {
265 nread += m_output_buffer.read(slice.slice(nread)).size();
266 }
267
268 total_read += nread;
269 if (nread == slice.size())
270 break;
271
272 m_compressed_block.~CompressedBlock();
273 m_state = State::Idle;
274
275 continue;
276 }
277
278 if (m_state == State::ReadingUncompressedBlock) {
279 auto nread = m_output_buffer.read(slice).size();
280
281 while (nread < slice.size() && TRY(m_uncompressed_block.try_read_more())) {
282 nread += m_output_buffer.read(slice.slice(nread)).size();
283 }
284
285 total_read += nread;
286 if (nread == slice.size())
287 break;
288
289 m_uncompressed_block.~UncompressedBlock();
290 m_state = State::Idle;
291
292 continue;
293 }
294
295 VERIFY_NOT_REACHED();
296 }
297
298 return bytes.slice(0, total_read);
299}
300
301bool DeflateDecompressor::is_eof() const { return m_state == State::Idle && m_read_final_bock; }
302
303ErrorOr<size_t> DeflateDecompressor::write_some(ReadonlyBytes)
304{
305 return Error::from_errno(EBADF);
306}
307
308bool DeflateDecompressor::is_open() const
309{
310 return true;
311}
312
313void DeflateDecompressor::close()
314{
315}
316
317ErrorOr<ByteBuffer> DeflateDecompressor::decompress_all(ReadonlyBytes bytes)
318{
319 auto memory_stream = TRY(try_make<FixedMemoryStream>(bytes));
320 auto deflate_stream = TRY(DeflateDecompressor::construct(move(memory_stream)));
321 AllocatingMemoryStream output_stream;
322
323 auto buffer = TRY(ByteBuffer::create_uninitialized(4096));
324 while (!deflate_stream->is_eof()) {
325 auto const slice = TRY(deflate_stream->read_some(buffer));
326 TRY(output_stream.write_until_depleted(slice));
327 }
328
329 auto output_buffer = TRY(ByteBuffer::create_uninitialized(output_stream.used_buffer_size()));
330 TRY(output_stream.read_until_filled(output_buffer));
331 return output_buffer;
332}
333
334ErrorOr<u32> DeflateDecompressor::decode_length(u32 symbol)
335{
336 // FIXME: I can't quite follow the algorithm here, but it seems to work.
337
338 if (symbol <= 264)
339 return symbol - 254;
340
341 if (symbol <= 284) {
342 auto extra_bits = (symbol - 261) / 4;
343 return (((symbol - 265) % 4 + 4) << extra_bits) + 3 + TRY(m_input_stream->read_bits(extra_bits));
344 }
345
346 if (symbol == 285)
347 return 258;
348
349 VERIFY_NOT_REACHED();
350}
351
352ErrorOr<u32> DeflateDecompressor::decode_distance(u32 symbol)
353{
354 // FIXME: I can't quite follow the algorithm here, but it seems to work.
355
356 if (symbol <= 3)
357 return symbol + 1;
358
359 if (symbol <= 29) {
360 auto extra_bits = (symbol / 2) - 1;
361 return ((symbol % 2 + 2) << extra_bits) + 1 + TRY(m_input_stream->read_bits(extra_bits));
362 }
363
364 VERIFY_NOT_REACHED();
365}
366
367ErrorOr<void> DeflateDecompressor::decode_codes(CanonicalCode& literal_code, Optional<CanonicalCode>& distance_code)
368{
369 auto literal_code_count = TRY(m_input_stream->read_bits(5)) + 257;
370 auto distance_code_count = TRY(m_input_stream->read_bits(5)) + 1;
371 auto code_length_count = TRY(m_input_stream->read_bits(4)) + 4;
372
373 // First we have to extract the code lengths of the code that was used to encode the code lengths of
374 // the code that was used to encode the block.
375
376 u8 code_lengths_code_lengths[19] = { 0 };
377 for (size_t i = 0; i < code_length_count; ++i) {
378 code_lengths_code_lengths[code_lengths_code_lengths_order[i]] = TRY(m_input_stream->read_bits(3));
379 }
380
381 // Now we can extract the code that was used to encode the code lengths of the code that was used to
382 // encode the block.
383
384 auto code_length_code_result = CanonicalCode::from_bytes({ code_lengths_code_lengths, sizeof(code_lengths_code_lengths) });
385 if (!code_length_code_result.has_value())
386 return Error::from_string_literal("Failed to decode code length code");
387 auto const code_length_code = code_length_code_result.value();
388
389 // Next we extract the code lengths of the code that was used to encode the block.
390
391 Vector<u8> code_lengths;
392 while (code_lengths.size() < literal_code_count + distance_code_count) {
393 auto symbol = TRY(code_length_code.read_symbol(*m_input_stream));
394
395 if (symbol < deflate_special_code_length_copy) {
396 code_lengths.append(static_cast<u8>(symbol));
397 continue;
398 } else if (symbol == deflate_special_code_length_zeros) {
399 auto nrepeat = 3 + TRY(m_input_stream->read_bits(3));
400 for (size_t j = 0; j < nrepeat; ++j)
401 code_lengths.append(0);
402 continue;
403 } else if (symbol == deflate_special_code_length_long_zeros) {
404 auto nrepeat = 11 + TRY(m_input_stream->read_bits(7));
405 for (size_t j = 0; j < nrepeat; ++j)
406 code_lengths.append(0);
407 continue;
408 } else {
409 VERIFY(symbol == deflate_special_code_length_copy);
410
411 if (code_lengths.is_empty())
412 return Error::from_string_literal("Found no codes to copy before a copy block");
413
414 auto nrepeat = 3 + TRY(m_input_stream->read_bits(2));
415 for (size_t j = 0; j < nrepeat; ++j)
416 code_lengths.append(code_lengths.last());
417 }
418 }
419
420 if (code_lengths.size() != literal_code_count + distance_code_count)
421 return Error::from_string_literal("Number of code lengths does not match the sum of codes");
422
423 // Now we extract the code that was used to encode literals and lengths in the block.
424
425 auto literal_code_result = CanonicalCode::from_bytes(code_lengths.span().trim(literal_code_count));
426 if (!literal_code_result.has_value())
427 return Error::from_string_literal("Failed to decode the literal code");
428 literal_code = literal_code_result.value();
429
430 // Now we extract the code that was used to encode distances in the block.
431
432 if (distance_code_count == 1) {
433 auto length = code_lengths[literal_code_count];
434
435 if (length == 0)
436 return {};
437 else if (length != 1)
438 return Error::from_string_literal("Length for a single distance code is longer than 1");
439 }
440
441 auto distance_code_result = CanonicalCode::from_bytes(code_lengths.span().slice(literal_code_count));
442 if (!distance_code_result.has_value())
443 return Error::from_string_literal("Failed to decode the distance code");
444 distance_code = distance_code_result.value();
445
446 return {};
447}
448
449ErrorOr<NonnullOwnPtr<DeflateCompressor>> DeflateCompressor::construct(MaybeOwned<Stream> stream, CompressionLevel compression_level)
450{
451 auto bit_stream = TRY(try_make<LittleEndianOutputBitStream>(move(stream)));
452 auto deflate_compressor = TRY(adopt_nonnull_own_or_enomem(new (nothrow) DeflateCompressor(move(bit_stream), compression_level)));
453 return deflate_compressor;
454}
455
456DeflateCompressor::DeflateCompressor(NonnullOwnPtr<LittleEndianOutputBitStream> stream, CompressionLevel compression_level)
457 : m_compression_level(compression_level)
458 , m_compression_constants(compression_constants[static_cast<int>(m_compression_level)])
459 , m_output_stream(move(stream))
460{
461 m_symbol_frequencies.fill(0);
462 m_distance_frequencies.fill(0);
463}
464
465DeflateCompressor::~DeflateCompressor()
466{
467 VERIFY(m_finished);
468}
469
470ErrorOr<Bytes> DeflateCompressor::read_some(Bytes)
471{
472 return Error::from_errno(EBADF);
473}
474
475ErrorOr<size_t> DeflateCompressor::write_some(ReadonlyBytes bytes)
476{
477 VERIFY(!m_finished);
478
479 size_t total_written = 0;
480 while (!bytes.is_empty()) {
481 auto n_written = bytes.copy_trimmed_to(pending_block().slice(m_pending_block_size));
482 m_pending_block_size += n_written;
483
484 if (m_pending_block_size == block_size)
485 TRY(flush());
486
487 bytes = bytes.slice(n_written);
488 total_written += n_written;
489 }
490 return total_written;
491}
492
493bool DeflateCompressor::is_eof() const
494{
495 return true;
496}
497
498bool DeflateCompressor::is_open() const
499{
500 return m_output_stream->is_open();
501}
502
503void DeflateCompressor::close()
504{
505}
506
507// Knuth's multiplicative hash on 4 bytes
508u16 DeflateCompressor::hash_sequence(u8 const* bytes)
509{
510 constexpr const u32 knuth_constant = 2654435761; // shares no common factors with 2^32
511 return ((bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24) * knuth_constant) >> (32 - hash_bits);
512}
513
514size_t DeflateCompressor::compare_match_candidate(size_t start, size_t candidate, size_t previous_match_length, size_t maximum_match_length)
515{
516 VERIFY(previous_match_length < maximum_match_length);
517
518 // We firstly check that the match is at least (prev_match_length + 1) long, we check backwards as there's a higher chance the end mismatches
519 for (ssize_t i = previous_match_length; i >= 0; i--) {
520 if (m_rolling_window[start + i] != m_rolling_window[candidate + i])
521 return 0;
522 }
523
524 // Find the actual length
525 auto match_length = previous_match_length + 1;
526 while (match_length < maximum_match_length && m_rolling_window[start + match_length] == m_rolling_window[candidate + match_length]) {
527 match_length++;
528 }
529
530 VERIFY(match_length > previous_match_length);
531 VERIFY(match_length <= maximum_match_length);
532 return match_length;
533}
534
535size_t DeflateCompressor::find_back_match(size_t start, u16 hash, size_t previous_match_length, size_t maximum_match_length, size_t& match_position)
536{
537 auto max_chain_length = m_compression_constants.max_chain;
538 if (previous_match_length == 0)
539 previous_match_length = min_match_length - 1; // we only care about matches that are at least min_match_length long
540 if (previous_match_length >= maximum_match_length)
541 return 0; // we can't improve a maximum length match
542 if (previous_match_length >= m_compression_constants.max_lazy_length)
543 return 0; // the previous match is already pretty, we shouldn't waste another full search
544 if (previous_match_length >= m_compression_constants.good_match_length)
545 max_chain_length /= 4; // we already have a pretty good much, so do a shorter search
546
547 auto candidate = m_hash_head[hash];
548 auto match_found = false;
549 while (max_chain_length--) {
550 if (candidate == empty_slot)
551 break; // no remaining candidates
552
553 VERIFY(candidate < start);
554 if (start - candidate > window_size)
555 break; // outside the window
556
557 auto match_length = compare_match_candidate(start, candidate, previous_match_length, maximum_match_length);
558
559 if (match_length != 0) {
560 match_found = true;
561 match_position = candidate;
562 previous_match_length = match_length;
563
564 if (match_length == maximum_match_length)
565 return match_length; // bail if we got the maximum possible length
566 }
567
568 candidate = m_hash_prev[candidate % window_size];
569 }
570 if (!match_found)
571 return 0; // we didn't find any matches
572 return previous_match_length; // we found matches, but they were at most previous_match_length long
573}
574
575ALWAYS_INLINE u8 DeflateCompressor::distance_to_base(u16 distance)
576{
577 return (distance <= 256) ? distance_to_base_lo[distance - 1] : distance_to_base_hi[(distance - 1) >> 7];
578}
579
580template<size_t Size>
581void DeflateCompressor::generate_huffman_lengths(Array<u8, Size>& lengths, Array<u16, Size> const& frequencies, size_t max_bit_length, u16 frequency_cap)
582{
583 VERIFY((1u << max_bit_length) >= Size);
584 u16 heap_keys[Size]; // Used for O(n) heap construction
585 u16 heap_values[Size];
586
587 u16 huffman_links[Size * 2 + 1] = { 0 };
588 size_t non_zero_freqs = 0;
589 for (size_t i = 0; i < Size; i++) {
590 auto frequency = frequencies[i];
591 if (frequency == 0)
592 continue;
593
594 if (frequency > frequency_cap) {
595 frequency = frequency_cap;
596 }
597
598 heap_keys[non_zero_freqs] = frequency; // sort symbols by frequency
599 heap_values[non_zero_freqs] = Size + non_zero_freqs; // huffman_links "links"
600 non_zero_freqs++;
601 }
602
603 // special case for only 1 used symbol
604 if (non_zero_freqs < 2) {
605 for (size_t i = 0; i < Size; i++)
606 lengths[i] = (frequencies[i] == 0) ? 0 : 1;
607 return;
608 }
609
610 BinaryHeap<u16, u16, Size> heap { heap_keys, heap_values, non_zero_freqs };
611
612 // build the huffman tree - binary heap is used for efficient frequency comparisons
613 while (heap.size() > 1) {
614 u16 lowest_frequency = heap.peek_min_key();
615 u16 lowest_link = heap.pop_min();
616 u16 second_lowest_frequency = heap.peek_min_key();
617 u16 second_lowest_link = heap.pop_min();
618
619 u16 new_link = heap.size() + 2;
620
621 heap.insert(lowest_frequency + second_lowest_frequency, new_link);
622
623 huffman_links[lowest_link] = new_link;
624 huffman_links[second_lowest_link] = new_link;
625 }
626
627 non_zero_freqs = 0;
628 for (size_t i = 0; i < Size; i++) {
629 if (frequencies[i] == 0) {
630 lengths[i] = 0;
631 continue;
632 }
633
634 u16 link = huffman_links[Size + non_zero_freqs];
635 non_zero_freqs++;
636
637 size_t bit_length = 1;
638 while (link != 2) {
639 bit_length++;
640 link = huffman_links[link];
641 }
642
643 if (bit_length > max_bit_length) {
644 VERIFY(frequency_cap != 1);
645 return generate_huffman_lengths(lengths, frequencies, max_bit_length, frequency_cap / 2);
646 }
647
648 lengths[i] = bit_length;
649 }
650}
651
652void DeflateCompressor::lz77_compress_block()
653{
654 for (auto& slot : m_hash_head) { // initialize chained hash table
655 slot = empty_slot;
656 }
657
658 auto insert_hash = [&](auto pos, auto hash) {
659 auto window_pos = pos % window_size;
660 m_hash_prev[window_pos] = m_hash_head[hash];
661 m_hash_head[hash] = window_pos;
662 };
663
664 auto emit_literal = [&](auto literal) {
665 VERIFY(m_pending_symbol_size <= block_size + 1);
666 auto index = m_pending_symbol_size++;
667 m_symbol_buffer[index].distance = 0;
668 m_symbol_buffer[index].literal = literal;
669 m_symbol_frequencies[literal]++;
670 };
671
672 auto emit_back_reference = [&](auto distance, auto length) {
673 VERIFY(m_pending_symbol_size <= block_size + 1);
674 auto index = m_pending_symbol_size++;
675 m_symbol_buffer[index].distance = distance;
676 m_symbol_buffer[index].length = length;
677 m_symbol_frequencies[length_to_symbol[length]]++;
678 m_distance_frequencies[distance_to_base(distance)]++;
679 };
680
681 size_t previous_match_length = 0;
682 size_t previous_match_position = 0;
683
684 VERIFY(m_compression_constants.great_match_length <= max_match_length);
685
686 // our block starts at block_size and is m_pending_block_size in length
687 auto block_end = block_size + m_pending_block_size;
688 size_t current_position;
689 for (current_position = block_size; current_position < block_end - min_match_length + 1; current_position++) {
690 auto hash = hash_sequence(&m_rolling_window[current_position]);
691 size_t match_position;
692 auto match_length = find_back_match(current_position, hash, previous_match_length,
693 min(m_compression_constants.great_match_length, block_end - current_position), match_position);
694
695 insert_hash(current_position, hash);
696
697 // if the previous match is as good as the new match, just use it
698 if (previous_match_length != 0 && previous_match_length >= match_length) {
699 emit_back_reference((current_position - 1) - previous_match_position, previous_match_length);
700
701 // skip all the bytes that are included in this match
702 for (size_t j = current_position + 1; j < min(current_position - 1 + previous_match_length, block_end - min_match_length + 1); j++) {
703 insert_hash(j, hash_sequence(&m_rolling_window[j]));
704 }
705 current_position = (current_position - 1) + previous_match_length - 1;
706 previous_match_length = 0;
707 continue;
708 }
709
710 if (match_length == 0) {
711 VERIFY(previous_match_length == 0);
712 emit_literal(m_rolling_window[current_position]);
713 continue;
714 }
715
716 // if this is a lazy match, and the new match is better than the old one, output previous as literal
717 if (previous_match_length != 0) {
718 emit_literal(m_rolling_window[current_position - 1]);
719 }
720
721 previous_match_length = match_length;
722 previous_match_position = match_position;
723 }
724
725 // clean up leftover lazy match
726 if (previous_match_length != 0) {
727 emit_back_reference((current_position - 1) - previous_match_position, previous_match_length);
728 current_position = (current_position - 1) + previous_match_length;
729 }
730
731 // output remaining literals
732 while (current_position < block_end) {
733 emit_literal(m_rolling_window[current_position++]);
734 }
735}
736
737size_t DeflateCompressor::huffman_block_length(Array<u8, max_huffman_literals> const& literal_bit_lengths, Array<u8, max_huffman_distances> const& distance_bit_lengths)
738{
739 size_t length = 0;
740
741 for (size_t i = 0; i < 286; i++) {
742 auto frequency = m_symbol_frequencies[i];
743 length += literal_bit_lengths[i] * frequency;
744
745 if (i >= 257) // back reference length symbols
746 length += packed_length_symbols[i - 257].extra_bits * frequency;
747 }
748
749 for (size_t i = 0; i < 30; i++) {
750 auto frequency = m_distance_frequencies[i];
751 length += distance_bit_lengths[i] * frequency;
752 length += packed_distances[i].extra_bits * frequency;
753 }
754
755 return length;
756}
757
758size_t DeflateCompressor::uncompressed_block_length()
759{
760 auto padding = 8 - ((m_output_stream->bit_offset() + 3) % 8);
761 // 3 bit block header + align to byte + 2 * 16 bit length fields + block contents
762 return 3 + padding + (2 * 16) + m_pending_block_size * 8;
763}
764
765size_t DeflateCompressor::fixed_block_length()
766{
767 // block header + fixed huffman encoded block contents
768 return 3 + huffman_block_length(fixed_literal_bit_lengths, fixed_distance_bit_lengths);
769}
770
771size_t DeflateCompressor::dynamic_block_length(Array<u8, max_huffman_literals> const& literal_bit_lengths, Array<u8, max_huffman_distances> const& distance_bit_lengths, Array<u8, 19> const& code_lengths_bit_lengths, Array<u16, 19> const& code_lengths_frequencies, size_t code_lengths_count)
772{
773 // block header + literal code count + distance code count + code length count
774 auto length = 3 + 5 + 5 + 4;
775
776 // 3 bits per code_length
777 length += 3 * code_lengths_count;
778
779 for (size_t i = 0; i < code_lengths_frequencies.size(); i++) {
780 auto frequency = code_lengths_frequencies[i];
781 length += code_lengths_bit_lengths[i] * frequency;
782
783 if (i == deflate_special_code_length_copy) {
784 length += 2 * frequency;
785 } else if (i == deflate_special_code_length_zeros) {
786 length += 3 * frequency;
787 } else if (i == deflate_special_code_length_long_zeros) {
788 length += 7 * frequency;
789 }
790 }
791
792 return length + huffman_block_length(literal_bit_lengths, distance_bit_lengths);
793}
794
795ErrorOr<void> DeflateCompressor::write_huffman(CanonicalCode const& literal_code, Optional<CanonicalCode> const& distance_code)
796{
797 auto has_distances = distance_code.has_value();
798 for (size_t i = 0; i < m_pending_symbol_size; i++) {
799 if (m_symbol_buffer[i].distance == 0) {
800 TRY(literal_code.write_symbol(*m_output_stream, m_symbol_buffer[i].literal));
801 continue;
802 }
803 VERIFY(has_distances);
804 auto symbol = length_to_symbol[m_symbol_buffer[i].length];
805 TRY(literal_code.write_symbol(*m_output_stream, symbol));
806 // Emit extra bits if needed
807 TRY(m_output_stream->write_bits<u16>(m_symbol_buffer[i].length - packed_length_symbols[symbol - 257].base_length, packed_length_symbols[symbol - 257].extra_bits));
808
809 auto base_distance = distance_to_base(m_symbol_buffer[i].distance);
810 TRY(distance_code.value().write_symbol(*m_output_stream, base_distance));
811 // Emit extra bits if needed
812 TRY(m_output_stream->write_bits<u16>(m_symbol_buffer[i].distance - packed_distances[base_distance].base_distance, packed_distances[base_distance].extra_bits));
813 }
814 return {};
815}
816
817size_t DeflateCompressor::encode_huffman_lengths(Array<u8, max_huffman_literals + max_huffman_distances> const& lengths, size_t lengths_count, Array<code_length_symbol, max_huffman_literals + max_huffman_distances>& encoded_lengths)
818{
819 size_t encoded_count = 0;
820 size_t i = 0;
821 while (i < lengths_count) {
822 if (lengths[i] == 0) {
823 auto zero_count = 0;
824 for (size_t j = i; j < min(lengths_count, i + 138) && lengths[j] == 0; j++)
825 zero_count++;
826
827 if (zero_count < 3) { // below minimum repeated zero count
828 encoded_lengths[encoded_count++].symbol = 0;
829 i++;
830 continue;
831 }
832
833 if (zero_count <= 10) {
834 encoded_lengths[encoded_count].symbol = deflate_special_code_length_zeros;
835 encoded_lengths[encoded_count++].count = zero_count;
836 } else {
837 encoded_lengths[encoded_count].symbol = deflate_special_code_length_long_zeros;
838 encoded_lengths[encoded_count++].count = zero_count;
839 }
840 i += zero_count;
841 continue;
842 }
843
844 encoded_lengths[encoded_count++].symbol = lengths[i++];
845
846 auto copy_count = 0;
847 for (size_t j = i; j < min(lengths_count, i + 6) && lengths[j] == lengths[i - 1]; j++)
848 copy_count++;
849
850 if (copy_count >= 3) {
851 encoded_lengths[encoded_count].symbol = deflate_special_code_length_copy;
852 encoded_lengths[encoded_count++].count = copy_count;
853 i += copy_count;
854 continue;
855 }
856 }
857 return encoded_count;
858}
859
860size_t DeflateCompressor::encode_block_lengths(Array<u8, max_huffman_literals> const& literal_bit_lengths, Array<u8, max_huffman_distances> const& distance_bit_lengths, Array<code_length_symbol, max_huffman_literals + max_huffman_distances>& encoded_lengths, size_t& literal_code_count, size_t& distance_code_count)
861{
862 literal_code_count = max_huffman_literals;
863 distance_code_count = max_huffman_distances;
864
865 VERIFY(literal_bit_lengths[256] != 0); // Make sure at least the EndOfBlock marker is present
866 while (literal_bit_lengths[literal_code_count - 1] == 0)
867 literal_code_count--;
868
869 // Drop trailing zero lengths, keeping at least one
870 while (distance_bit_lengths[distance_code_count - 1] == 0 && distance_code_count > 1)
871 distance_code_count--;
872
873 Array<u8, max_huffman_literals + max_huffman_distances> all_lengths {};
874 size_t lengths_count = 0;
875 for (size_t i = 0; i < literal_code_count; i++) {
876 all_lengths[lengths_count++] = literal_bit_lengths[i];
877 }
878 for (size_t i = 0; i < distance_code_count; i++) {
879 all_lengths[lengths_count++] = distance_bit_lengths[i];
880 }
881
882 return encode_huffman_lengths(all_lengths, lengths_count, encoded_lengths);
883}
884
885ErrorOr<void> DeflateCompressor::write_dynamic_huffman(CanonicalCode const& literal_code, size_t literal_code_count, Optional<CanonicalCode> const& distance_code, size_t distance_code_count, Array<u8, 19> const& code_lengths_bit_lengths, size_t code_length_count, Array<code_length_symbol, max_huffman_literals + max_huffman_distances> const& encoded_lengths, size_t encoded_lengths_count)
886{
887 TRY(m_output_stream->write_bits(literal_code_count - 257, 5));
888 TRY(m_output_stream->write_bits(distance_code_count - 1, 5));
889 TRY(m_output_stream->write_bits(code_length_count - 4, 4));
890
891 for (size_t i = 0; i < code_length_count; i++) {
892 TRY(m_output_stream->write_bits(code_lengths_bit_lengths[code_lengths_code_lengths_order[i]], 3));
893 }
894
895 auto code_lengths_code = CanonicalCode::from_bytes(code_lengths_bit_lengths);
896 VERIFY(code_lengths_code.has_value());
897 for (size_t i = 0; i < encoded_lengths_count; i++) {
898 auto encoded_length = encoded_lengths[i];
899 TRY(code_lengths_code->write_symbol(*m_output_stream, encoded_length.symbol));
900 if (encoded_length.symbol == deflate_special_code_length_copy) {
901 TRY(m_output_stream->write_bits<u8>(encoded_length.count - 3, 2));
902 } else if (encoded_length.symbol == deflate_special_code_length_zeros) {
903 TRY(m_output_stream->write_bits<u8>(encoded_length.count - 3, 3));
904 } else if (encoded_length.symbol == deflate_special_code_length_long_zeros) {
905 TRY(m_output_stream->write_bits<u8>(encoded_length.count - 11, 7));
906 }
907 }
908
909 TRY(write_huffman(literal_code, distance_code));
910 return {};
911}
912
913ErrorOr<void> DeflateCompressor::flush()
914{
915 TRY(m_output_stream->write_bits(m_finished, 1));
916
917 // if this is just an empty block to signify the end of the deflate stream use the smallest block possible (10 bits total)
918 if (m_pending_block_size == 0) {
919 VERIFY(m_finished); // we shouldn't be writing empty blocks unless this is the final one
920 TRY(m_output_stream->write_bits(0b01u, 2)); // fixed huffman codes
921 TRY(m_output_stream->write_bits(0b0000000u, 7)); // end of block symbol
922 TRY(m_output_stream->align_to_byte_boundary());
923 return {};
924 }
925
926 auto write_uncompressed = [&]() -> ErrorOr<void> {
927 TRY(m_output_stream->write_bits(0b00u, 2)); // no compression
928 TRY(m_output_stream->align_to_byte_boundary());
929 LittleEndian<u16> len = m_pending_block_size;
930 TRY(m_output_stream->write_until_depleted(len.bytes()));
931 LittleEndian<u16> nlen = ~m_pending_block_size;
932 TRY(m_output_stream->write_until_depleted(nlen.bytes()));
933 TRY(m_output_stream->write_until_depleted(pending_block().slice(0, m_pending_block_size)));
934 return {};
935 };
936
937 if (m_compression_level == CompressionLevel::STORE) { // disabled compression fast path
938 TRY(write_uncompressed());
939 m_pending_block_size = 0;
940 return {};
941 }
942
943 // The following implementation of lz77 compression and huffman encoding is based on the reference implementation by Hans Wennborg https://www.hanshq.net/zip.html
944
945 // this reads from the pending block and writes to m_symbol_buffer
946 lz77_compress_block();
947
948 // insert EndOfBlock marker to the symbol buffer
949 m_symbol_buffer[m_pending_symbol_size].distance = 0;
950 m_symbol_buffer[m_pending_symbol_size++].literal = 256;
951 m_symbol_frequencies[256]++;
952
953 // generate optimal dynamic huffman code lengths
954 Array<u8, max_huffman_literals> dynamic_literal_bit_lengths {};
955 Array<u8, max_huffman_distances> dynamic_distance_bit_lengths {};
956 generate_huffman_lengths(dynamic_literal_bit_lengths, m_symbol_frequencies, 15); // deflate data huffman can use up to 15 bits per symbol
957 generate_huffman_lengths(dynamic_distance_bit_lengths, m_distance_frequencies, 15);
958
959 // encode literal and distance lengths together in deflate format
960 Array<code_length_symbol, max_huffman_literals + max_huffman_distances> encoded_lengths {};
961 size_t literal_code_count;
962 size_t distance_code_count;
963 auto encoded_lengths_count = encode_block_lengths(dynamic_literal_bit_lengths, dynamic_distance_bit_lengths, encoded_lengths, literal_code_count, distance_code_count);
964
965 // count code length frequencies
966 Array<u16, 19> code_lengths_frequencies { 0 };
967 for (size_t i = 0; i < encoded_lengths_count; i++) {
968 code_lengths_frequencies[encoded_lengths[i].symbol]++;
969 }
970 // generate optimal huffman code lengths code lengths
971 Array<u8, 19> code_lengths_bit_lengths {};
972 generate_huffman_lengths(code_lengths_bit_lengths, code_lengths_frequencies, 7); // deflate code length huffman can use up to 7 bits per symbol
973 // calculate actual code length code lengths count (without trailing zeros)
974 auto code_lengths_count = code_lengths_bit_lengths.size();
975 while (code_lengths_bit_lengths[code_lengths_code_lengths_order[code_lengths_count - 1]] == 0)
976 code_lengths_count--;
977
978 auto uncompressed_size = uncompressed_block_length();
979 auto fixed_huffman_size = fixed_block_length();
980 auto dynamic_huffman_size = dynamic_block_length(dynamic_literal_bit_lengths, dynamic_distance_bit_lengths, code_lengths_bit_lengths, code_lengths_frequencies, code_lengths_count);
981
982 // If the compression somehow didn't reduce the size enough, just write out the block uncompressed as it allows for much faster decompression
983 if (uncompressed_size <= min(fixed_huffman_size, dynamic_huffman_size)) {
984 TRY(write_uncompressed());
985 } else if (fixed_huffman_size <= dynamic_huffman_size) {
986 // If the fixed and dynamic huffman codes come out the same size, prefer the fixed version, as it takes less time to decode fixed huffman codes.
987 TRY(m_output_stream->write_bits(0b01u, 2));
988 TRY(write_huffman(CanonicalCode::fixed_literal_codes(), CanonicalCode::fixed_distance_codes()));
989 } else {
990 // dynamic huffman codes
991 TRY(m_output_stream->write_bits(0b10u, 2));
992 auto literal_code = CanonicalCode::from_bytes(dynamic_literal_bit_lengths);
993 VERIFY(literal_code.has_value());
994 auto distance_code = CanonicalCode::from_bytes(dynamic_distance_bit_lengths);
995 TRY(write_dynamic_huffman(literal_code.value(), literal_code_count, distance_code, distance_code_count, code_lengths_bit_lengths, code_lengths_count, encoded_lengths, encoded_lengths_count));
996 }
997 if (m_finished)
998 TRY(m_output_stream->align_to_byte_boundary());
999
1000 // reset all block specific members
1001 m_pending_block_size = 0;
1002 m_pending_symbol_size = 0;
1003 m_symbol_frequencies.fill(0);
1004 m_distance_frequencies.fill(0);
1005 // On the final block this copy will potentially produce an invalid search window, but since its the final block we dont care
1006 pending_block().copy_trimmed_to({ m_rolling_window, block_size });
1007
1008 return {};
1009}
1010
1011ErrorOr<void> DeflateCompressor::final_flush()
1012{
1013 VERIFY(!m_finished);
1014 m_finished = true;
1015 TRY(flush());
1016 return {};
1017}
1018
1019ErrorOr<ByteBuffer> DeflateCompressor::compress_all(ReadonlyBytes bytes, CompressionLevel compression_level)
1020{
1021 auto output_stream = TRY(try_make<AllocatingMemoryStream>());
1022 auto deflate_stream = TRY(DeflateCompressor::construct(MaybeOwned<Stream>(*output_stream), compression_level));
1023
1024 TRY(deflate_stream->write_until_depleted(bytes));
1025 TRY(deflate_stream->final_flush());
1026
1027 auto buffer = TRY(ByteBuffer::create_uninitialized(output_stream->used_buffer_size()));
1028 TRY(output_stream->read_until_filled(buffer));
1029
1030 return buffer;
1031}
1032
1033}