brotli 0.2.0 → 0.4.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 (111) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/main.yml +34 -0
  3. data/.github/workflows/publish.yml +34 -0
  4. data/Gemfile +6 -2
  5. data/Rakefile +18 -6
  6. data/bin/before_install.sh +9 -0
  7. data/brotli.gemspec +7 -13
  8. data/ext/brotli/brotli.c +209 -11
  9. data/ext/brotli/buffer.c +1 -7
  10. data/ext/brotli/buffer.h +1 -1
  11. data/ext/brotli/extconf.rb +45 -26
  12. data/lib/brotli/version.rb +1 -1
  13. data/smoke.sh +1 -1
  14. data/test/brotli_test.rb +104 -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 +149 -6
  19. data/vendor/brotli/c/{dec/context.h → common/context.c} +91 -186
  20. data/vendor/brotli/c/common/context.h +113 -0
  21. data/vendor/brotli/c/common/dictionary.bin +0 -0
  22. data/vendor/brotli/c/common/dictionary.bin.br +0 -0
  23. data/vendor/brotli/c/common/dictionary.c +11 -2
  24. data/vendor/brotli/c/common/dictionary.h +4 -4
  25. data/vendor/brotli/c/common/platform.c +22 -0
  26. data/vendor/brotli/c/common/platform.h +594 -0
  27. data/vendor/brotli/c/common/transform.c +291 -0
  28. data/vendor/brotli/c/common/transform.h +85 -0
  29. data/vendor/brotli/c/common/version.h +8 -1
  30. data/vendor/brotli/c/dec/bit_reader.c +29 -1
  31. data/vendor/brotli/c/dec/bit_reader.h +91 -100
  32. data/vendor/brotli/c/dec/decode.c +665 -437
  33. data/vendor/brotli/c/dec/huffman.c +65 -84
  34. data/vendor/brotli/c/dec/huffman.h +67 -14
  35. data/vendor/brotli/c/dec/prefix.h +1 -20
  36. data/vendor/brotli/c/dec/state.c +32 -45
  37. data/vendor/brotli/c/dec/state.h +173 -55
  38. data/vendor/brotli/c/enc/backward_references.c +27 -16
  39. data/vendor/brotli/c/enc/backward_references.h +7 -7
  40. data/vendor/brotli/c/enc/backward_references_hq.c +155 -116
  41. data/vendor/brotli/c/enc/backward_references_hq.h +22 -23
  42. data/vendor/brotli/c/enc/backward_references_inc.h +32 -22
  43. data/vendor/brotli/c/enc/bit_cost.c +1 -1
  44. data/vendor/brotli/c/enc/bit_cost.h +5 -5
  45. data/vendor/brotli/c/enc/block_encoder_inc.h +7 -6
  46. data/vendor/brotli/c/enc/block_splitter.c +5 -6
  47. data/vendor/brotli/c/enc/block_splitter.h +1 -1
  48. data/vendor/brotli/c/enc/block_splitter_inc.h +26 -17
  49. data/vendor/brotli/c/enc/brotli_bit_stream.c +107 -123
  50. data/vendor/brotli/c/enc/brotli_bit_stream.h +19 -38
  51. data/vendor/brotli/c/enc/cluster.c +1 -1
  52. data/vendor/brotli/c/enc/cluster.h +1 -1
  53. data/vendor/brotli/c/enc/cluster_inc.h +6 -3
  54. data/vendor/brotli/c/enc/command.c +28 -0
  55. data/vendor/brotli/c/enc/command.h +52 -42
  56. data/vendor/brotli/c/enc/compress_fragment.c +21 -22
  57. data/vendor/brotli/c/enc/compress_fragment.h +1 -1
  58. data/vendor/brotli/c/enc/compress_fragment_two_pass.c +102 -69
  59. data/vendor/brotli/c/enc/compress_fragment_two_pass.h +1 -1
  60. data/vendor/brotli/c/enc/dictionary_hash.c +1827 -1101
  61. data/vendor/brotli/c/enc/dictionary_hash.h +2 -1
  62. data/vendor/brotli/c/enc/encode.c +358 -195
  63. data/vendor/brotli/c/enc/encoder_dict.c +33 -0
  64. data/vendor/brotli/c/enc/encoder_dict.h +43 -0
  65. data/vendor/brotli/c/enc/entropy_encode.c +16 -14
  66. data/vendor/brotli/c/enc/entropy_encode.h +7 -7
  67. data/vendor/brotli/c/enc/entropy_encode_static.h +3 -3
  68. data/vendor/brotli/c/enc/fast_log.c +105 -0
  69. data/vendor/brotli/c/enc/fast_log.h +20 -99
  70. data/vendor/brotli/c/enc/find_match_length.h +5 -6
  71. data/vendor/brotli/c/enc/hash.h +145 -103
  72. data/vendor/brotli/c/enc/hash_composite_inc.h +125 -0
  73. data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +93 -53
  74. data/vendor/brotli/c/enc/hash_longest_match64_inc.h +54 -53
  75. data/vendor/brotli/c/enc/hash_longest_match_inc.h +58 -54
  76. data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +95 -63
  77. data/vendor/brotli/c/enc/hash_rolling_inc.h +212 -0
  78. data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +46 -43
  79. data/vendor/brotli/c/enc/histogram.c +9 -6
  80. data/vendor/brotli/c/enc/histogram.h +6 -3
  81. data/vendor/brotli/c/enc/histogram_inc.h +1 -1
  82. data/vendor/brotli/c/enc/literal_cost.c +5 -5
  83. data/vendor/brotli/c/enc/literal_cost.h +2 -2
  84. data/vendor/brotli/c/enc/memory.c +5 -16
  85. data/vendor/brotli/c/enc/memory.h +52 -1
  86. data/vendor/brotli/c/enc/metablock.c +171 -36
  87. data/vendor/brotli/c/enc/metablock.h +13 -8
  88. data/vendor/brotli/c/enc/metablock_inc.h +2 -2
  89. data/vendor/brotli/c/enc/params.h +46 -0
  90. data/vendor/brotli/c/enc/prefix.h +3 -4
  91. data/vendor/brotli/c/enc/quality.h +29 -24
  92. data/vendor/brotli/c/enc/ringbuffer.h +19 -12
  93. data/vendor/brotli/c/enc/static_dict.c +49 -45
  94. data/vendor/brotli/c/enc/static_dict.h +4 -3
  95. data/vendor/brotli/c/enc/static_dict_lut.h +1 -1
  96. data/vendor/brotli/c/enc/utf8_util.c +21 -21
  97. data/vendor/brotli/c/enc/utf8_util.h +1 -1
  98. data/vendor/brotli/c/enc/write_bits.h +35 -38
  99. data/vendor/brotli/c/include/brotli/decode.h +13 -8
  100. data/vendor/brotli/c/include/brotli/encode.h +54 -8
  101. data/vendor/brotli/c/include/brotli/port.h +225 -83
  102. data/vendor/brotli/c/include/brotli/types.h +0 -7
  103. metadata +28 -87
  104. data/.travis.yml +0 -30
  105. data/spec/brotli_spec.rb +0 -88
  106. data/spec/inflate_spec.rb +0 -75
  107. data/spec/spec_helper.rb +0 -4
  108. data/vendor/brotli/c/dec/port.h +0 -168
  109. data/vendor/brotli/c/dec/transform.h +0 -300
  110. data/vendor/brotli/c/enc/context.h +0 -184
  111. data/vendor/brotli/c/enc/port.h +0 -184
