brotli 0.2.3 → 0.5.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 (124) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +37 -0
  3. data/.github/workflows/publish.yml +24 -0
  4. data/.gitmodules +1 -1
  5. data/Gemfile +6 -3
  6. data/README.md +2 -2
  7. data/Rakefile +16 -9
  8. data/brotli.gemspec +7 -13
  9. data/ext/brotli/brotli.c +210 -31
  10. data/ext/brotli/buffer.c +1 -7
  11. data/ext/brotli/buffer.h +1 -1
  12. data/ext/brotli/extconf.rb +25 -17
  13. data/lib/brotli/version.rb +1 -1
  14. data/test/brotli_test.rb +107 -0
  15. data/test/brotli_writer_test.rb +36 -0
  16. data/test/test_helper.rb +8 -0
  17. data/vendor/brotli/c/common/constants.c +15 -0
  18. data/vendor/brotli/c/common/constants.h +137 -0
  19. data/vendor/brotli/c/common/context.c +156 -0
  20. data/vendor/brotli/c/common/context.h +4 -152
  21. data/vendor/brotli/c/common/dictionary.bin.br +0 -0
  22. data/vendor/brotli/c/common/dictionary.c +14 -3
  23. data/vendor/brotli/c/common/platform.c +23 -0
  24. data/vendor/brotli/c/common/platform.h +95 -122
  25. data/vendor/brotli/c/common/shared_dictionary.c +521 -0
  26. data/vendor/brotli/c/common/shared_dictionary_internal.h +75 -0
  27. data/vendor/brotli/c/common/transform.c +60 -4
  28. data/vendor/brotli/c/common/transform.h +5 -0
  29. data/vendor/brotli/c/common/version.h +31 -6
  30. data/vendor/brotli/c/dec/bit_reader.c +34 -4
  31. data/vendor/brotli/c/dec/bit_reader.h +221 -107
  32. data/vendor/brotli/c/dec/decode.c +772 -403
  33. data/vendor/brotli/c/dec/huffman.c +7 -4
  34. data/vendor/brotli/c/dec/huffman.h +8 -13
  35. data/vendor/brotli/c/dec/prefix.h +1 -18
  36. data/vendor/brotli/c/dec/state.c +40 -21
  37. data/vendor/brotli/c/dec/state.h +201 -59
  38. data/vendor/brotli/c/enc/backward_references.c +88 -25
  39. data/vendor/brotli/c/enc/backward_references.h +10 -8
  40. data/vendor/brotli/c/enc/backward_references_hq.c +194 -80
  41. data/vendor/brotli/c/enc/backward_references_hq.h +17 -13
  42. data/vendor/brotli/c/enc/backward_references_inc.h +52 -16
  43. data/vendor/brotli/c/enc/bit_cost.c +8 -7
  44. data/vendor/brotli/c/enc/bit_cost.h +5 -4
  45. data/vendor/brotli/c/enc/block_splitter.c +40 -17
  46. data/vendor/brotli/c/enc/block_splitter.h +5 -4
  47. data/vendor/brotli/c/enc/block_splitter_inc.h +99 -49
  48. data/vendor/brotli/c/enc/brotli_bit_stream.c +142 -137
  49. data/vendor/brotli/c/enc/brotli_bit_stream.h +11 -6
  50. data/vendor/brotli/c/enc/cluster.c +10 -9
  51. data/vendor/brotli/c/enc/cluster.h +7 -6
  52. data/vendor/brotli/c/enc/cluster_inc.h +30 -22
  53. data/vendor/brotli/c/enc/command.c +28 -0
  54. data/vendor/brotli/c/enc/command.h +17 -16
  55. data/vendor/brotli/c/enc/compound_dictionary.c +207 -0
  56. data/vendor/brotli/c/enc/compound_dictionary.h +74 -0
  57. data/vendor/brotli/c/enc/compress_fragment.c +93 -83
  58. data/vendor/brotli/c/enc/compress_fragment.h +32 -7
  59. data/vendor/brotli/c/enc/compress_fragment_two_pass.c +100 -88
  60. data/vendor/brotli/c/enc/compress_fragment_two_pass.h +21 -3
  61. data/vendor/brotli/c/enc/dictionary_hash.c +1829 -1101
  62. data/vendor/brotli/c/enc/dictionary_hash.h +2 -1
  63. data/vendor/brotli/c/enc/encode.c +550 -416
  64. data/vendor/brotli/c/enc/encoder_dict.c +613 -5
  65. data/vendor/brotli/c/enc/encoder_dict.h +120 -4
  66. data/vendor/brotli/c/enc/entropy_encode.c +5 -2
  67. data/vendor/brotli/c/enc/entropy_encode.h +4 -3
  68. data/vendor/brotli/c/enc/entropy_encode_static.h +5 -2
  69. data/vendor/brotli/c/enc/fast_log.c +105 -0
  70. data/vendor/brotli/c/enc/fast_log.h +21 -101
  71. data/vendor/brotli/c/enc/find_match_length.h +17 -25
  72. data/vendor/brotli/c/enc/hash.h +350 -120
  73. data/vendor/brotli/c/enc/hash_composite_inc.h +71 -67
  74. data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +92 -51
  75. data/vendor/brotli/c/enc/hash_longest_match64_inc.h +79 -84
  76. data/vendor/brotli/c/enc/hash_longest_match_inc.h +53 -54
  77. data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +93 -62
  78. data/vendor/brotli/c/enc/hash_rolling_inc.h +25 -29
  79. data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +42 -40
  80. data/vendor/brotli/c/enc/histogram.c +4 -4
  81. data/vendor/brotli/c/enc/histogram.h +7 -6
  82. data/vendor/brotli/c/enc/literal_cost.c +20 -15
  83. data/vendor/brotli/c/enc/literal_cost.h +4 -2
  84. data/vendor/brotli/c/enc/memory.c +29 -5
  85. data/vendor/brotli/c/enc/memory.h +43 -14
  86. data/vendor/brotli/c/enc/metablock.c +95 -85
  87. data/vendor/brotli/c/enc/metablock.h +9 -8
  88. data/vendor/brotli/c/enc/metablock_inc.h +9 -7
  89. data/vendor/brotli/c/enc/params.h +7 -4
  90. data/vendor/brotli/c/enc/prefix.h +3 -2
  91. data/vendor/brotli/c/enc/quality.h +40 -3
  92. data/vendor/brotli/c/enc/ringbuffer.h +8 -4
  93. data/vendor/brotli/c/enc/state.h +104 -0
  94. data/vendor/brotli/c/enc/static_dict.c +60 -4
  95. data/vendor/brotli/c/enc/static_dict.h +3 -2
  96. data/vendor/brotli/c/enc/static_dict_lut.h +2 -0
  97. data/vendor/brotli/c/enc/utf8_util.c +2 -2
  98. data/vendor/brotli/c/enc/utf8_util.h +2 -1
  99. data/vendor/brotli/c/enc/write_bits.h +29 -26
  100. data/vendor/brotli/c/include/brotli/decode.h +67 -2
  101. data/vendor/brotli/c/include/brotli/encode.h +77 -3
  102. data/vendor/brotli/c/include/brotli/port.h +34 -3
  103. data/vendor/brotli/c/include/brotli/shared_dictionary.h +100 -0
  104. metadata +23 -97
  105. data/.travis.yml +0 -31
  106. data/docs/Brotli/Error.html +0 -124
  107. data/docs/Brotli.html +0 -485
  108. data/docs/_index.html +0 -122
  109. data/docs/class_list.html +0 -51
  110. data/docs/css/common.css +0 -1
  111. data/docs/css/full_list.css +0 -58
  112. data/docs/css/style.css +0 -496
  113. data/docs/file.README.html +0 -127
  114. data/docs/file_list.html +0 -56
  115. data/docs/frames.html +0 -17
  116. data/docs/index.html +0 -127
  117. data/docs/js/app.js +0 -292
  118. data/docs/js/full_list.js +0 -216
  119. data/docs/js/jquery.js +0 -4
  120. data/docs/method_list.html +0 -67
  121. data/docs/top-level-namespace.html +0 -110
  122. data/spec/brotli_spec.rb +0 -88
  123. data/spec/inflate_spec.rb +0 -75
  124. data/spec/spec_helper.rb +0 -4
