brotli 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +6 -3
  3. data/.github/workflows/publish.yml +7 -17
  4. data/.gitmodules +1 -1
  5. data/README.md +2 -2
  6. data/ext/brotli/brotli.c +8 -0
  7. data/ext/brotli/extconf.rb +6 -0
  8. data/lib/brotli/version.rb +1 -1
  9. data/test/brotli_test.rb +14 -1
  10. data/test/test_helper.rb +1 -0
  11. data/vendor/brotli/c/common/constants.c +1 -1
  12. data/vendor/brotli/c/common/constants.h +2 -1
  13. data/vendor/brotli/c/common/context.c +1 -1
  14. data/vendor/brotli/c/common/dictionary.c +5 -3
  15. data/vendor/brotli/c/common/platform.c +2 -1
  16. data/vendor/brotli/c/common/platform.h +60 -113
  17. data/vendor/brotli/c/common/shared_dictionary.c +521 -0
  18. data/vendor/brotli/c/common/shared_dictionary_internal.h +75 -0
  19. data/vendor/brotli/c/common/transform.c +1 -1
  20. data/vendor/brotli/c/common/version.h +31 -6
  21. data/vendor/brotli/c/dec/bit_reader.c +10 -8
  22. data/vendor/brotli/c/dec/bit_reader.h +172 -100
  23. data/vendor/brotli/c/dec/decode.c +467 -200
  24. data/vendor/brotli/c/dec/huffman.c +7 -4
  25. data/vendor/brotli/c/dec/huffman.h +2 -1
  26. data/vendor/brotli/c/dec/prefix.h +2 -1
  27. data/vendor/brotli/c/dec/state.c +33 -9
  28. data/vendor/brotli/c/dec/state.h +70 -35
  29. data/vendor/brotli/c/enc/backward_references.c +81 -19
  30. data/vendor/brotli/c/enc/backward_references.h +5 -4
  31. data/vendor/brotli/c/enc/backward_references_hq.c +148 -52
  32. data/vendor/brotli/c/enc/backward_references_hq.h +6 -5
  33. data/vendor/brotli/c/enc/backward_references_inc.h +31 -5
  34. data/vendor/brotli/c/enc/bit_cost.c +8 -7
  35. data/vendor/brotli/c/enc/bit_cost.h +5 -4
  36. data/vendor/brotli/c/enc/block_splitter.c +37 -14
  37. data/vendor/brotli/c/enc/block_splitter.h +5 -4
  38. data/vendor/brotli/c/enc/block_splitter_inc.h +86 -45
  39. data/vendor/brotli/c/enc/brotli_bit_stream.c +132 -110
  40. data/vendor/brotli/c/enc/brotli_bit_stream.h +11 -6
  41. data/vendor/brotli/c/enc/cluster.c +10 -9
  42. data/vendor/brotli/c/enc/cluster.h +7 -6
  43. data/vendor/brotli/c/enc/cluster_inc.h +25 -20
  44. data/vendor/brotli/c/enc/command.c +1 -1
  45. data/vendor/brotli/c/enc/command.h +5 -4
  46. data/vendor/brotli/c/enc/compound_dictionary.c +207 -0
  47. data/vendor/brotli/c/enc/compound_dictionary.h +74 -0
  48. data/vendor/brotli/c/enc/compress_fragment.c +93 -83
  49. data/vendor/brotli/c/enc/compress_fragment.h +32 -7
  50. data/vendor/brotli/c/enc/compress_fragment_two_pass.c +99 -87
  51. data/vendor/brotli/c/enc/compress_fragment_two_pass.h +21 -3
  52. data/vendor/brotli/c/enc/dictionary_hash.c +3 -1
  53. data/vendor/brotli/c/enc/encode.c +473 -404
  54. data/vendor/brotli/c/enc/encoder_dict.c +611 -4
  55. data/vendor/brotli/c/enc/encoder_dict.h +117 -3
  56. data/vendor/brotli/c/enc/entropy_encode.c +3 -2
  57. data/vendor/brotli/c/enc/entropy_encode.h +2 -1
  58. data/vendor/brotli/c/enc/entropy_encode_static.h +5 -2
  59. data/vendor/brotli/c/enc/fast_log.c +1 -1
  60. data/vendor/brotli/c/enc/fast_log.h +2 -1
  61. data/vendor/brotli/c/enc/find_match_length.h +15 -22
  62. data/vendor/brotli/c/enc/hash.h +285 -45
  63. data/vendor/brotli/c/enc/hash_composite_inc.h +26 -11
  64. data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +20 -18
  65. data/vendor/brotli/c/enc/hash_longest_match64_inc.h +34 -39
  66. data/vendor/brotli/c/enc/hash_longest_match_inc.h +6 -10
  67. data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -4
  68. data/vendor/brotli/c/enc/hash_rolling_inc.h +4 -4
  69. data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +6 -5
  70. data/vendor/brotli/c/enc/histogram.c +4 -4
  71. data/vendor/brotli/c/enc/histogram.h +7 -6
  72. data/vendor/brotli/c/enc/literal_cost.c +20 -15
  73. data/vendor/brotli/c/enc/literal_cost.h +4 -2
  74. data/vendor/brotli/c/enc/memory.c +29 -5
  75. data/vendor/brotli/c/enc/memory.h +19 -2
  76. data/vendor/brotli/c/enc/metablock.c +72 -58
  77. data/vendor/brotli/c/enc/metablock.h +9 -8
  78. data/vendor/brotli/c/enc/metablock_inc.h +8 -6
  79. data/vendor/brotli/c/enc/params.h +4 -3
  80. data/vendor/brotli/c/enc/prefix.h +3 -2
  81. data/vendor/brotli/c/enc/quality.h +40 -3
  82. data/vendor/brotli/c/enc/ringbuffer.h +4 -3
  83. data/vendor/brotli/c/enc/state.h +104 -0
  84. data/vendor/brotli/c/enc/static_dict.c +60 -4
  85. data/vendor/brotli/c/enc/static_dict.h +3 -2
  86. data/vendor/brotli/c/enc/static_dict_lut.h +2 -0
  87. data/vendor/brotli/c/enc/utf8_util.c +1 -1
  88. data/vendor/brotli/c/enc/utf8_util.h +2 -1
  89. data/vendor/brotli/c/enc/write_bits.h +2 -1
  90. data/vendor/brotli/c/include/brotli/decode.h +67 -2
  91. data/vendor/brotli/c/include/brotli/encode.h +55 -2
  92. data/vendor/brotli/c/include/brotli/port.h +28 -11
  93. data/vendor/brotli/c/include/brotli/shared_dictionary.h +100 -0
  94. metadata +9 -3