@@ -15,25 +15,11 @@
15
15
  extern "C" {
16
16
  #endif
17
17
 
18
- static void* DefaultAllocFunc(void* opaque, size_t size) {
19
- BROTLI_UNUSED(opaque);
20
- return malloc(size);
21
- }
22
-
23
- static void DefaultFreeFunc(void* opaque, void* address) {
24
- BROTLI_UNUSED(opaque);
25
- free(address);
26
- }
27
-
28
- void BrotliDecoderStateInit(BrotliDecoderState* s) {
29
- BrotliDecoderStateInitWithCustomAllocators(s, 0, 0, 0);
30
- }
31
-
32
- void BrotliDecoderStateInitWithCustomAllocators(BrotliDecoderState* s,
18
+ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
33
19
  brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {
34
20
  if (!alloc_func) {
35
- s->alloc_func = DefaultAllocFunc;
36
- s->free_func = DefaultFreeFunc;
21
+ s->alloc_func = BrotliDefaultAllocFunc;
22
+ s->free_func = BrotliDefaultFreeFunc;
37
23
  s->memory_manager_opaque = 0;
38
24
  } else {
39
25
  s->alloc_func = alloc_func;
@@ -45,16 +31,12 @@ void BrotliDecoderStateInitWithCustomAllocators(BrotliDecoderState* s,
45
31
 
46
32
  BrotliInitBitReader(&s->br);
47
33
  s->state = BROTLI_STATE_UNINITED;
34
+ s->large_window = 0;
48
35
  s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
49
- s->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
50
- s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
51
36
  s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
52
- s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
53
37
  s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
54
38
  s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
55
39
 
56
- s->dictionary = BrotliGetDictionary();
57
-
58
40
  s->buffer_length = 0;
59
41
  s->loop_counter = 0;
60
42
  s->pos = 0;
@@ -74,8 +56,6 @@ void BrotliDecoderStateInitWithCustomAllocators(BrotliDecoderState* s,
74
56
  s->context_map_slice = NULL;
75
57
  s->dist_context_map_slice = NULL;
76
58
 
77
- s->sub_loop_counter = 0;
78
-
79
59
  s->literal_hgroup.codes = NULL;
80
60
  s->literal_hgroup.htrees = NULL;
81
61
  s->insert_copy_hgroup.codes = NULL;
@@ -99,17 +79,19 @@ void BrotliDecoderStateInitWithCustomAllocators(BrotliDecoderState* s,
99
79
  s->block_type_trees = NULL;
100
80
  s->block_len_trees = NULL;
101
81
 
102
- /* Make small negative indexes addressable. */
103
- s->symbol_lists = &s->symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1];
104
-
105
82
  s->mtf_upper_bound = 63;
83
+
84
+ s->dictionary = BrotliGetDictionary();
85
+ s->transforms = BrotliGetTransforms();
86
+
87
+ return BROTLI_TRUE;
106
88
  }
107
89
 
108
90
  void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) {
109
91
  s->meta_block_remaining_len = 0;
110
- s->block_length[0] = 1U << 28;
111
- s->block_length[1] = 1U << 28;
112
- s->block_length[2] = 1U << 28;
92
+ s->block_length[0] = 1U << 24;
93
+ s->block_length[1] = 1U << 24;
94
+ s->block_length[2] = 1U << 24;
113
95
  s->num_block_types[0] = 1;
114
96
  s->num_block_types[1] = 1;
115
97
  s->num_block_types[2] = 1;
@@ -126,8 +108,7 @@ void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) {
126
108
  s->literal_htree = NULL;
127
109
  s->dist_context_map_slice = NULL;
128
110
  s->dist_htree_index = 0;
129
- s->context_lookup1 = NULL;
130
- s->context_lookup2 = NULL;
111
+ s->context_lookup = NULL;
131
112
  s->literal_hgroup.codes = NULL;
132
113
  s->literal_hgroup.htrees = NULL;
133
114
  s->insert_copy_hgroup.codes = NULL;
@@ -137,30 +118,36 @@ void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) {
137
118
  }
138
119
 
139
120
  void BrotliDecoderStateCleanupAfterMetablock(BrotliDecoderState* s) {
140
- BROTLI_FREE(s, s->context_modes);
141
- BROTLI_FREE(s, s->context_map);
142
- BROTLI_FREE(s, s->dist_context_map);
143
- BROTLI_FREE(s, s->literal_hgroup.htrees);
144
- BROTLI_FREE(s, s->insert_copy_hgroup.htrees);
145
- BROTLI_FREE(s, s->distance_hgroup.htrees);
121
+ BROTLI_DECODER_FREE(s, s->context_modes);
122
+ BROTLI_DECODER_FREE(s, s->context_map);
123
+ BROTLI_DECODER_FREE(s, s->dist_context_map);
124
+ BROTLI_DECODER_FREE(s, s->literal_hgroup.htrees);
125
+ BROTLI_DECODER_FREE(s, s->insert_copy_hgroup.htrees);
126
+ BROTLI_DECODER_FREE(s, s->distance_hgroup.htrees);
146
127
  }
147
128
 
148
129
  void BrotliDecoderStateCleanup(BrotliDecoderState* s) {
149
130
  BrotliDecoderStateCleanupAfterMetablock(s);
150
131
 
151
- BROTLI_FREE(s, s->ringbuffer);
152
- BROTLI_FREE(s, s->block_type_trees);
132
+ BROTLI_DECODER_FREE(s, s->ringbuffer);
133
+ BROTLI_DECODER_FREE(s, s->block_type_trees);
153
134
  }
154
135
 
155
136
  BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s,
156
- HuffmanTreeGroup* group, uint32_t alphabet_size, uint32_t ntrees) {
157
- /* Pack two allocations into one */
158
- const size_t max_table_size = kMaxHuffmanTableSize[(alphabet_size + 31) >> 5];
137
+ HuffmanTreeGroup* group, uint32_t alphabet_size_max,
138
+ uint32_t alphabet_size_limit, uint32_t ntrees) {
139
+ /* 376 = 256 (1-st level table) + 4 + 7 + 15 + 31 + 63 (2-nd level mix-tables)
140
+ This number is discovered "unlimited" "enough" calculator; it is actually
141
+ a wee bigger than required in several cases (especially for alphabets with
142
+ less than 16 symbols). */
143
+ const size_t max_table_size = alphabet_size_limit + 376;
159
144
  const size_t code_size = sizeof(HuffmanCode) * ntrees * max_table_size;
160
145
  const size_t htree_size = sizeof(HuffmanCode*) * ntrees;
161
146
  /* Pointer alignment is, hopefully, wider than sizeof(HuffmanCode). */
162
- HuffmanCode** p = (HuffmanCode**)BROTLI_ALLOC(s, code_size + htree_size);
163
- group->alphabet_size = (uint16_t)alphabet_size;
147
+ HuffmanCode** p = (HuffmanCode**)BROTLI_DECODER_ALLOC(s,
148
+ code_size + htree_size);
149
+ group->alphabet_size_max = (uint16_t)alphabet_size_max;
150
+ group->alphabet_size_limit = (uint16_t)alphabet_size_limit;
164
151
  group->num_htrees = (uint16_t)ntrees;
165
152
  group->htrees = p;
166
153
  group->codes = (HuffmanCode*)(&p[ntrees]);
@@ -11,17 +11,109 @@
11
11
 
12
12
  #include "../common/constants.h"
13
13
  #include "../common/dictionary.h"
14
+ #include "../common/platform.h"
15
+ #include "../common/transform.h"
14
16
  #include <brotli/types.h>
15
17
  #include "./bit_reader.h"
16
18
  #include "./huffman.h"
17
- #include "./port.h"
18
19
 
19
20
  #if defined(__cplusplus) || defined(c_plusplus)
20
21
  extern "C" {
21
22
  #endif
22
23
 
24
+ /* Graphviz diagram that describes state transitions:
25
+
26
+ digraph States {
27
+ graph [compound=true]
28
+ concentrate=true
29
+ node [shape="box"]
30
+
31
+ UNINITED -> {LARGE_WINDOW_BITS -> INITIALIZE}
32
+ subgraph cluster_metablock_workflow {
33
+ style="rounded"
34
+ label=< <B>METABLOCK CYCLE</B> >
35
+ METABLOCK_BEGIN -> METABLOCK_HEADER
36
+ METABLOCK_HEADER:sw -> METADATA
37
+ METABLOCK_HEADER:s -> UNCOMPRESSED
38
+ METABLOCK_HEADER:se -> METABLOCK_DONE:ne
39
+ METADATA:s -> METABLOCK_DONE:w
40
+ UNCOMPRESSED:s -> METABLOCK_DONE:n
41
+ METABLOCK_DONE:e -> METABLOCK_BEGIN:e [constraint="false"]
42
+ }
43
+ INITIALIZE -> METABLOCK_BEGIN
44
+ METABLOCK_DONE -> DONE
45
+
46
+ subgraph cluster_compressed_metablock {
47
+ style="rounded"
48
+ label=< <B>COMPRESSED METABLOCK</B> >
49
+
50
+ subgraph cluster_command {
51
+ style="rounded"
52
+ label=< <B>HOT LOOP</B> >
53
+
54
+ _METABLOCK_DONE_PORT_ [shape=point style=invis]
55
+
56
+ {
57
+ // Set different shape for nodes returning from "compressed metablock".
58
+ node [shape=invhouse]; CMD_INNER CMD_POST_DECODE_LITERALS;
59
+ CMD_POST_WRAP_COPY; CMD_INNER_WRITE; CMD_POST_WRITE_1;
60
+ }
61
+
62
+ CMD_BEGIN -> CMD_INNER -> CMD_POST_DECODE_LITERALS -> CMD_POST_WRAP_COPY
63
+
64
+ // IO ("write") nodes are not in the hot loop!
65
+ CMD_INNER_WRITE [style=dashed]
66
+ CMD_INNER -> CMD_INNER_WRITE
67
+ CMD_POST_WRITE_1 [style=dashed]
68
+ CMD_POST_DECODE_LITERALS -> CMD_POST_WRITE_1
69
+ CMD_POST_WRITE_2 [style=dashed]
70
+ CMD_POST_WRAP_COPY -> CMD_POST_WRITE_2
71
+
72
+ CMD_POST_WRITE_1 -> CMD_BEGIN:s [constraint="false"]
73
+ CMD_INNER_WRITE -> {CMD_INNER CMD_POST_DECODE_LITERALS}
74
+ [constraint="false"]
75
+ CMD_BEGIN:ne -> CMD_POST_DECODE_LITERALS [constraint="false"]
76
+ CMD_POST_WRAP_COPY -> CMD_BEGIN [constraint="false"]
77
+ CMD_POST_DECODE_LITERALS -> CMD_BEGIN:ne [constraint="false"]
78
+ CMD_POST_WRITE_2 -> CMD_POST_WRAP_COPY [constraint="false"]
79
+ {rank=same; CMD_BEGIN; CMD_INNER; CMD_POST_DECODE_LITERALS;
80
+ CMD_POST_WRAP_COPY}
81
+ {rank=same; CMD_INNER_WRITE; CMD_POST_WRITE_1; CMD_POST_WRITE_2}
82
+
83
+ {CMD_INNER CMD_POST_DECODE_LITERALS CMD_POST_WRAP_COPY} ->
84
+ _METABLOCK_DONE_PORT_ [style=invis]
85
+ {CMD_INNER_WRITE CMD_POST_WRITE_1} -> _METABLOCK_DONE_PORT_
86
+ [constraint="false" style=invis]
87
+ }
88
+
89
+ BEFORE_COMPRESSED_METABLOCK_HEADER:s -> HUFFMAN_CODE_0:n
90
+ HUFFMAN_CODE_0 -> HUFFMAN_CODE_1 -> HUFFMAN_CODE_2 -> HUFFMAN_CODE_3
91
+ HUFFMAN_CODE_0 -> METABLOCK_HEADER_2 -> CONTEXT_MODES -> CONTEXT_MAP_1
92
+ CONTEXT_MAP_1 -> CONTEXT_MAP_2 -> TREE_GROUP
93
+ TREE_GROUP -> BEFORE_COMPRESSED_METABLOCK_BODY:e
94
+ BEFORE_COMPRESSED_METABLOCK_BODY:s -> CMD_BEGIN:n
95
+
96
+ HUFFMAN_CODE_3:e -> HUFFMAN_CODE_0:ne [constraint="false"]
97
+ {rank=same; HUFFMAN_CODE_0; HUFFMAN_CODE_1; HUFFMAN_CODE_2; HUFFMAN_CODE_3}
98
+ {rank=same; METABLOCK_HEADER_2; CONTEXT_MODES; CONTEXT_MAP_1; CONTEXT_MAP_2;
99
+ TREE_GROUP}
100
+ }
101
+ METABLOCK_HEADER:e -> BEFORE_COMPRESSED_METABLOCK_HEADER:n
102
+
103
+ _METABLOCK_DONE_PORT_ -> METABLOCK_DONE:se
104
+ [constraint="false" ltail=cluster_command]
105
+
106
+ UNINITED [shape=Mdiamond];
107
+ DONE [shape=Msquare];
108
+ }
109
+
110
+
111
+ */
112
+
23
113
  typedef enum {
24
114
  BROTLI_STATE_UNINITED,
115
+ BROTLI_STATE_LARGE_WINDOW_BITS,
116
+ BROTLI_STATE_INITIALIZE,
25
117
  BROTLI_STATE_METABLOCK_BEGIN,
26
118
  BROTLI_STATE_METABLOCK_HEADER,
27
119
  BROTLI_STATE_METABLOCK_HEADER_2,
@@ -36,6 +128,7 @@ typedef enum {
36
128
  BROTLI_STATE_METABLOCK_DONE,
37
129
  BROTLI_STATE_COMMAND_POST_WRITE_1,
38
130
  BROTLI_STATE_COMMAND_POST_WRITE_2,
131
+ BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER,
39
132
  BROTLI_STATE_HUFFMAN_CODE_0,
40
133
  BROTLI_STATE_HUFFMAN_CODE_1,
41
134
  BROTLI_STATE_HUFFMAN_CODE_2,
@@ -43,6 +136,7 @@ typedef enum {
43
136
  BROTLI_STATE_CONTEXT_MAP_1,
44
137
  BROTLI_STATE_CONTEXT_MAP_2,
45
138
  BROTLI_STATE_TREE_GROUP,
139
+ BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY,
46
140
  BROTLI_STATE_DONE
47
141
  } BrotliRunningState;
48
142
 
@@ -95,6 +189,50 @@ typedef enum {
95
189
  BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX
96
190
  } BrotliRunningReadBlockLengthState;
97
191
 
192
+ typedef struct BrotliMetablockHeaderArena {
193
+ BrotliRunningTreeGroupState substate_tree_group;
194
+ BrotliRunningContextMapState substate_context_map;
195
+ BrotliRunningHuffmanState substate_huffman;
196
+
197
+ uint32_t sub_loop_counter;
198
+
199
+ uint32_t repeat_code_len;
200
+ uint32_t prev_code_len;
201
+
202
+ /* For ReadHuffmanCode. */
203
+ uint32_t symbol;
204
+ uint32_t repeat;
205
+ uint32_t space;
206
+
207
+ /* Huffman table for "histograms". */
208
+ HuffmanCode table[32];
209
+ /* List of heads of symbol chains. */
210
+ uint16_t* symbol_lists;
211
+ /* Storage from symbol_lists. */
212
+ uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
213
+ BROTLI_NUM_COMMAND_SYMBOLS];
214
+ /* Tails of symbol chains. */
215
+ int next_symbol[32];
216
+ uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES];
217
+ /* Population counts for the code lengths. */
218
+ uint16_t code_length_histo[16];
219
+
220
+ /* For HuffmanTreeGroupDecode. */
221
+ int htree_index;
222
+ HuffmanCode* next;
223
+
224
+ /* For DecodeContextMap. */
225
+ uint32_t context_index;
226
+ uint32_t max_run_length_prefix;
227
+ uint32_t code;
228
+ HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
229
+ } BrotliMetablockHeaderArena;
230
+
231
+ typedef struct BrotliMetablockBodyArena {
232
+ uint8_t dist_extra_bits[544];
233
+ uint32_t dist_offset[544];
234
+ } BrotliMetablockBodyArena;
235
+
98
236
  struct BrotliDecoderStateStruct {
99
237
  BrotliRunningState state;
100
238
 
@@ -107,7 +245,8 @@ struct BrotliDecoderStateStruct {
107
245
  brotli_free_func free_func;
108
246
  void* memory_manager_opaque;
109
247
 
110
- /* Temporary storage for remaining input. */
248
+ /* Temporary storage for remaining input. Brotli stream format is designed in
249
+ a way, that 64 bits are enough to make progress in decoding. */
111
250
  union {
112
251
  uint64_t u64;
113
252
  uint8_t u8[8];
@@ -122,27 +261,25 @@ struct BrotliDecoderStateStruct {
122
261
  int dist_rb_idx;
123
262
  int dist_rb[4];
124
263
  int error_code;
125
- uint32_t sub_loop_counter;
126
264
  uint8_t* ringbuffer;
127
265
  uint8_t* ringbuffer_end;
128
266
  HuffmanCode* htree_command;
129
- const uint8_t* context_lookup1;
130
- const uint8_t* context_lookup2;
267
+ const uint8_t* context_lookup;
131
268
  uint8_t* context_map_slice;
132
269
  uint8_t* dist_context_map_slice;
133
270
 
134
- /* This ring buffer holds a few past copy distances that will be used by */
135
- /* some special distance codes. */
271
+ /* This ring buffer holds a few past copy distances that will be used by
272
+ some special distance codes. */
136
273
  HuffmanTreeGroup literal_hgroup;
137
274
  HuffmanTreeGroup insert_copy_hgroup;
138
275
  HuffmanTreeGroup distance_hgroup;
139
276
  HuffmanCode* block_type_trees;
140
277
  HuffmanCode* block_len_trees;
141
278
  /* This is true if the literal context map histogram type always matches the
142
- block type. It is then not needed to keep the context (faster decoding). */
279
+ block type. It is then not needed to keep the context (faster decoding). */
143
280
  int trivial_literal_context;
144
- /* Distance context is actual after command is decoded and before distance
145
- is computed. After distance computation it is used as a temporary variable. */
281
+ /* Distance context is actual after command is decoded and before distance is
282
+ computed. After distance computation it is used as a temporary variable. */
146
283
  int distance_context;
147
284
  int meta_block_remaining_len;
148
285
  uint32_t block_length_index;
@@ -151,59 +288,27 @@ struct BrotliDecoderStateStruct {
151
288
  uint32_t block_type_rb[6];
152
289
  uint32_t distance_postfix_bits;
153
290
  uint32_t num_direct_distance_codes;
154
- int distance_postfix_mask;
155
291
  uint32_t num_dist_htrees;
156
292
  uint8_t* dist_context_map;
157
293
  HuffmanCode* literal_htree;
158
294
  uint8_t dist_htree_index;
159
- uint32_t repeat_code_len;
160
- uint32_t prev_code_len;
161
295
 
162
296
  int copy_length;
163
297
  int distance_code;
164
298
 
165
- /* For partial write operations */
166
- size_t rb_roundtrips; /* How many times we went around the ring-buffer */
167
- size_t partial_pos_out; /* How much output to the user in total */
168
-
169
- /* For ReadHuffmanCode */
170
- uint32_t symbol;
171
- uint32_t repeat;
172
- uint32_t space;
173
-
174
- HuffmanCode table[32];
175
- /* List of heads of symbol chains. */
176
- uint16_t* symbol_lists;
177
- /* Storage from symbol_lists. */
178
- uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
179
- BROTLI_NUM_COMMAND_SYMBOLS];
180
- /* Tails of symbol chains. */
181
- int next_symbol[32];
182
- uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES];
183
- /* Population counts for the code lengths */
184
- uint16_t code_length_histo[16];
185
-
186
- /* For HuffmanTreeGroupDecode */
187
- int htree_index;
188
- HuffmanCode* next;
299
+ /* For partial write operations. */
300
+ size_t rb_roundtrips; /* how many times we went around the ring-buffer */
301
+ size_t partial_pos_out; /* how much output to the user in total */
189
302
 
190
- /* For DecodeContextMap */
191
- uint32_t context_index;
192
- uint32_t max_run_length_prefix;
193
- uint32_t code;
194
- HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
195
-
196
- /* For InverseMoveToFrontTransform */
303
+ /* For InverseMoveToFrontTransform. */
197
304
  uint32_t mtf_upper_bound;
198
305
  uint32_t mtf[64 + 1];
199
306
 
200
- /* less used attributes are in the end of this struct */
201
- /* States inside function calls */
307
+ /* Less used attributes are at the end of this struct. */
308
+
309
+ /* States inside function calls. */
202
310
  BrotliRunningMetablockHeaderState substate_metablock_header;
203
- BrotliRunningTreeGroupState substate_tree_group;
204
- BrotliRunningContextMapState substate_context_map;
205
311
  BrotliRunningUncompressedState substate_uncompressed;
206
- BrotliRunningHuffmanState substate_huffman;
207
312
  BrotliRunningDecodeUint8State substate_decode_uint8;
208
313
  BrotliRunningReadBlockLengthState substate_read_block_length;
209
314
 
@@ -212,6 +317,7 @@ struct BrotliDecoderStateStruct {
212
317
  unsigned int is_metadata : 1;
213
318
  unsigned int should_wrap_ringbuffer : 1;
214
319
  unsigned int canny_ringbuffer_allocation : 1;
320
+ unsigned int large_window : 1;
215
321
  unsigned int size_nibbles : 8;
216
322
  uint32_t window_bits;
217
323
 
@@ -220,25 +326,37 @@ struct BrotliDecoderStateStruct {
220
326
  uint32_t num_literal_htrees;
221
327
  uint8_t* context_map;
222
328
  uint8_t* context_modes;
329
+
223
330
  const BrotliDictionary* dictionary;
331
+ const BrotliTransforms* transforms;
224
332
 
225
333
  uint32_t trivial_literal_contexts[8]; /* 256 bits */
334
+
335
+ union {
336
+ BrotliMetablockHeaderArena header;
337
+ BrotliMetablockBodyArena body;
338
+ } arena;
226
339
  };
227
340
 
228
341
  typedef struct BrotliDecoderStateStruct BrotliDecoderStateInternal;
229
342
  #define BrotliDecoderState BrotliDecoderStateInternal
230
343
 
231
- BROTLI_INTERNAL void BrotliDecoderStateInit(BrotliDecoderState* s);
232
- BROTLI_INTERNAL void BrotliDecoderStateInitWithCustomAllocators(
233
- BrotliDecoderState* s, brotli_alloc_func alloc_func,
234
- brotli_free_func free_func, void* opaque);
344
+ BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
345
+ brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque);
235
346
  BROTLI_INTERNAL void BrotliDecoderStateCleanup(BrotliDecoderState* s);
236
347
  BROTLI_INTERNAL void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s);
237
348
  BROTLI_INTERNAL void BrotliDecoderStateCleanupAfterMetablock(
238
349
  BrotliDecoderState* s);
239
350
  BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(
240
- BrotliDecoderState* s, HuffmanTreeGroup* group, uint32_t alphabet_size,
241
- uint32_t ntrees);
351
+ BrotliDecoderState* s, HuffmanTreeGroup* group, uint32_t alphabet_size_max,
352
+ uint32_t alphabet_size_limit, uint32_t ntrees);
353
+
354
+ #define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
355
+
356
+ #define BROTLI_DECODER_FREE(S, X) { \
357
+ S->free_func(S->memory_manager_opaque, X); \
358
+ X = NULL; \
359
+ }
242
360
 
243
361
  #if defined(__cplusplus) || defined(c_plusplus)
244
362
  } /* extern "C" */