@@ -6,13 +6,14 @@
6
6
 
7
7
  /* Utilities for building Huffman decoding tables. */
8
8
 
9
- #include "./huffman.h"
9
+ #include "huffman.h"
10
10
 
11
11
  #include <string.h> /* memcpy, memset */
12
12
 
13
+ #include <brotli/types.h>
14
+
13
15
  #include "../common/constants.h"
14
16
  #include "../common/platform.h"
15
- #include <brotli/types.h>
16
17
 
17
18
  #if defined(__cplusplus) || defined(c_plusplus)
18
19
  extern "C" {
@@ -117,11 +118,13 @@ void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
117
118
  int bits_count;
118
119
  BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH <=
119
120
  BROTLI_REVERSE_BITS_MAX);
121
+ BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH == 5);
120
122
 
121
123
  /* Generate offsets into sorted symbol table by code length. */
122
124
  symbol = -1;
123
125
  bits = 1;
124
- BROTLI_REPEAT(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH, {
126
+ /* BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH == 5 */
127
+ BROTLI_REPEAT_5({
125
128
  symbol += count[bits];
126
129
  offset[bits] = symbol;
127
130
  bits++;
@@ -132,7 +135,7 @@ void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
132
135
  /* Sort symbols by length, by symbol order within each length. */
133
136
  symbol = BROTLI_CODE_LENGTH_CODES;
134
137
  do {
135
- BROTLI_REPEAT(6, {
138
+ BROTLI_REPEAT_6({
136
139
  symbol--;
137
140
  sorted[offset[code_lengths[symbol]]--] = symbol;
138
141
  });
@@ -9,21 +9,16 @@
9
9
  #ifndef BROTLI_DEC_HUFFMAN_H_
10
10
  #define BROTLI_DEC_HUFFMAN_H_
11
11
 
12
- #include "../common/platform.h"
13
12
  #include <brotli/types.h>
14
13
 
14
+ #include "../common/platform.h"
15
+
15
16
  #if defined(__cplusplus) || defined(c_plusplus)
16
17
  extern "C" {
17
18
  #endif
18
19
 
19
20
  #define BROTLI_HUFFMAN_MAX_CODE_LENGTH 15
20
21
 
21
- /* Maximum possible Huffman table size for an alphabet size of (index * 32),
22
- max code length 15 and root table bits 8. */
23
- static const uint16_t kMaxHuffmanTableSize[] = {
24
- 256, 402, 436, 468, 500, 534, 566, 598, 630, 662, 694, 726, 758, 790, 822,
25
- 854, 886, 920, 952, 984, 1016, 1048, 1080, 1112, 1144, 1176, 1208, 1240, 1272,
26
- 1304, 1336, 1368, 1400, 1432, 1464, 1496, 1528};
27
22
  /* BROTLI_NUM_BLOCK_LEN_SYMBOLS == 26 */
28
23
  #define BROTLI_HUFFMAN_MAX_SIZE_26 396
29
24
  /* BROTLI_MAX_BLOCK_TYPE_SYMBOLS == 258 */
@@ -82,7 +77,7 @@ typedef BROTLI_ALIGNED(4) uint32_t HuffmanCode;
82
77
 
83
78
  static BROTLI_INLINE HuffmanCode ConstructHuffmanCode(const uint8_t bits,
84
79
  const uint16_t value) {
85
- return ((value & 0xFFFF) << 16) | (bits & 0xFF);
80
+ return (HuffmanCode) ((value & 0xFFFF) << 16) | (bits & 0xFF);
86
81
  }
87
82
 
88
83
  #define BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(H) uint32_t __fastload_##H = (*H)
@@ -100,7 +95,7 @@ BROTLI_INTERNAL void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* root_table,
100
95
  /* Builds Huffman lookup table assuming code lengths are in symbol order.
101
96
  Returns size of resulting table. */
102
97
  BROTLI_INTERNAL uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
103
- int root_bits, const uint16_t* const symbol_lists, uint16_t* count_arg);
98
+ int root_bits, const uint16_t* const symbol_lists, uint16_t* count);
104
99
 
105
100
  /* Builds a simple Huffman table. The |num_symbols| parameter is to be
106
101
  interpreted as follows: 0 means 1 symbol, 1 means 2 symbols,
@@ -110,13 +105,13 @@ BROTLI_INTERNAL uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
110
105
  int root_bits, uint16_t* symbols, uint32_t num_symbols);
111
106
 
112
107
  /* Contains a collection of Huffman trees with the same alphabet size. */
113
- /* max_symbol is needed due to simple codes since log2(alphabet_size) could be
114
- greater than log2(max_symbol). */
108
+ /* alphabet_size_limit is needed due to simple codes, since
109
+ log2(alphabet_size_max) could be greater than log2(alphabet_size_limit). */
115
110
  typedef struct {
116
111
  HuffmanCode** htrees;
117
112
  HuffmanCode* codes;
118
- uint16_t alphabet_size;
119
- uint16_t max_symbol;
113
+ uint16_t alphabet_size_max;
114
+ uint16_t alphabet_size_limit;
120
115
  uint16_t num_htrees;
121
116
  } HuffmanTreeGroup;
122
117
 
@@ -10,26 +10,9 @@
10
10
  #ifndef BROTLI_DEC_PREFIX_H_
11
11
  #define BROTLI_DEC_PREFIX_H_
12
12
 
13
- #include "../common/constants.h"
14
13
  #include <brotli/types.h>
15
14
 
16
- /* Represents the range of values belonging to a prefix code:
17
- [offset, offset + 2^nbits) */
18
- struct PrefixCodeRange {
19
- uint16_t offset;
20
- uint8_t nbits;
21
- };
22
-
23
- static const struct PrefixCodeRange
24
- kBlockLengthPrefixCode[BROTLI_NUM_BLOCK_LEN_SYMBOLS] = {
25
- { 1, 2}, { 5, 2}, { 9, 2}, { 13, 2},
26
- { 17, 3}, { 25, 3}, { 33, 3}, { 41, 3},
27
- { 49, 4}, { 65, 4}, { 81, 4}, { 97, 4},
28
- { 113, 5}, { 145, 5}, { 177, 5}, { 209, 5},
29
- { 241, 6}, { 305, 6}, { 369, 7}, { 497, 8},
30
- { 753, 9}, { 1265, 10}, {2289, 11}, {4337, 12},
31
- {8433, 13}, {16625, 24}
32
- };
15
+ #include "../common/constants.h"
33
16
 
34
17
  typedef struct CmdLutElement {
35
18
  uint8_t insert_len_extra_bits;
@@ -4,12 +4,14 @@
4
4
  See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5
5
  */
6
6
 
7
- #include "./state.h"
7
+ #include "state.h"
8
8
 
9
9
  #include <stdlib.h> /* free, malloc */
10
10
 
11
11
  #include <brotli/types.h>
12
- #include "./huffman.h"
12
+
13
+ #include "../common/dictionary.h"
14
+ #include "huffman.h"
13
15
 
14
16
  #if defined(__cplusplus) || defined(c_plusplus)
15
17
  extern "C" {
@@ -33,10 +35,7 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
33
35
  s->state = BROTLI_STATE_UNINITED;
34
36
  s->large_window = 0;
35
37
  s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
36
- s->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
37
- s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
38
38
  s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
39
- s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
40
39
  s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
41
40
  s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
42
41
 
@@ -45,6 +44,7 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
45
44
  s->pos = 0;
46
45
  s->rb_roundtrips = 0;
47
46
  s->partial_pos_out = 0;
47
+ s->used_input = 0;
48
48
 
49
49
  s->block_type_trees = NULL;
50
50
  s->block_len_trees = NULL;
@@ -59,8 +59,6 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
59
59
  s->context_map_slice = NULL;
60
60
  s->dist_context_map_slice = NULL;
61
61
 
62
- s->sub_loop_counter = 0;
63
-
64
62
  s->literal_hgroup.codes = NULL;
65
63
  s->literal_hgroup.htrees = NULL;
66
64
  s->insert_copy_hgroup.codes = NULL;
@@ -84,22 +82,25 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
84
82
  s->block_type_trees = NULL;
85
83
  s->block_len_trees = NULL;
86
84
 
87
- /* Make small negative indexes addressable. */
88
- s->symbol_lists = &s->symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1];
89
-
90
85
  s->mtf_upper_bound = 63;
91
86
 
92
- s->dictionary = BrotliGetDictionary();
93
- s->transforms = BrotliGetTransforms();
87
+ s->compound_dictionary = NULL;
88
+ s->dictionary =
89
+ BrotliSharedDictionaryCreateInstance(alloc_func, free_func, opaque);
90
+ if (!s->dictionary) return BROTLI_FALSE;
91
+
92
+ s->metadata_start_func = NULL;
93
+ s->metadata_chunk_func = NULL;
94
+ s->metadata_callback_opaque = 0;
94
95
 
95
96
  return BROTLI_TRUE;
96
97
  }
97
98
 
98
99
  void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) {
99
100
  s->meta_block_remaining_len = 0;
100
- s->block_length[0] = 1U << 24;
101
- s->block_length[1] = 1U << 24;
102
- s->block_length[2] = 1U << 24;
101
+ s->block_length[0] = BROTLI_BLOCK_SIZE_CAP;
102
+ s->block_length[1] = BROTLI_BLOCK_SIZE_CAP;
103
+ s->block_length[2] = BROTLI_BLOCK_SIZE_CAP;
103
104
  s->num_block_types[0] = 1;
104
105
  s->num_block_types[1] = 1;
105
106
  s->num_block_types[2] = 1;
@@ -134,25 +135,43 @@ void BrotliDecoderStateCleanupAfterMetablock(BrotliDecoderState* s) {
134
135
  BROTLI_DECODER_FREE(s, s->distance_hgroup.htrees);
135
136
  }
136
137
 
138
+ #ifdef BROTLI_REPORTING
139
+ /* When BROTLI_REPORTING is defined extra reporting module have to be linked. */
140
+ void BrotliDecoderOnFinish(const BrotliDecoderState* s);
141
+ #define BROTLI_DECODER_ON_FINISH(s) BrotliDecoderOnFinish(s);
142
+ #else
143
+ #if !defined(BROTLI_DECODER_ON_FINISH)
144
+ #define BROTLI_DECODER_ON_FINISH(s) (void)(s);
145
+ #endif
146
+ #endif
147
+
137
148
  void BrotliDecoderStateCleanup(BrotliDecoderState* s) {
138
149
  BrotliDecoderStateCleanupAfterMetablock(s);
139
150
 
151
+ BROTLI_DECODER_ON_FINISH(s);
152
+
153
+ BROTLI_DECODER_FREE(s, s->compound_dictionary);
154
+ BrotliSharedDictionaryDestroyInstance(s->dictionary);
155
+ s->dictionary = NULL;
140
156
  BROTLI_DECODER_FREE(s, s->ringbuffer);
141
157
  BROTLI_DECODER_FREE(s, s->block_type_trees);
142
158
  }
143
159
 
144
160
  BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s,
145
- HuffmanTreeGroup* group, uint32_t alphabet_size, uint32_t max_symbol,
146
- uint32_t ntrees) {
147
- /* Pack two allocations into one */
148
- const size_t max_table_size = kMaxHuffmanTableSize[(alphabet_size + 31) >> 5];
161
+ HuffmanTreeGroup* group, brotli_reg_t alphabet_size_max,
162
+ brotli_reg_t alphabet_size_limit, brotli_reg_t ntrees) {
163
+ /* 376 = 256 (1-st level table) + 4 + 7 + 15 + 31 + 63 (2-nd level mix-tables)
164
+ This number is discovered "unlimited" "enough" calculator; it is actually
165
+ a wee bigger than required in several cases (especially for alphabets with
166
+ less than 16 symbols). */
167
+ const size_t max_table_size = alphabet_size_limit + 376;
149
168
  const size_t code_size = sizeof(HuffmanCode) * ntrees * max_table_size;
150
169
  const size_t htree_size = sizeof(HuffmanCode*) * ntrees;
151
170
  /* Pointer alignment is, hopefully, wider than sizeof(HuffmanCode). */
152
171
  HuffmanCode** p = (HuffmanCode**)BROTLI_DECODER_ALLOC(s,
153
172
  code_size + htree_size);
154
- group->alphabet_size = (uint16_t)alphabet_size;
155
- group->max_symbol = (uint16_t)max_symbol;
173
+ group->alphabet_size_max = (uint16_t)alphabet_size_max;
174
+ group->alphabet_size_limit = (uint16_t)alphabet_size_limit;
156
175
  group->num_htrees = (uint16_t)ntrees;
157
176
  group->htrees = p;
158
177
  group->codes = (HuffmanCode*)(&p[ntrees]);
@@ -9,18 +9,110 @@
9
9
  #ifndef BROTLI_DEC_STATE_H_
10
10
  #define BROTLI_DEC_STATE_H_
11
11
 
12
+ #include <brotli/decode.h>
13
+ #include <brotli/shared_dictionary.h>
14
+ #include <brotli/types.h>
15
+
12
16
  #include "../common/constants.h"
13
17
  #include "../common/dictionary.h"
14
18
  #include "../common/platform.h"
15
19
  #include "../common/transform.h"
16
- #include <brotli/types.h>
17
- #include "./bit_reader.h"
18
- #include "./huffman.h"
20
+ #include "bit_reader.h"
21
+ #include "huffman.h"
19
22
 
20
23
  #if defined(__cplusplus) || defined(c_plusplus)
21
24
  extern "C" {
22
25
  #endif
23
26
 
27
+ /* Graphviz diagram that describes state transitions:
28
+
29
+ digraph States {
30
+ graph [compound=true]
31
+ concentrate=true
32
+ node [shape="box"]
33
+
34
+ UNINITED -> {LARGE_WINDOW_BITS -> INITIALIZE}
35
+ subgraph cluster_metablock_workflow {
36
+ style="rounded"
37
+ label=< <B>METABLOCK CYCLE</B> >
38
+ METABLOCK_BEGIN -> METABLOCK_HEADER
39
+ METABLOCK_HEADER:sw -> METADATA
40
+ METABLOCK_HEADER:s -> UNCOMPRESSED
41
+ METABLOCK_HEADER:se -> METABLOCK_DONE:ne
42
+ METADATA:s -> METABLOCK_DONE:w
43
+ UNCOMPRESSED:s -> METABLOCK_DONE:n
44
+ METABLOCK_DONE:e -> METABLOCK_BEGIN:e [constraint="false"]
45
+ }
46
+ INITIALIZE -> METABLOCK_BEGIN
47
+ METABLOCK_DONE -> DONE
48
+
49
+ subgraph cluster_compressed_metablock {
50
+ style="rounded"
51
+ label=< <B>COMPRESSED METABLOCK</B> >
52
+
53
+ subgraph cluster_command {
54
+ style="rounded"
55
+ label=< <B>HOT LOOP</B> >
56
+
57
+ _METABLOCK_DONE_PORT_ [shape=point style=invis]
58
+
59
+ {
60
+ // Set different shape for nodes returning from "compressed metablock".
61
+ node [shape=invhouse]; CMD_INNER CMD_POST_DECODE_LITERALS;
62
+ CMD_POST_WRAP_COPY; CMD_INNER_WRITE; CMD_POST_WRITE_1;
63
+ }
64
+
65
+ CMD_BEGIN -> CMD_INNER -> CMD_POST_DECODE_LITERALS -> CMD_POST_WRAP_COPY
66
+
67
+ // IO ("write") nodes are not in the hot loop!
68
+ CMD_INNER_WRITE [style=dashed]
69
+ CMD_INNER -> CMD_INNER_WRITE
70
+ CMD_POST_WRITE_1 [style=dashed]
71
+ CMD_POST_DECODE_LITERALS -> CMD_POST_WRITE_1
72
+ CMD_POST_WRITE_2 [style=dashed]
73
+ CMD_POST_WRAP_COPY -> CMD_POST_WRITE_2
74
+
75
+ CMD_POST_WRITE_1 -> CMD_BEGIN:s [constraint="false"]
76
+ CMD_INNER_WRITE -> {CMD_INNER CMD_POST_DECODE_LITERALS}
77
+ [constraint="false"]
78
+ CMD_BEGIN:ne -> CMD_POST_DECODE_LITERALS [constraint="false"]
79
+ CMD_POST_WRAP_COPY -> CMD_BEGIN [constraint="false"]
80
+ CMD_POST_DECODE_LITERALS -> CMD_BEGIN:ne [constraint="false"]
81
+ CMD_POST_WRITE_2 -> CMD_POST_WRAP_COPY [constraint="false"]
82
+ {rank=same; CMD_BEGIN; CMD_INNER; CMD_POST_DECODE_LITERALS;
83
+ CMD_POST_WRAP_COPY}
84
+ {rank=same; CMD_INNER_WRITE; CMD_POST_WRITE_1; CMD_POST_WRITE_2}
85
+
86
+ {CMD_INNER CMD_POST_DECODE_LITERALS CMD_POST_WRAP_COPY} ->
87
+ _METABLOCK_DONE_PORT_ [style=invis]
88
+ {CMD_INNER_WRITE CMD_POST_WRITE_1} -> _METABLOCK_DONE_PORT_
89
+ [constraint="false" style=invis]
90
+ }
91
+
92
+ BEFORE_COMPRESSED_METABLOCK_HEADER:s -> HUFFMAN_CODE_0:n
93
+ HUFFMAN_CODE_0 -> HUFFMAN_CODE_1 -> HUFFMAN_CODE_2 -> HUFFMAN_CODE_3
94
+ HUFFMAN_CODE_0 -> METABLOCK_HEADER_2 -> CONTEXT_MODES -> CONTEXT_MAP_1
95
+ CONTEXT_MAP_1 -> CONTEXT_MAP_2 -> TREE_GROUP
96
+ TREE_GROUP -> BEFORE_COMPRESSED_METABLOCK_BODY:e
97
+ BEFORE_COMPRESSED_METABLOCK_BODY:s -> CMD_BEGIN:n
98
+
99
+ HUFFMAN_CODE_3:e -> HUFFMAN_CODE_0:ne [constraint="false"]
100
+ {rank=same; HUFFMAN_CODE_0; HUFFMAN_CODE_1; HUFFMAN_CODE_2; HUFFMAN_CODE_3}
101
+ {rank=same; METABLOCK_HEADER_2; CONTEXT_MODES; CONTEXT_MAP_1; CONTEXT_MAP_2;
102
+ TREE_GROUP}
103
+ }
104
+ METABLOCK_HEADER:e -> BEFORE_COMPRESSED_METABLOCK_HEADER:n
105
+
106
+ _METABLOCK_DONE_PORT_ -> METABLOCK_DONE:se
107
+ [constraint="false" ltail=cluster_command]
108
+
109
+ UNINITED [shape=Mdiamond];
110
+ DONE [shape=Msquare];
111
+ }
112
+
113
+
114
+ */
115
+
24
116
  typedef enum {
25
117
  BROTLI_STATE_UNINITED,
26
118
  BROTLI_STATE_LARGE_WINDOW_BITS,
@@ -39,6 +131,7 @@ typedef enum {
39
131
  BROTLI_STATE_METABLOCK_DONE,
40
132
  BROTLI_STATE_COMMAND_POST_WRITE_1,
41
133
  BROTLI_STATE_COMMAND_POST_WRITE_2,
134
+ BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER,
42
135
  BROTLI_STATE_HUFFMAN_CODE_0,
43
136
  BROTLI_STATE_HUFFMAN_CODE_1,
44
137
  BROTLI_STATE_HUFFMAN_CODE_2,
@@ -46,6 +139,7 @@ typedef enum {
46
139
  BROTLI_STATE_CONTEXT_MAP_1,
47
140
  BROTLI_STATE_CONTEXT_MAP_2,
48
141
  BROTLI_STATE_TREE_GROUP,
142
+ BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY,
49
143
  BROTLI_STATE_DONE
50
144
  } BrotliRunningState;
51
145
 
@@ -98,6 +192,65 @@ typedef enum {
98
192
  BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX
99
193
  } BrotliRunningReadBlockLengthState;
100
194
 
195
+ /* BrotliDecoderState addon, used for Compound Dictionary functionality. */
196
+ typedef struct BrotliDecoderCompoundDictionary {
197
+ int num_chunks;
198
+ int total_size;
199
+ int br_index;
200
+ int br_offset;
201
+ int br_length;
202
+ int br_copied;
203
+ const uint8_t* chunks[16];
204
+ int chunk_offsets[16];
205
+ int block_bits;
206
+ uint8_t block_map[256];
207
+ } BrotliDecoderCompoundDictionary;
208
+
209
+ typedef struct BrotliMetablockHeaderArena {
210
+ BrotliRunningTreeGroupState substate_tree_group;
211
+ BrotliRunningContextMapState substate_context_map;
212
+ BrotliRunningHuffmanState substate_huffman;
213
+
214
+ brotli_reg_t sub_loop_counter;
215
+
216
+ brotli_reg_t repeat_code_len;
217
+ brotli_reg_t prev_code_len;
218
+
219
+ /* For ReadHuffmanCode. */
220
+ brotli_reg_t symbol;
221
+ brotli_reg_t repeat;
222
+ brotli_reg_t space;
223
+
224
+ /* Huffman table for "histograms". */
225
+ HuffmanCode table[32];
226
+ /* List of heads of symbol chains. */
227
+ uint16_t* symbol_lists;
228
+ /* Storage from symbol_lists. */
229
+ uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
230
+ BROTLI_NUM_COMMAND_SYMBOLS];
231
+ /* Tails of symbol chains. */
232
+ int next_symbol[32];
233
+ uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES];
234
+ /* Population counts for the code lengths. */
235
+ uint16_t code_length_histo[16];
236
+ /* TODO(eustas): +2 bytes padding */
237
+
238
+ /* For HuffmanTreeGroupDecode. */
239
+ int htree_index;
240
+ HuffmanCode* next;
241
+
242
+ /* For DecodeContextMap. */
243
+ brotli_reg_t context_index;
244
+ brotli_reg_t max_run_length_prefix;
245
+ brotli_reg_t code;
246
+ HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
247
+ } BrotliMetablockHeaderArena;
248
+
249
+ typedef struct BrotliMetablockBodyArena {
250
+ uint8_t dist_extra_bits[544];
251
+ brotli_reg_t dist_offset[544];
252
+ } BrotliMetablockBodyArena;
253
+
101
254
  struct BrotliDecoderStateStruct {
102
255
  BrotliRunningState state;
103
256
 
@@ -110,12 +263,13 @@ struct BrotliDecoderStateStruct {
110
263
  brotli_free_func free_func;
111
264
  void* memory_manager_opaque;
112
265
 
113
- /* Temporary storage for remaining input. */
266
+ /* Temporary storage for remaining input. Brotli stream format is designed in
267
+ a way, that 64 bits are enough to make progress in decoding. */
114
268
  union {
115
269
  uint64_t u64;
116
270
  uint8_t u8[8];
117
271
  } buffer;
118
- uint32_t buffer_length;
272
+ brotli_reg_t buffer_length;
119
273
 
120
274
  int pos;
121
275
  int max_backward_distance;
@@ -125,7 +279,8 @@ struct BrotliDecoderStateStruct {
125
279
  int dist_rb_idx;
126
280
  int dist_rb[4];
127
281
  int error_code;
128
- uint32_t sub_loop_counter;
282
+ int meta_block_remaining_len;
283
+
129
284
  uint8_t* ringbuffer;
130
285
  uint8_t* ringbuffer_end;
131
286
  HuffmanCode* htree_command;
@@ -146,89 +301,71 @@ struct BrotliDecoderStateStruct {
146
301
  /* Distance context is actual after command is decoded and before distance is
147
302
  computed. After distance computation it is used as a temporary variable. */
148
303
  int distance_context;
149
- int meta_block_remaining_len;
150
- uint32_t block_length_index;
151
- uint32_t block_length[3];
152
- uint32_t num_block_types[3];
153
- uint32_t block_type_rb[6];
154
- uint32_t distance_postfix_bits;
155
- uint32_t num_direct_distance_codes;
156
- int distance_postfix_mask;
157
- uint32_t num_dist_htrees;
304
+ brotli_reg_t block_length[3];
305
+ brotli_reg_t block_length_index;
306
+ brotli_reg_t num_block_types[3];
307
+ brotli_reg_t block_type_rb[6];
308
+ brotli_reg_t distance_postfix_bits;
309
+ brotli_reg_t num_direct_distance_codes;
310
+ brotli_reg_t num_dist_htrees;
158
311
  uint8_t* dist_context_map;
159
312
  HuffmanCode* literal_htree;
160
- uint8_t dist_htree_index;
161
- uint32_t repeat_code_len;
162
- uint32_t prev_code_len;
163
-
164
- int copy_length;
165
- int distance_code;
166
313
 
167
314
  /* For partial write operations. */
168
315
  size_t rb_roundtrips; /* how many times we went around the ring-buffer */
169
316
  size_t partial_pos_out; /* how much output to the user in total */
170
317
 
171
- /* For ReadHuffmanCode. */
172
- uint32_t symbol;
173
- uint32_t repeat;
174
- uint32_t space;
318
+ /* For InverseMoveToFrontTransform. */
319
+ brotli_reg_t mtf_upper_bound;
320
+ uint32_t mtf[64 + 1];
175
321
 
176
- HuffmanCode table[32];
177
- /* List of heads of symbol chains. */
178
- uint16_t* symbol_lists;
179
- /* Storage from symbol_lists. */
180
- uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
181
- BROTLI_NUM_COMMAND_SYMBOLS];
182
- /* Tails of symbol chains. */
183
- int next_symbol[32];
184
- uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES];
185
- /* Population counts for the code lengths. */
186
- uint16_t code_length_histo[16];
322
+ int copy_length;
323
+ int distance_code;
187
324
 
188
- /* For HuffmanTreeGroupDecode. */
189
- int htree_index;
190
- HuffmanCode* next;
325
+ uint8_t dist_htree_index;
326
+ /* TODO(eustas): +3 bytes padding */
191
327
 
192
- /* For DecodeContextMap. */
193
- uint32_t context_index;
194
- uint32_t max_run_length_prefix;
195
- uint32_t code;
196
- HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
328
+ /* Less used attributes are at the end of this struct. */
197
329
 
198
- /* For InverseMoveToFrontTransform. */
199
- uint32_t mtf_upper_bound;
200
- uint32_t mtf[64 + 1];
330
+ brotli_decoder_metadata_start_func metadata_start_func;
331
+ brotli_decoder_metadata_chunk_func metadata_chunk_func;
332
+ void* metadata_callback_opaque;
201
333
 
202
- /* Less used attributes are at the end of this struct. */
334
+ /* For reporting. */
335
+ uint64_t used_input; /* how many bytes of input are consumed */
203
336
 
204
337
  /* States inside function calls. */
205
338
  BrotliRunningMetablockHeaderState substate_metablock_header;
206
- BrotliRunningTreeGroupState substate_tree_group;
207
- BrotliRunningContextMapState substate_context_map;
208
339
  BrotliRunningUncompressedState substate_uncompressed;
209
- BrotliRunningHuffmanState substate_huffman;
210
340
  BrotliRunningDecodeUint8State substate_decode_uint8;
211
341
  BrotliRunningReadBlockLengthState substate_read_block_length;
212
342
 
343
+ int new_ringbuffer_size;
344
+ /* TODO(eustas): +4 bytes padding */
345
+
213
346
  unsigned int is_last_metablock : 1;
214
347
  unsigned int is_uncompressed : 1;
215
348
  unsigned int is_metadata : 1;
216
349
  unsigned int should_wrap_ringbuffer : 1;
217
350
  unsigned int canny_ringbuffer_allocation : 1;
218
351
  unsigned int large_window : 1;
352
+ unsigned int window_bits : 6;
219
353
  unsigned int size_nibbles : 8;
220
- uint32_t window_bits;
354
+ /* TODO(eustas): +12 bits padding */
221
355
 
222
- int new_ringbuffer_size;
223
-
224
- uint32_t num_literal_htrees;
356
+ brotli_reg_t num_literal_htrees;
225
357
  uint8_t* context_map;
226
358
  uint8_t* context_modes;
227
359
 
228
- const BrotliDictionary* dictionary;
229
- const BrotliTransforms* transforms;
360
+ BrotliSharedDictionary* dictionary;
361
+ BrotliDecoderCompoundDictionary* compound_dictionary;
230
362
 
231
363
  uint32_t trivial_literal_contexts[8]; /* 256 bits */
364
+
365
+ union {
366
+ BrotliMetablockHeaderArena header;
367
+ BrotliMetablockBodyArena body;
368
+ } arena;
232
369
  };
233
370
 
234
371
  typedef struct BrotliDecoderStateStruct BrotliDecoderStateInternal;
@@ -241,8 +378,9 @@ BROTLI_INTERNAL void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s);
241
378
  BROTLI_INTERNAL void BrotliDecoderStateCleanupAfterMetablock(
242
379
  BrotliDecoderState* s);
243
380
  BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(
244
- BrotliDecoderState* s, HuffmanTreeGroup* group, uint32_t alphabet_size,
245
- uint32_t max_symbol, uint32_t ntrees);
381
+ BrotliDecoderState* s, HuffmanTreeGroup* group,
382
+ brotli_reg_t alphabet_size_max, brotli_reg_t alphabet_size_limit,
383
+ brotli_reg_t ntrees);
246
384
 
247
385
  #define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
248
386
 
@@ -251,6 +389,10 @@ BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(
251
389
  X = NULL; \
252
390
  }
253
391
 
392
+ /* Literal/Command/Distance block size maximum; same as maximum metablock size;
393
+ used as block size when there is no block switching. */
394
+ #define BROTLI_BLOCK_SIZE_CAP (1U << 24)
395
+
254
396
  #if defined(__cplusplus) || defined(c_plusplus)
255
397
  } /* extern "C" */
256
398
  #endif