@@ -8,20 +8,21 @@
8
8
  compression algorithms here, just the right ordering of bits to match the
9
9
  specs. */
10
10
 
11
- #include "./brotli_bit_stream.h"
11
+ #include "brotli_bit_stream.h"
12
12
 
13
13
  #include <string.h> /* memcpy, memset */
14
14
 
15
+ #include <brotli/types.h>
16
+
15
17
  #include "../common/constants.h"
16
18
  #include "../common/context.h"
17
19
  #include "../common/platform.h"
18
- #include <brotli/types.h>
19
- #include "./entropy_encode.h"
20
- #include "./entropy_encode_static.h"
21
- #include "./fast_log.h"
22
- #include "./histogram.h"
23
- #include "./memory.h"
24
- #include "./write_bits.h"
20
+ #include "entropy_encode.h"
21
+ #include "entropy_encode_static.h"
22
+ #include "fast_log.h"
23
+ #include "histogram.h"
24
+ #include "memory.h"
25
+ #include "write_bits.h"
25
26
 
26
27
  #if defined(__cplusplus) || defined(c_plusplus)
27
28
  extern "C" {
@@ -286,6 +287,7 @@ void BrotliStoreHuffmanTree(const uint8_t* depths, size_t num,
286
287
  /* Write the Huffman tree into the brotli-representation.
287
288
  The command alphabet is the largest, so this allocation will fit all
288
289
  alphabets. */
290
+ /* TODO(eustas): fix me */
289
291
  uint8_t huffman_tree[BROTLI_NUM_COMMAND_SYMBOLS];
290
292
  uint8_t huffman_tree_extra_bits[BROTLI_NUM_COMMAND_SYMBOLS];
291
293
  size_t huffman_tree_size = 0;
@@ -400,7 +402,7 @@ static BROTLI_INLINE BROTLI_BOOL SortHuffmanTree(
400
402
  return TO_BROTLI_BOOL(v0->total_count_ < v1->total_count_);
401
403
  }
402
404
 
403
- void BrotliBuildAndStoreHuffmanTreeFast(MemoryManager* m,
405
+ void BrotliBuildAndStoreHuffmanTreeFast(HuffmanTree* tree,
404
406
  const uint32_t* histogram,
405
407
  const size_t histogram_total,
406
408
  const size_t max_bits,
@@ -432,10 +434,7 @@ void BrotliBuildAndStoreHuffmanTreeFast(MemoryManager* m,
432
434
 
433
435
  memset(depth, 0, length * sizeof(depth[0]));
434
436
  {
435
- const size_t max_tree_size = 2 * length + 1;
436
- HuffmanTree* tree = BROTLI_ALLOC(m, HuffmanTree, max_tree_size);
437
437
  uint32_t count_limit;
438
- if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(tree)) return;
439
438
  for (count_limit = 1; ; count_limit *= 2) {
440
439
  HuffmanTree* node = tree;
441
440
  size_t l;
@@ -500,7 +499,6 @@ void BrotliBuildAndStoreHuffmanTreeFast(MemoryManager* m,
500
499
  }
501
500
  }
502
501
  }
503
- BROTLI_FREE(m, tree);
504
502
  }
505
503
  BrotliConvertBitDepthsToSymbols(depth, length, bits);
506
504
  if (count <= 4) {
@@ -677,7 +675,14 @@ static void RunLengthCodeZeros(const size_t in_size,
677
675
 
678
676
  #define SYMBOL_BITS 9
679
677
 
678
+ typedef struct EncodeContextMapArena {
679
+ uint32_t histogram[BROTLI_MAX_CONTEXT_MAP_SYMBOLS];
680
+ uint8_t depths[BROTLI_MAX_CONTEXT_MAP_SYMBOLS];
681
+ uint16_t bits[BROTLI_MAX_CONTEXT_MAP_SYMBOLS];
682
+ } EncodeContextMapArena;
683
+
680
684
  static void EncodeContextMap(MemoryManager* m,
685
+ EncodeContextMapArena* arena,
681
686
  const uint32_t* context_map,
682
687
  size_t context_map_size,
683
688
  size_t num_clusters,
@@ -687,10 +692,10 @@ static void EncodeContextMap(MemoryManager* m,
687
692
  uint32_t* rle_symbols;
688
693
  uint32_t max_run_length_prefix = 6;
689
694
  size_t num_rle_symbols = 0;
690
- uint32_t histogram[BROTLI_MAX_CONTEXT_MAP_SYMBOLS];
695
+ uint32_t* BROTLI_RESTRICT const histogram = arena->histogram;
691
696
  static const uint32_t kSymbolMask = (1u << SYMBOL_BITS) - 1u;
692
- uint8_t depths[BROTLI_MAX_CONTEXT_MAP_SYMBOLS];
693
- uint16_t bits[BROTLI_MAX_CONTEXT_MAP_SYMBOLS];
697
+ uint8_t* BROTLI_RESTRICT const depths = arena->depths;
698
+ uint16_t* BROTLI_RESTRICT const bits = arena->bits;
694
699
 
695
700
  StoreVarLenUint8(num_clusters - 1, storage_ix, storage);
696
701
 
@@ -703,7 +708,7 @@ static void EncodeContextMap(MemoryManager* m,
703
708
  MoveToFrontTransform(context_map, context_map_size, rle_symbols);
704
709
  RunLengthCodeZeros(context_map_size, rle_symbols,
705
710
  &num_rle_symbols, &max_run_length_prefix);
706
- memset(histogram, 0, sizeof(histogram));
711
+ memset(histogram, 0, sizeof(arena->histogram));
707
712
  for (i = 0; i < num_rle_symbols; ++i) {
708
713
  ++histogram[rle_symbols[i] & kSymbolMask];
709
714
  }
@@ -774,7 +779,7 @@ static void BuildAndStoreBlockSplitCode(const uint8_t* types,
774
779
  ++length_histo[BlockLengthPrefixCode(lengths[i])];
775
780
  }
776
781
  StoreVarLenUint8(num_types - 1, storage_ix, storage);
777
- if (num_types > 1) { /* TODO: else? could StoreBlockSwitch occur? */
782
+ if (num_types > 1) { /* TODO(eustas): else? could StoreBlockSwitch occur? */
778
783
  BuildAndStoreHuffmanTree(&type_histo[0], num_types + 2, num_types + 2, tree,
779
784
  &code->type_depths[0], &code->type_bits[0],
780
785
  storage_ix, storage);
@@ -787,7 +792,8 @@ static void BuildAndStoreBlockSplitCode(const uint8_t* types,
787
792
  }
788
793
 
789
794
  /* Stores a context map where the histogram type is always the block type. */
790
- static void StoreTrivialContextMap(size_t num_types,
795
+ static void StoreTrivialContextMap(EncodeContextMapArena* arena,
796
+ size_t num_types,
791
797
  size_t context_bits,
792
798
  HuffmanTree* tree,
793
799
  size_t* storage_ix,
@@ -797,9 +803,9 @@ static void StoreTrivialContextMap(size_t num_types,
797
803
  size_t repeat_code = context_bits - 1u;
798
804
  size_t repeat_bits = (1u << repeat_code) - 1u;
799
805
  size_t alphabet_size = num_types + repeat_code;
800
- uint32_t histogram[BROTLI_MAX_CONTEXT_MAP_SYMBOLS];
801
- uint8_t depths[BROTLI_MAX_CONTEXT_MAP_SYMBOLS];
802
- uint16_t bits[BROTLI_MAX_CONTEXT_MAP_SYMBOLS];
806
+ uint32_t* BROTLI_RESTRICT const histogram = arena->histogram;
807
+ uint8_t* BROTLI_RESTRICT const depths = arena->depths;
808
+ uint16_t* BROTLI_RESTRICT const bits = arena->bits;
803
809
  size_t i;
804
810
  memset(histogram, 0, alphabet_size * sizeof(histogram[0]));
805
811
  /* Write RLEMAX. */
@@ -914,17 +920,17 @@ static void StoreSymbolWithContext(BlockEncoder* self, size_t symbol,
914
920
 
915
921
  #define FN(X) X ## Literal
916
922
  /* NOLINTNEXTLINE(build/include) */
917
- #include "./block_encoder_inc.h"
923
+ #include "block_encoder_inc.h"
918
924
  #undef FN
919
925
 
920
926
  #define FN(X) X ## Command
921
927
  /* NOLINTNEXTLINE(build/include) */
922
- #include "./block_encoder_inc.h"
928
+ #include "block_encoder_inc.h"
923
929
  #undef FN
924
930
 
925
931
  #define FN(X) X ## Distance
926
932
  /* NOLINTNEXTLINE(build/include) */
927
- #include "./block_encoder_inc.h"
933
+ #include "block_encoder_inc.h"
928
934
  #undef FN
929
935
 
930
936
  static void JumpToByteBoundary(size_t* storage_ix, uint8_t* storage) {
@@ -932,6 +938,13 @@ static void JumpToByteBoundary(size_t* storage_ix, uint8_t* storage) {
932
938
  storage[*storage_ix >> 3] = 0;
933
939
  }
934
940
 
941
+ typedef struct StoreMetablockArena {
942
+ BlockEncoder literal_enc;
943
+ BlockEncoder command_enc;
944
+ BlockEncoder distance_enc;
945
+ EncodeContextMapArena context_map_arena;
946
+ } StoreMetablockArena;
947
+
935
948
  void BrotliStoreMetaBlock(MemoryManager* m,
936
949
  const uint8_t* input, size_t start_pos, size_t length, size_t mask,
937
950
  uint8_t prev_byte, uint8_t prev_byte2, BROTLI_BOOL is_last,
@@ -945,9 +958,10 @@ void BrotliStoreMetaBlock(MemoryManager* m,
945
958
  uint32_t num_effective_distance_symbols = params->dist.alphabet_size_limit;
946
959
  HuffmanTree* tree;
947
960
  ContextLut literal_context_lut = BROTLI_CONTEXT_LUT(literal_context_mode);
948
- BlockEncoder literal_enc;
949
- BlockEncoder command_enc;
950
- BlockEncoder distance_enc;
961
+ StoreMetablockArena* arena = NULL;
962
+ BlockEncoder* literal_enc = NULL;
963
+ BlockEncoder* command_enc = NULL;
964
+ BlockEncoder* distance_enc = NULL;
951
965
  const BrotliDistanceParams* dist = &params->dist;
952
966
  BROTLI_DCHECK(
953
967
  num_effective_distance_symbols <= BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS);
@@ -955,21 +969,24 @@ void BrotliStoreMetaBlock(MemoryManager* m,
955
969
  StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage);
956
970
 
957
971
  tree = BROTLI_ALLOC(m, HuffmanTree, MAX_HUFFMAN_TREE_SIZE);
958
- if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(tree)) return;
959
- InitBlockEncoder(&literal_enc, BROTLI_NUM_LITERAL_SYMBOLS,
972
+ arena = BROTLI_ALLOC(m, StoreMetablockArena, 1);
973
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(tree) || BROTLI_IS_NULL(arena)) return;
974
+ literal_enc = &arena->literal_enc;
975
+ command_enc = &arena->command_enc;
976
+ distance_enc = &arena->distance_enc;
977
+ InitBlockEncoder(literal_enc, BROTLI_NUM_LITERAL_SYMBOLS,
960
978
  mb->literal_split.num_types, mb->literal_split.types,
961
979
  mb->literal_split.lengths, mb->literal_split.num_blocks);
962
- InitBlockEncoder(&command_enc, BROTLI_NUM_COMMAND_SYMBOLS,
980
+ InitBlockEncoder(command_enc, BROTLI_NUM_COMMAND_SYMBOLS,
963
981
  mb->command_split.num_types, mb->command_split.types,
964
982
  mb->command_split.lengths, mb->command_split.num_blocks);
965
- InitBlockEncoder(&distance_enc, num_effective_distance_symbols,
983
+ InitBlockEncoder(distance_enc, num_effective_distance_symbols,
966
984
  mb->distance_split.num_types, mb->distance_split.types,
967
985
  mb->distance_split.lengths, mb->distance_split.num_blocks);
968
986
 
969
- BuildAndStoreBlockSwitchEntropyCodes(&literal_enc, tree, storage_ix, storage);
970
- BuildAndStoreBlockSwitchEntropyCodes(&command_enc, tree, storage_ix, storage);
971
- BuildAndStoreBlockSwitchEntropyCodes(
972
- &distance_enc, tree, storage_ix, storage);
987
+ BuildAndStoreBlockSwitchEntropyCodes(literal_enc, tree, storage_ix, storage);
988
+ BuildAndStoreBlockSwitchEntropyCodes(command_enc, tree, storage_ix, storage);
989
+ BuildAndStoreBlockSwitchEntropyCodes(distance_enc, tree, storage_ix, storage);
973
990
 
974
991
  BrotliWriteBits(2, dist->distance_postfix_bits, storage_ix, storage);
975
992
  BrotliWriteBits(
@@ -980,34 +997,36 @@ void BrotliStoreMetaBlock(MemoryManager* m,
980
997
  }
981
998
 
982
999
  if (mb->literal_context_map_size == 0) {
983
- StoreTrivialContextMap(mb->literal_histograms_size,
1000
+ StoreTrivialContextMap(
1001
+ &arena->context_map_arena, mb->literal_histograms_size,
984
1002
  BROTLI_LITERAL_CONTEXT_BITS, tree, storage_ix, storage);
985
1003
  } else {
986
- EncodeContextMap(m,
1004
+ EncodeContextMap(m, &arena->context_map_arena,
987
1005
  mb->literal_context_map, mb->literal_context_map_size,
988
1006
  mb->literal_histograms_size, tree, storage_ix, storage);
989
1007
  if (BROTLI_IS_OOM(m)) return;
990
1008
  }
991
1009
 
992
1010
  if (mb->distance_context_map_size == 0) {
993
- StoreTrivialContextMap(mb->distance_histograms_size,
1011
+ StoreTrivialContextMap(
1012
+ &arena->context_map_arena, mb->distance_histograms_size,
994
1013
  BROTLI_DISTANCE_CONTEXT_BITS, tree, storage_ix, storage);
995
1014
  } else {
996
- EncodeContextMap(m,
1015
+ EncodeContextMap(m, &arena->context_map_arena,
997
1016
  mb->distance_context_map, mb->distance_context_map_size,
998
1017
  mb->distance_histograms_size, tree, storage_ix, storage);
999
1018
  if (BROTLI_IS_OOM(m)) return;
1000
1019
  }
1001
1020
 
1002
- BuildAndStoreEntropyCodesLiteral(m, &literal_enc, mb->literal_histograms,
1021
+ BuildAndStoreEntropyCodesLiteral(m, literal_enc, mb->literal_histograms,
1003
1022
  mb->literal_histograms_size, BROTLI_NUM_LITERAL_SYMBOLS, tree,
1004
1023
  storage_ix, storage);
1005
1024
  if (BROTLI_IS_OOM(m)) return;
1006
- BuildAndStoreEntropyCodesCommand(m, &command_enc, mb->command_histograms,
1025
+ BuildAndStoreEntropyCodesCommand(m, command_enc, mb->command_histograms,
1007
1026
  mb->command_histograms_size, BROTLI_NUM_COMMAND_SYMBOLS, tree,
1008
1027
  storage_ix, storage);
1009
1028
  if (BROTLI_IS_OOM(m)) return;
1010
- BuildAndStoreEntropyCodesDistance(m, &distance_enc, mb->distance_histograms,
1029
+ BuildAndStoreEntropyCodesDistance(m, distance_enc, mb->distance_histograms,
1011
1030
  mb->distance_histograms_size, num_distance_symbols, tree,
1012
1031
  storage_ix, storage);
1013
1032
  if (BROTLI_IS_OOM(m)) return;
@@ -1016,12 +1035,12 @@ void BrotliStoreMetaBlock(MemoryManager* m,
1016
1035
  for (i = 0; i < n_commands; ++i) {
1017
1036
  const Command cmd = commands[i];
1018
1037
  size_t cmd_code = cmd.cmd_prefix_;
1019
- StoreSymbol(&command_enc, cmd_code, storage_ix, storage);
1038
+ StoreSymbol(command_enc, cmd_code, storage_ix, storage);
1020
1039
  StoreCommandExtra(&cmd, storage_ix, storage);
1021
1040
  if (mb->literal_context_map_size == 0) {
1022
1041
  size_t j;
1023
1042
  for (j = cmd.insert_len_; j != 0; --j) {
1024
- StoreSymbol(&literal_enc, input[pos & mask], storage_ix, storage);
1043
+ StoreSymbol(literal_enc, input[pos & mask], storage_ix, storage);
1025
1044
  ++pos;
1026
1045
  }
1027
1046
  } else {
@@ -1030,7 +1049,7 @@ void BrotliStoreMetaBlock(MemoryManager* m,
1030
1049
  size_t context =
1031
1050
  BROTLI_CONTEXT(prev_byte, prev_byte2, literal_context_lut);
1032
1051
  uint8_t literal = input[pos & mask];
1033
- StoreSymbolWithContext(&literal_enc, literal, context,
1052
+ StoreSymbolWithContext(literal_enc, literal, context,
1034
1053
  mb->literal_context_map, storage_ix, storage,
1035
1054
  BROTLI_LITERAL_CONTEXT_BITS);
1036
1055
  prev_byte2 = prev_byte;
@@ -1047,10 +1066,10 @@ void BrotliStoreMetaBlock(MemoryManager* m,
1047
1066
  uint32_t distnumextra = cmd.dist_prefix_ >> 10;
1048
1067
  uint64_t distextra = cmd.dist_extra_;
1049
1068
  if (mb->distance_context_map_size == 0) {
1050
- StoreSymbol(&distance_enc, dist_code, storage_ix, storage);
1069
+ StoreSymbol(distance_enc, dist_code, storage_ix, storage);
1051
1070
  } else {
1052
1071
  size_t context = CommandDistanceContext(&cmd);
1053
- StoreSymbolWithContext(&distance_enc, dist_code, context,
1072
+ StoreSymbolWithContext(distance_enc, dist_code, context,
1054
1073
  mb->distance_context_map, storage_ix, storage,
1055
1074
  BROTLI_DISTANCE_CONTEXT_BITS);
1056
1075
  }
@@ -1058,9 +1077,10 @@ void BrotliStoreMetaBlock(MemoryManager* m,
1058
1077
  }
1059
1078
  }
1060
1079
  }
1061
- CleanupBlockEncoder(m, &distance_enc);
1062
- CleanupBlockEncoder(m, &command_enc);
1063
- CleanupBlockEncoder(m, &literal_enc);
1080
+ CleanupBlockEncoder(m, distance_enc);
1081
+ CleanupBlockEncoder(m, command_enc);
1082
+ CleanupBlockEncoder(m, literal_enc);
1083
+ BROTLI_FREE(m, arena);
1064
1084
  if (is_last) {
1065
1085
  JumpToByteBoundary(storage_ix, storage);
1066
1086
  }
@@ -1131,54 +1151,60 @@ static void StoreDataWithHuffmanCodes(const uint8_t* input,
1131
1151
  }
1132
1152
  }
1133
1153
 
1134
- void BrotliStoreMetaBlockTrivial(MemoryManager* m,
1135
- const uint8_t* input, size_t start_pos, size_t length, size_t mask,
1136
- BROTLI_BOOL is_last, const BrotliEncoderParams* params,
1137
- const Command* commands, size_t n_commands,
1138
- size_t* storage_ix, uint8_t* storage) {
1154
+ /* TODO(eustas): pull alloc/dealloc to caller? */
1155
+ typedef struct MetablockArena {
1139
1156
  HistogramLiteral lit_histo;
1140
1157
  HistogramCommand cmd_histo;
1141
1158
  HistogramDistance dist_histo;
1159
+ /* TODO(eustas): merge bits and depth? */
1142
1160
  uint8_t lit_depth[BROTLI_NUM_LITERAL_SYMBOLS];
1143
1161
  uint16_t lit_bits[BROTLI_NUM_LITERAL_SYMBOLS];
1144
1162
  uint8_t cmd_depth[BROTLI_NUM_COMMAND_SYMBOLS];
1145
1163
  uint16_t cmd_bits[BROTLI_NUM_COMMAND_SYMBOLS];
1146
1164
  uint8_t dist_depth[MAX_SIMPLE_DISTANCE_ALPHABET_SIZE];
1147
1165
  uint16_t dist_bits[MAX_SIMPLE_DISTANCE_ALPHABET_SIZE];
1148
- HuffmanTree* tree;
1166
+ HuffmanTree tree[MAX_HUFFMAN_TREE_SIZE];
1167
+ } MetablockArena;
1168
+
1169
+ void BrotliStoreMetaBlockTrivial(MemoryManager* m,
1170
+ const uint8_t* input, size_t start_pos, size_t length, size_t mask,
1171
+ BROTLI_BOOL is_last, const BrotliEncoderParams* params,
1172
+ const Command* commands, size_t n_commands,
1173
+ size_t* storage_ix, uint8_t* storage) {
1174
+ MetablockArena* arena = BROTLI_ALLOC(m, MetablockArena, 1);
1149
1175
  uint32_t num_distance_symbols = params->dist.alphabet_size_max;
1176
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(arena)) return;
1150
1177
 
1151
1178
  StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage);
1152
1179
 
1153
- HistogramClearLiteral(&lit_histo);
1154
- HistogramClearCommand(&cmd_histo);
1155
- HistogramClearDistance(&dist_histo);
1180
+ HistogramClearLiteral(&arena->lit_histo);
1181
+ HistogramClearCommand(&arena->cmd_histo);
1182
+ HistogramClearDistance(&arena->dist_histo);
1156
1183
 
1157
1184
  BuildHistograms(input, start_pos, mask, commands, n_commands,
1158
- &lit_histo, &cmd_histo, &dist_histo);
1185
+ &arena->lit_histo, &arena->cmd_histo, &arena->dist_histo);
1159
1186
 
1160
1187
  BrotliWriteBits(13, 0, storage_ix, storage);
1161
1188
 
1162
- tree = BROTLI_ALLOC(m, HuffmanTree, MAX_HUFFMAN_TREE_SIZE);
1163
- if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(tree)) return;
1164
- BuildAndStoreHuffmanTree(lit_histo.data_, BROTLI_NUM_LITERAL_SYMBOLS,
1165
- BROTLI_NUM_LITERAL_SYMBOLS, tree,
1166
- lit_depth, lit_bits,
1189
+ BuildAndStoreHuffmanTree(arena->lit_histo.data_, BROTLI_NUM_LITERAL_SYMBOLS,
1190
+ BROTLI_NUM_LITERAL_SYMBOLS, arena->tree,
1191
+ arena->lit_depth, arena->lit_bits,
1167
1192
  storage_ix, storage);
1168
- BuildAndStoreHuffmanTree(cmd_histo.data_, BROTLI_NUM_COMMAND_SYMBOLS,
1169
- BROTLI_NUM_COMMAND_SYMBOLS, tree,
1170
- cmd_depth, cmd_bits,
1193
+ BuildAndStoreHuffmanTree(arena->cmd_histo.data_, BROTLI_NUM_COMMAND_SYMBOLS,
1194
+ BROTLI_NUM_COMMAND_SYMBOLS, arena->tree,
1195
+ arena->cmd_depth, arena->cmd_bits,
1171
1196
  storage_ix, storage);
1172
- BuildAndStoreHuffmanTree(dist_histo.data_, MAX_SIMPLE_DISTANCE_ALPHABET_SIZE,
1173
- num_distance_symbols, tree,
1174
- dist_depth, dist_bits,
1197
+ BuildAndStoreHuffmanTree(arena->dist_histo.data_,
1198
+ MAX_SIMPLE_DISTANCE_ALPHABET_SIZE,
1199
+ num_distance_symbols, arena->tree,
1200
+ arena->dist_depth, arena->dist_bits,
1175
1201
  storage_ix, storage);
1176
- BROTLI_FREE(m, tree);
1177
1202
  StoreDataWithHuffmanCodes(input, start_pos, mask, commands,
1178
- n_commands, lit_depth, lit_bits,
1179
- cmd_depth, cmd_bits,
1180
- dist_depth, dist_bits,
1203
+ n_commands, arena->lit_depth, arena->lit_bits,
1204
+ arena->cmd_depth, arena->cmd_bits,
1205
+ arena->dist_depth, arena->dist_bits,
1181
1206
  storage_ix, storage);
1207
+ BROTLI_FREE(m, arena);
1182
1208
  if (is_last) {
1183
1209
  JumpToByteBoundary(storage_ix, storage);
1184
1210
  }
@@ -1189,9 +1215,11 @@ void BrotliStoreMetaBlockFast(MemoryManager* m,
1189
1215
  BROTLI_BOOL is_last, const BrotliEncoderParams* params,
1190
1216
  const Command* commands, size_t n_commands,
1191
1217
  size_t* storage_ix, uint8_t* storage) {
1218
+ MetablockArena* arena = BROTLI_ALLOC(m, MetablockArena, 1);
1192
1219
  uint32_t num_distance_symbols = params->dist.alphabet_size_max;
1193
1220
  uint32_t distance_alphabet_bits =
1194
1221
  Log2FloorNonZero(num_distance_symbols - 1) + 1;
1222
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(arena)) return;
1195
1223
 
1196
1224
  StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage);
1197
1225
 
@@ -1202,8 +1230,6 @@ void BrotliStoreMetaBlockFast(MemoryManager* m,
1202
1230
  size_t pos = start_pos;
1203
1231
  size_t num_literals = 0;
1204
1232
  size_t i;
1205
- uint8_t lit_depth[BROTLI_NUM_LITERAL_SYMBOLS];
1206
- uint16_t lit_bits[BROTLI_NUM_LITERAL_SYMBOLS];
1207
1233
  for (i = 0; i < n_commands; ++i) {
1208
1234
  const Command cmd = commands[i];
1209
1235
  size_t j;
@@ -1214,61 +1240,50 @@ void BrotliStoreMetaBlockFast(MemoryManager* m,
1214
1240
  num_literals += cmd.insert_len_;
1215
1241
  pos += CommandCopyLen(&cmd);
1216
1242
  }
1217
- BrotliBuildAndStoreHuffmanTreeFast(m, histogram, num_literals,
1243
+ BrotliBuildAndStoreHuffmanTreeFast(arena->tree, histogram, num_literals,
1218
1244
  /* max_bits = */ 8,
1219
- lit_depth, lit_bits,
1245
+ arena->lit_depth, arena->lit_bits,
1220
1246
  storage_ix, storage);
1221
- if (BROTLI_IS_OOM(m)) return;
1222
1247
  StoreStaticCommandHuffmanTree(storage_ix, storage);
1223
1248
  StoreStaticDistanceHuffmanTree(storage_ix, storage);
1224
1249
  StoreDataWithHuffmanCodes(input, start_pos, mask, commands,
1225
- n_commands, lit_depth, lit_bits,
1250
+ n_commands, arena->lit_depth, arena->lit_bits,
1226
1251
  kStaticCommandCodeDepth,
1227
1252
  kStaticCommandCodeBits,
1228
1253
  kStaticDistanceCodeDepth,
1229
1254
  kStaticDistanceCodeBits,
1230
1255
  storage_ix, storage);
1231
1256
  } else {
1232
- HistogramLiteral lit_histo;
1233
- HistogramCommand cmd_histo;
1234
- HistogramDistance dist_histo;
1235
- uint8_t lit_depth[BROTLI_NUM_LITERAL_SYMBOLS];
1236
- uint16_t lit_bits[BROTLI_NUM_LITERAL_SYMBOLS];
1237
- uint8_t cmd_depth[BROTLI_NUM_COMMAND_SYMBOLS];
1238
- uint16_t cmd_bits[BROTLI_NUM_COMMAND_SYMBOLS];
1239
- uint8_t dist_depth[MAX_SIMPLE_DISTANCE_ALPHABET_SIZE];
1240
- uint16_t dist_bits[MAX_SIMPLE_DISTANCE_ALPHABET_SIZE];
1241
- HistogramClearLiteral(&lit_histo);
1242
- HistogramClearCommand(&cmd_histo);
1243
- HistogramClearDistance(&dist_histo);
1257
+ HistogramClearLiteral(&arena->lit_histo);
1258
+ HistogramClearCommand(&arena->cmd_histo);
1259
+ HistogramClearDistance(&arena->dist_histo);
1244
1260
  BuildHistograms(input, start_pos, mask, commands, n_commands,
1245
- &lit_histo, &cmd_histo, &dist_histo);
1246
- BrotliBuildAndStoreHuffmanTreeFast(m, lit_histo.data_,
1247
- lit_histo.total_count_,
1261
+ &arena->lit_histo, &arena->cmd_histo, &arena->dist_histo);
1262
+ BrotliBuildAndStoreHuffmanTreeFast(arena->tree, arena->lit_histo.data_,
1263
+ arena->lit_histo.total_count_,
1248
1264
  /* max_bits = */ 8,
1249
- lit_depth, lit_bits,
1265
+ arena->lit_depth, arena->lit_bits,
1250
1266
  storage_ix, storage);
1251
- if (BROTLI_IS_OOM(m)) return;
1252
- BrotliBuildAndStoreHuffmanTreeFast(m, cmd_histo.data_,
1253
- cmd_histo.total_count_,
1267
+ BrotliBuildAndStoreHuffmanTreeFast(arena->tree, arena->cmd_histo.data_,
1268
+ arena->cmd_histo.total_count_,
1254
1269
  /* max_bits = */ 10,
1255
- cmd_depth, cmd_bits,
1270
+ arena->cmd_depth, arena->cmd_bits,
1256
1271
  storage_ix, storage);
1257
- if (BROTLI_IS_OOM(m)) return;
1258
- BrotliBuildAndStoreHuffmanTreeFast(m, dist_histo.data_,
1259
- dist_histo.total_count_,
1272
+ BrotliBuildAndStoreHuffmanTreeFast(arena->tree, arena->dist_histo.data_,
1273
+ arena->dist_histo.total_count_,
1260
1274
  /* max_bits = */
1261
1275
  distance_alphabet_bits,
1262
- dist_depth, dist_bits,
1276
+ arena->dist_depth, arena->dist_bits,
1263
1277
  storage_ix, storage);
1264
- if (BROTLI_IS_OOM(m)) return;
1265
1278
  StoreDataWithHuffmanCodes(input, start_pos, mask, commands,
1266
- n_commands, lit_depth, lit_bits,
1267
- cmd_depth, cmd_bits,
1268
- dist_depth, dist_bits,
1279
+ n_commands, arena->lit_depth, arena->lit_bits,
1280
+ arena->cmd_depth, arena->cmd_bits,
1281
+ arena->dist_depth, arena->dist_bits,
1269
1282
  storage_ix, storage);
1270
1283
  }
1271
1284
 
1285
+ BROTLI_FREE(m, arena);
1286
+
1272
1287
  if (is_last) {
1273
1288
  JumpToByteBoundary(storage_ix, storage);
1274
1289
  }
@@ -1309,6 +1324,13 @@ void BrotliStoreUncompressedMetaBlock(BROTLI_BOOL is_final_block,
1309
1324
  }
1310
1325
  }
1311
1326
 
1327
+ #if defined(BROTLI_TEST)
1328
+ void GetBlockLengthPrefixCodeForTest(uint32_t len, size_t* code,
1329
+ uint32_t* n_extra, uint32_t* extra) {
1330
+ GetBlockLengthPrefixCode(len, code, n_extra, extra);
1331
+ }
1332
+ #endif
1333
+
1312
1334
  #if defined(__cplusplus) || defined(c_plusplus)
1313
1335
  } /* extern "C" */
1314
1336
  #endif
@@ -16,13 +16,14 @@
16
16
  #ifndef BROTLI_ENC_BROTLI_BIT_STREAM_H_
17
17
  #define BROTLI_ENC_BROTLI_BIT_STREAM_H_
18
18
 
19
+ #include <brotli/types.h>
20
+
19
21
  #include "../common/context.h"
20
22
  #include "../common/platform.h"
21
- #include <brotli/types.h>
22
- #include "./command.h"
23
- #include "./entropy_encode.h"
24
- #include "./memory.h"
25
- #include "./metablock.h"
23
+ #include "command.h"
24
+ #include "entropy_encode.h"
25
+ #include "memory.h"
26
+ #include "metablock.h"
26
27
 
27
28
  #if defined(__cplusplus) || defined(c_plusplus)
28
29
  extern "C" {
@@ -35,7 +36,7 @@ BROTLI_INTERNAL void BrotliStoreHuffmanTree(const uint8_t* depths, size_t num,
35
36
  HuffmanTree* tree, size_t* storage_ix, uint8_t* storage);
36
37
 
37
38
  BROTLI_INTERNAL void BrotliBuildAndStoreHuffmanTreeFast(
38
- MemoryManager* m, const uint32_t* histogram, const size_t histogram_total,
39
+ HuffmanTree* tree, const uint32_t* histogram, const size_t histogram_total,
39
40
  const size_t max_bits, uint8_t* depth, uint16_t* bits, size_t* storage_ix,
40
41
  uint8_t* storage);
41
42
 
@@ -77,6 +78,10 @@ BROTLI_INTERNAL void BrotliStoreUncompressedMetaBlock(
77
78
  size_t position, size_t mask, size_t len,
78
79
  size_t* BROTLI_RESTRICT storage_ix, uint8_t* BROTLI_RESTRICT storage);
79
80
 
81
+ #if defined(BROTLI_TEST)
82
+ void GetBlockLengthPrefixCodeForTest(uint32_t, size_t*, uint32_t*, uint32_t*);
83
+ #endif
84
+
80
85
  #if defined(__cplusplus) || defined(c_plusplus)
81
86
  } /* extern "C" */
82
87
  #endif
@@ -6,14 +6,15 @@
6
6
 
7
7
  /* Functions for clustering similar histograms together. */
8
8
 
9
- #include "./cluster.h"
9
+ #include "cluster.h"
10
10
 
11
- #include "../common/platform.h"
12
11
  #include <brotli/types.h>
13
- #include "./bit_cost.h" /* BrotliPopulationCost */
14
- #include "./fast_log.h"
15
- #include "./histogram.h"
16
- #include "./memory.h"
12
+
13
+ #include "../common/platform.h"
14
+ #include "bit_cost.h" /* BrotliPopulationCost */
15
+ #include "fast_log.h"
16
+ #include "histogram.h"
17
+ #include "memory.h"
17
18
 
18
19
  #if defined(__cplusplus) || defined(c_plusplus)
19
20
  extern "C" {
@@ -38,15 +39,15 @@ static BROTLI_INLINE double ClusterCostDiff(size_t size_a, size_t size_b) {
38
39
  #define CODE(X) X
39
40
 
40
41
  #define FN(X) X ## Literal
41
- #include "./cluster_inc.h" /* NOLINT(build/include) */
42
+ #include "cluster_inc.h" /* NOLINT(build/include) */
42
43
  #undef FN
43
44
 
44
45
  #define FN(X) X ## Command
45
- #include "./cluster_inc.h" /* NOLINT(build/include) */
46
+ #include "cluster_inc.h" /* NOLINT(build/include) */
46
47
  #undef FN
47
48
 
48
49
  #define FN(X) X ## Distance
49
- #include "./cluster_inc.h" /* NOLINT(build/include) */
50
+ #include "cluster_inc.h" /* NOLINT(build/include) */
50
51
  #undef FN
51
52
 
52
53
  #undef CODE
@@ -9,10 +9,11 @@
9
9
  #ifndef BROTLI_ENC_CLUSTER_H_
10
10
  #define BROTLI_ENC_CLUSTER_H_
11
11
 
12
- #include "../common/platform.h"
13
12
  #include <brotli/types.h>
14
- #include "./histogram.h"
15
- #include "./memory.h"
13
+
14
+ #include "../common/platform.h"
15
+ #include "histogram.h"
16
+ #include "memory.h"
16
17
 
17
18
  #if defined(__cplusplus) || defined(c_plusplus)
18
19
  extern "C" {
@@ -28,15 +29,15 @@ typedef struct HistogramPair {
28
29
  #define CODE(X) /* Declaration */;
29
30
 
30
31
  #define FN(X) X ## Literal
31
- #include "./cluster_inc.h" /* NOLINT(build/include) */
32
+ #include "cluster_inc.h" /* NOLINT(build/include) */
32
33
  #undef FN
33
34
 
34
35
  #define FN(X) X ## Command
35
- #include "./cluster_inc.h" /* NOLINT(build/include) */
36
+ #include "cluster_inc.h" /* NOLINT(build/include) */
36
37
  #undef FN
37
38
 
38
39
  #define FN(X) X ## Distance
39
- #include "./cluster_inc.h" /* NOLINT(build/include) */
40
+ #include "cluster_inc.h" /* NOLINT(build/include) */
40
41
  #undef FN
41
42
 
42
43
  #undef CODE