317 void compress_fixed_block(writer_type& writer, std::span< std::byte const > input,
bool final_block, std::int32_t level)
319 constexpr std::array< std::uint16_t, 29U > length_bases{3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 13U, 15U, 17U, 19U, 23U, 27U, 31U, 35U, 43U, 51U, 59U, 67U, 83U, 99U, 115U, 131U, 163U, 195U, 227U, 258U};
320 constexpr std::array< std::uint8_t, 29U > length_extras{0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 1U, 1U, 1U, 2U, 2U, 2U, 2U, 3U, 3U, 3U, 3U, 4U, 4U, 4U, 4U, 5U, 5U, 5U, 5U, 0U};
321 constexpr std::array< std::uint16_t, 30U > distance_bases{1U, 2U, 3U, 4U, 5U, 7U, 9U, 13U, 17U, 25U, 33U, 49U, 65U, 97U, 129U, 193U, 257U, 385U, 513U, 769U, 1025U, 1537U, 2049U, 3073U, 4097U, 6145U, 8193U, 12289U, 16385U, 24577U};
322 constexpr std::array< std::uint8_t, 30U > distance_extras{0U, 0U, 0U, 0U, 1U, 1U, 2U, 2U, 3U, 3U, 4U, 4U, 5U, 5U, 6U, 6U, 7U, 7U, 8U, 8U, 9U, 9U, 10U, 10U, 11U, 11U, 12U, 12U, 13U, 13U};
324 writer.write_bits(final_block ? 1U : 0U, 1U);
325 writer.write_bits(1U, 2U);
326 constexpr std::size_t no_position = std::numeric_limits< std::size_t >::max();
327 std::array< std::size_t, 65536U > hash_heads{};
328 hash_heads.fill(no_position);
329 std::vector< std::size_t > previous(input.size(), no_position);
330 std::size_t position = 0U;
331 std::size_t
const maximum_search_depth = 8U +
static_cast< std::size_t
>(level) * 28U;
332 while (position < input.size())
334 std::size_t best_length = 0U;
335 std::size_t best_distance = 0U;
336 if (position + 2U < input.size())
338 std::uint32_t
const hash = (
static_cast< std::uint32_t
>(std::to_integer< std::uint8_t >(input[position])) * 251U ^
static_cast< std::uint32_t
>(std::to_integer< std::uint8_t >(input[position + 1U])) * 31U ^ std::to_integer< std::uint8_t >(input[position + 2U])) & 0xffffU;
339 std::size_t candidate = hash_heads[hash];
340 previous[position] = candidate;
341 hash_heads[hash] = position;
342 std::size_t depth = 0U;
343 std::size_t
const maximum_length = std::min< std::size_t >(258U, input.size() - position);
344 while (candidate != no_position && position - candidate <= 32768U && depth < maximum_search_depth)
346 std::size_t length = 0U;
347 while (length < maximum_length && input[candidate + length] == input[position + length])
351 if (length > best_length && length >= 3U)
353 best_length = length;
354 best_distance = position - candidate;
356 candidate = previous[candidate];
360 if (best_length < 3U)
365 std::size_t length_index = 0U;
366 while (length_index + 1U < length_bases.size() && best_length >= length_bases[length_index + 1U])
371 writer.write_bits(
static_cast< std::uint32_t
>(best_length - length_bases[length_index]), length_extras[length_index]);
372 std::size_t distance_index = 0U;
373 while (distance_index + 1U < distance_bases.size() && best_distance >= distance_bases[distance_index + 1U])
377 writer.write_bits(
reverse_bits(
static_cast< std::uint16_t
>(distance_index), 5U), 5U);
378 writer.write_bits(
static_cast< std::uint32_t
>(best_distance - distance_bases[distance_index]), distance_extras[distance_index]);
379 for (std::size_t offset = 1U; offset < best_length; ++offset)
381 std::size_t
const inserted = position + offset;
382 if (inserted + 2U >= input.size())
386 std::uint32_t
const hash = (
static_cast< std::uint32_t
>(std::to_integer< std::uint8_t >(input[inserted])) * 251U ^
static_cast< std::uint32_t
>(std::to_integer< std::uint8_t >(input[inserted + 1U])) * 31U ^ std::to_integer< std::uint8_t >(input[inserted + 2U])) & 0xffffU;
387 previous[inserted] = hash_heads[hash];
388 hash_heads[hash] = inserted;
390 position += best_length;
520 constexpr std::array< std::uint16_t, 29U > length_bases{3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 13U, 15U, 17U, 19U, 23U, 27U, 31U, 35U, 43U, 51U, 59U, 67U, 83U, 99U, 115U, 131U, 163U, 195U, 227U, 258U};
521 constexpr std::array< std::uint8_t, 29U > length_extras{0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 1U, 1U, 1U, 2U, 2U, 2U, 2U, 3U, 3U, 3U, 3U, 4U, 4U, 4U, 4U, 5U, 5U, 5U, 5U, 0U};
522 constexpr std::array< std::uint16_t, 30U > distance_bases{1U, 2U, 3U, 4U, 5U, 7U, 9U, 13U, 17U, 25U, 33U, 49U, 65U, 97U, 129U, 193U, 257U, 385U, 513U, 769U, 1025U, 1537U, 2049U, 3073U, 4097U, 6145U, 8193U, 12289U, 16385U, 24577U};
523 constexpr std::array< std::uint8_t, 30U > distance_extras{0U, 0U, 0U, 0U, 1U, 1U, 2U, 2U, 3U, 3U, 4U, 4U, 5U, 5U, 6U, 6U, 7U, 7U, 8U, 8U, 9U, 9U, 10U, 10U, 11U, 11U, 12U, 12U, 13U, 13U};
526 auto read_byte = [&]() -> std::byte
529 if (!source.
read(value))
535 auto read_u32 = [&](
bool little_endian) -> std::uint32_t
537 std::uint32_t value = 0U;
538 for (std::uint8_t index = 0U; index < 4U; ++index)
540 std::uint8_t
const shift = little_endian ? index * 8U :
static_cast< std::uint8_t
>((3U - index) * 8U);
541 value |=
static_cast< std::uint32_t
>(std::to_integer< std::uint8_t >(read_byte())) << shift;
546 std::size_t total_output = 0U;
547 bool decoded_member =
false;
556 std::uint8_t
const method = std::to_integer< std::uint8_t >(read_byte());
557 std::uint8_t
const flags = std::to_integer< std::uint8_t >(read_byte());
558 if ((method & 0x0fU) != 8U || (method >> 4U) > 7U || (
static_cast< std::uint16_t
>(method) * 256U + flags) % 31U != 0U || (flags & 0x20U) != 0U)
566 auto read_header_byte = [&]() -> std::byte
568 std::byte
const value = read_byte();
572 if (read_header_byte() != std::byte{0x1f} || read_header_byte() != std::byte{0x8b} || read_header_byte() != std::byte{0x08})
576 std::uint8_t
const flags = std::to_integer< std::uint8_t >(read_header_byte());
577 if ((flags & 0xe0U) != 0U)
581 for (std::size_t index = 0U; index < 6U; ++index)
583 static_cast< void >(read_header_byte());
585 if ((flags & 0x04U) != 0U)
587 std::uint16_t
const extra_size =
static_cast< std::uint16_t
>(std::to_integer< std::uint8_t >(read_header_byte()) | (
static_cast< std::uint16_t
>(std::to_integer< std::uint8_t >(read_header_byte())) << 8U));
588 for (std::size_t index = 0U; index < extra_size; ++index)
590 static_cast< void >(read_header_byte());
593 for (std::uint8_t flag : {std::uint8_t{0x08U}, std::uint8_t{0x10U}})
595 if ((flags & flag) != 0U)
597 while (read_header_byte() != std::byte{0x00})
602 if ((flags & 0x02U) != 0U)
604 std::uint16_t
const expected =
static_cast< std::uint16_t
>(std::to_integer< std::uint8_t >(read_byte()) | (
static_cast< std::uint16_t
>(std::to_integer< std::uint8_t >(read_byte())) << 8U));
605 if (
static_cast< std::uint16_t
>(header_crc.
value()) != expected)
613 std::array< std::byte, 32768U > history{};
614 std::size_t member_size = 0U;
617 auto emit = [&](std::byte value)
623 history[member_size % history.size()] = value;
627 member_adler.
update(value);
631 bool final_block =
false;
634 final_block = reader.read_bits(1U) != 0U;
635 std::uint32_t
const block_type = reader.read_bits(2U);
636 if (block_type == 0U)
638 reader.align_to_byte();
639 std::uint16_t
const length =
static_cast< std::uint16_t
>(reader.read_bits(16U));
640 std::uint16_t
const inverse =
static_cast< std::uint16_t
>(reader.read_bits(16U));
641 if (
static_cast< std::uint16_t
>(length ^ inverse) != 0xffffU)
645 for (std::size_t index = 0U; index < length; ++index)
647 emit(
static_cast< std::byte
>(reader.read_bits(8U)));
651 if (block_type == 3U)
657 if (block_type == 1U)
659 std::array< std::uint8_t, 288U > literal_lengths{};
660 std::fill(literal_lengths.begin(), literal_lengths.begin() + 144, 8U);
661 std::fill(literal_lengths.begin() + 144, literal_lengths.begin() + 256, 9U);
662 std::fill(literal_lengths.begin() + 256, literal_lengths.begin() + 280, 7U);
663 std::fill(literal_lengths.begin() + 280, literal_lengths.end(), 8U);
664 std::array< std::uint8_t, 32U > distance_lengths{};
665 distance_lengths.fill(5U);
666 literal_decoder.
build(literal_lengths, stream_format);
667 distance_decoder.
build(distance_lengths, stream_format);
671 std::size_t
const literal_count = reader.read_bits(5U) + 257U;
672 std::size_t
const distance_count = reader.read_bits(5U) + 1U;
673 std::size_t
const code_length_count = reader.read_bits(4U) + 4U;
674 constexpr std::array< std::uint8_t, 19U > order{16U, 17U, 18U, 0U, 8U, 7U, 9U, 6U, 10U, 5U, 11U, 4U, 12U, 3U, 13U, 2U, 14U, 1U, 15U};
675 std::array< std::uint8_t, 19U > code_lengths{};
676 for (std::size_t index = 0U; index < code_length_count; ++index)
678 code_lengths[order[index]] =
static_cast< std::uint8_t
>(reader.read_bits(3U));
681 code_length_decoder.
build(code_lengths, stream_format);
682 std::vector< std::uint8_t > lengths;
683 lengths.reserve(literal_count + distance_count);
684 while (lengths.size() < literal_count + distance_count)
686 std::uint16_t
const symbol = code_length_decoder.
decode(reader, stream_format);
689 lengths.push_back(
static_cast< std::uint8_t
>(symbol));
691 else if (symbol == 16U)
697 std::size_t
const repeat = reader.read_bits(2U) + 3U;
698 if (repeat > literal_count + distance_count - lengths.size())
702 lengths.insert(lengths.end(), repeat, lengths.back());
704 else if (symbol == 17U || symbol == 18U)
706 std::size_t
const repeat = symbol == 17U ? reader.read_bits(3U) + 3U : reader.read_bits(7U) + 11U;
707 if (repeat > literal_count + distance_count - lengths.size())
711 lengths.insert(lengths.end(), repeat, 0U);
718 if (lengths[256U] == 0U)
722 literal_decoder.
build(std::span< std::uint8_t const >(lengths.data(), literal_count), stream_format);
723 distance_decoder.
build(std::span< std::uint8_t const >(lengths.data() + literal_count, distance_count), stream_format,
true);
727 std::uint16_t
const symbol = literal_decoder.
decode(reader, stream_format);
730 emit(
static_cast< std::byte
>(symbol));
737 if (symbol < 257U || symbol > 285U)
741 std::size_t
const length_index = symbol - 257U;
742 std::size_t
const length = length_bases[length_index] + reader.read_bits(length_extras[length_index]);
743 std::uint16_t
const distance_symbol = distance_decoder.
decode(reader, stream_format);
744 if (distance_symbol >= distance_bases.size())
748 std::size_t
const distance = distance_bases[distance_symbol] + reader.read_bits(distance_extras[distance_symbol]);
749 if (distance == 0U || distance > member_size || distance > history.size())
753 for (std::size_t index = 0U; index < length; ++index)
755 emit(history[(member_size - distance) % history.size()]);
759 reader.align_to_byte();
764 if (stream_format ==
format::gzip && (read_u32(
true) != member_crc.
value() || read_u32(
true) !=
static_cast< std::uint32_t
>(member_size)))
768 decoded_member =
true;
769 }
while (!source.
empty());