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
@@ -10,29 +10,127 @@
10
10
  #include "./metablock.h"
11
11
 
12
12
  #include "../common/constants.h"
13
+ #include "../common/context.h"
14
+ #include "../common/platform.h"
13
15
  #include <brotli/types.h>
14
16
  #include "./bit_cost.h"
15
17
  #include "./block_splitter.h"
16
18
  #include "./cluster.h"
17
- #include "./context.h"
18
19
  #include "./entropy_encode.h"
19
20
  #include "./histogram.h"
20
21
  #include "./memory.h"
21
- #include "./port.h"
22
22
  #include "./quality.h"
23
23
 
24
24
  #if defined(__cplusplus) || defined(c_plusplus)
25
25
  extern "C" {
26
26
  #endif
27
27
 
28
+ void BrotliInitDistanceParams(BrotliEncoderParams* params,
29
+ uint32_t npostfix, uint32_t ndirect) {
30
+ BrotliDistanceParams* dist_params = &params->dist;
31
+ uint32_t alphabet_size_max;
32
+ uint32_t alphabet_size_limit;
33
+ uint32_t max_distance;
34
+
35
+ dist_params->distance_postfix_bits = npostfix;
36
+ dist_params->num_direct_distance_codes = ndirect;
37
+
38
+ alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
39
+ npostfix, ndirect, BROTLI_MAX_DISTANCE_BITS);
40
+ alphabet_size_limit = alphabet_size_max;
41
+ max_distance = ndirect + (1U << (BROTLI_MAX_DISTANCE_BITS + npostfix + 2)) -
42
+ (1U << (npostfix + 2));
43
+
44
+ if (params->large_window) {
45
+ BrotliDistanceCodeLimit limit = BrotliCalculateDistanceCodeLimit(
46
+ BROTLI_MAX_ALLOWED_DISTANCE, npostfix, ndirect);
47
+ alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
48
+ npostfix, ndirect, BROTLI_LARGE_MAX_DISTANCE_BITS);
49
+ alphabet_size_limit = limit.max_alphabet_size;
50
+ max_distance = limit.max_distance;
51
+ }
52
+
53
+ dist_params->alphabet_size_max = alphabet_size_max;
54
+ dist_params->alphabet_size_limit = alphabet_size_limit;
55
+ dist_params->max_distance = max_distance;
56
+ }
57
+
58
+ static void RecomputeDistancePrefixes(Command* cmds,
59
+ size_t num_commands,
60
+ const BrotliDistanceParams* orig_params,
61
+ const BrotliDistanceParams* new_params) {
62
+ size_t i;
63
+
64
+ if (orig_params->distance_postfix_bits == new_params->distance_postfix_bits &&
65
+ orig_params->num_direct_distance_codes ==
66
+ new_params->num_direct_distance_codes) {
67
+ return;
68
+ }
69
+
70
+ for (i = 0; i < num_commands; ++i) {
71
+ Command* cmd = &cmds[i];
72
+ if (CommandCopyLen(cmd) && cmd->cmd_prefix_ >= 128) {
73
+ PrefixEncodeCopyDistance(CommandRestoreDistanceCode(cmd, orig_params),
74
+ new_params->num_direct_distance_codes,
75
+ new_params->distance_postfix_bits,
76
+ &cmd->dist_prefix_,
77
+ &cmd->dist_extra_);
78
+ }
79
+ }
80
+ }
81
+
82
+ static BROTLI_BOOL ComputeDistanceCost(const Command* cmds,
83
+ size_t num_commands,
84
+ const BrotliDistanceParams* orig_params,
85
+ const BrotliDistanceParams* new_params,
86
+ double* cost) {
87
+ size_t i;
88
+ BROTLI_BOOL equal_params = BROTLI_FALSE;
89
+ uint16_t dist_prefix;
90
+ uint32_t dist_extra;
91
+ double extra_bits = 0.0;
92
+ HistogramDistance histo;
93
+ HistogramClearDistance(&histo);
94
+
95
+ if (orig_params->distance_postfix_bits == new_params->distance_postfix_bits &&
96
+ orig_params->num_direct_distance_codes ==
97
+ new_params->num_direct_distance_codes) {
98
+ equal_params = BROTLI_TRUE;
99
+ }
100
+
101
+ for (i = 0; i < num_commands; i++) {
102
+ const Command* cmd = &cmds[i];
103
+ if (CommandCopyLen(cmd) && cmd->cmd_prefix_ >= 128) {
104
+ if (equal_params) {
105
+ dist_prefix = cmd->dist_prefix_;
106
+ } else {
107
+ uint32_t distance = CommandRestoreDistanceCode(cmd, orig_params);
108
+ if (distance > new_params->max_distance) {
109
+ return BROTLI_FALSE;
110
+ }
111
+ PrefixEncodeCopyDistance(distance,
112
+ new_params->num_direct_distance_codes,
113
+ new_params->distance_postfix_bits,
114
+ &dist_prefix,
115
+ &dist_extra);
116
+ }
117
+ HistogramAddDistance(&histo, dist_prefix & 0x3FF);
118
+ extra_bits += dist_prefix >> 10;
119
+ }
120
+ }
121
+
122
+ *cost = BrotliPopulationCostDistance(&histo) + extra_bits;
123
+ return BROTLI_TRUE;
124
+ }
125
+
28
126
  void BrotliBuildMetaBlock(MemoryManager* m,
29
127
  const uint8_t* ringbuffer,
30
128
  const size_t pos,
31
129
  const size_t mask,
32
- const BrotliEncoderParams* params,
130
+ BrotliEncoderParams* params,
33
131
  uint8_t prev_byte,
34
132
  uint8_t prev_byte2,
35
- const Command* cmds,
133
+ Command* cmds,
36
134
  size_t num_commands,
37
135
  ContextType literal_context_mode,
38
136
  MetaBlockSplit* mb) {
@@ -45,6 +143,47 @@ void BrotliBuildMetaBlock(MemoryManager* m,
45
143
  size_t distance_histograms_size;
46
144
  size_t i;
47
145
  size_t literal_context_multiplier = 1;
146
+ uint32_t npostfix;
147
+ uint32_t ndirect_msb = 0;
148
+ BROTLI_BOOL check_orig = BROTLI_TRUE;
149
+ double best_dist_cost = 1e99;
150
+ BrotliEncoderParams orig_params = *params;
151
+ BrotliEncoderParams new_params = *params;
152
+
153
+ for (npostfix = 0; npostfix <= BROTLI_MAX_NPOSTFIX; npostfix++) {
154
+ for (; ndirect_msb < 16; ndirect_msb++) {
155
+ uint32_t ndirect = ndirect_msb << npostfix;
156
+ BROTLI_BOOL skip;
157
+ double dist_cost;
158
+ BrotliInitDistanceParams(&new_params, npostfix, ndirect);
159
+ if (npostfix == orig_params.dist.distance_postfix_bits &&
160
+ ndirect == orig_params.dist.num_direct_distance_codes) {
161
+ check_orig = BROTLI_FALSE;
162
+ }
163
+ skip = !ComputeDistanceCost(
164
+ cmds, num_commands,
165
+ &orig_params.dist, &new_params.dist, &dist_cost);
166
+ if (skip || (dist_cost > best_dist_cost)) {
167
+ break;
168
+ }
169
+ best_dist_cost = dist_cost;
170
+ params->dist = new_params.dist;
171
+ }
172
+ if (ndirect_msb > 0) ndirect_msb--;
173
+ ndirect_msb /= 2;
174
+ }
175
+ if (check_orig) {
176
+ double dist_cost;
177
+ ComputeDistanceCost(cmds, num_commands,
178
+ &orig_params.dist, &orig_params.dist, &dist_cost);
179
+ if (dist_cost < best_dist_cost) {
180
+ /* NB: currently unused; uncomment when more param tuning is added. */
181
+ /* best_dist_cost = dist_cost; */
182
+ params->dist = orig_params.dist;
183
+ }
184
+ }
185
+ RecomputeDistancePrefixes(cmds, num_commands,
186
+ &orig_params.dist, &params->dist);
48
187
 
49
188
  BrotliSplitBlock(m, cmds, num_commands,
50
189
  ringbuffer, pos, mask, params,
@@ -57,7 +196,7 @@ void BrotliBuildMetaBlock(MemoryManager* m,
57
196
  literal_context_multiplier = 1 << BROTLI_LITERAL_CONTEXT_BITS;
58
197
  literal_context_modes =
59
198
  BROTLI_ALLOC(m, ContextType, mb->literal_split.num_types);
60
- if (BROTLI_IS_OOM(m)) return;
199
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(literal_context_modes)) return;
61
200
  for (i = 0; i < mb->literal_split.num_types; ++i) {
62
201
  literal_context_modes[i] = literal_context_mode;
63
202
  }
@@ -67,21 +206,21 @@ void BrotliBuildMetaBlock(MemoryManager* m,
67
206
  mb->literal_split.num_types * literal_context_multiplier;
68
207
  literal_histograms =
69
208
  BROTLI_ALLOC(m, HistogramLiteral, literal_histograms_size);
70
- if (BROTLI_IS_OOM(m)) return;
209
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(literal_histograms)) return;
71
210
  ClearHistogramsLiteral(literal_histograms, literal_histograms_size);
72
211
 
73
212
  distance_histograms_size =
74
213
  mb->distance_split.num_types << BROTLI_DISTANCE_CONTEXT_BITS;
75
214
  distance_histograms =
76
215
  BROTLI_ALLOC(m, HistogramDistance, distance_histograms_size);
77
- if (BROTLI_IS_OOM(m)) return;
216
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(distance_histograms)) return;
78
217
  ClearHistogramsDistance(distance_histograms, distance_histograms_size);
79
218
 
80
- assert(mb->command_histograms == 0);
219
+ BROTLI_DCHECK(mb->command_histograms == 0);
81
220
  mb->command_histograms_size = mb->command_split.num_types;
82
221
  mb->command_histograms =
83
222
  BROTLI_ALLOC(m, HistogramCommand, mb->command_histograms_size);
84
- if (BROTLI_IS_OOM(m)) return;
223
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->command_histograms)) return;
85
224
  ClearHistogramsCommand(mb->command_histograms, mb->command_histograms_size);
86
225
 
87
226
  BrotliBuildHistogramsWithContext(cmds, num_commands,
@@ -90,18 +229,18 @@ void BrotliBuildMetaBlock(MemoryManager* m,
90
229
  literal_histograms, mb->command_histograms, distance_histograms);
91
230
  BROTLI_FREE(m, literal_context_modes);
92
231
 
93
- assert(mb->literal_context_map == 0);
232
+ BROTLI_DCHECK(mb->literal_context_map == 0);
94
233
  mb->literal_context_map_size =
95
234
  mb->literal_split.num_types << BROTLI_LITERAL_CONTEXT_BITS;
96
235
  mb->literal_context_map =
97
236
  BROTLI_ALLOC(m, uint32_t, mb->literal_context_map_size);
98
- if (BROTLI_IS_OOM(m)) return;
237
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->literal_context_map)) return;
99
238
 
100
- assert(mb->literal_histograms == 0);
239
+ BROTLI_DCHECK(mb->literal_histograms == 0);
101
240
  mb->literal_histograms_size = mb->literal_context_map_size;
102
241
  mb->literal_histograms =
103
242
  BROTLI_ALLOC(m, HistogramLiteral, mb->literal_histograms_size);
104
- if (BROTLI_IS_OOM(m)) return;
243
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->literal_histograms)) return;
105
244
 
106
245
  BrotliClusterHistogramsLiteral(m, literal_histograms, literal_histograms_size,
107
246
  kMaxNumberOfHistograms, mb->literal_histograms,
@@ -121,18 +260,18 @@ void BrotliBuildMetaBlock(MemoryManager* m,
121
260
  }
122
261
  }
123
262
 
124
- assert(mb->distance_context_map == 0);
263
+ BROTLI_DCHECK(mb->distance_context_map == 0);
125
264
  mb->distance_context_map_size =
126
265
  mb->distance_split.num_types << BROTLI_DISTANCE_CONTEXT_BITS;
127
266
  mb->distance_context_map =
128
267
  BROTLI_ALLOC(m, uint32_t, mb->distance_context_map_size);
129
- if (BROTLI_IS_OOM(m)) return;
268
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->distance_context_map)) return;
130
269
 
131
- assert(mb->distance_histograms == 0);
270
+ BROTLI_DCHECK(mb->distance_histograms == 0);
132
271
  mb->distance_histograms_size = mb->distance_context_map_size;
133
272
  mb->distance_histograms =
134
273
  BROTLI_ALLOC(m, HistogramDistance, mb->distance_histograms_size);
135
- if (BROTLI_IS_OOM(m)) return;
274
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->distance_histograms)) return;
136
275
 
137
276
  BrotliClusterHistogramsDistance(m, distance_histograms,
138
277
  mb->distance_context_map_size,
@@ -200,7 +339,7 @@ static void InitContextBlockSplitter(
200
339
  size_t* histograms_size) {
201
340
  size_t max_num_blocks = num_symbols / min_block_size + 1;
202
341
  size_t max_num_types;
203
- assert(num_contexts <= BROTLI_MAX_STATIC_CONTEXTS);
342
+ BROTLI_DCHECK(num_contexts <= BROTLI_MAX_STATIC_CONTEXTS);
204
343
 
205
344
  self->alphabet_size_ = alphabet_size;
206
345
  self->num_contexts_ = num_contexts;
@@ -226,11 +365,11 @@ static void InitContextBlockSplitter(
226
365
  if (BROTLI_IS_OOM(m)) return;
227
366
  split->num_blocks = max_num_blocks;
228
367
  if (BROTLI_IS_OOM(m)) return;
229
- assert(*histograms == 0);
368
+ BROTLI_DCHECK(*histograms == 0);
230
369
  *histograms_size = max_num_types * num_contexts;
231
370
  *histograms = BROTLI_ALLOC(m, HistogramLiteral, *histograms_size);
232
371
  self->histograms_ = *histograms;
233
- if (BROTLI_IS_OOM(m)) return;
372
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(*histograms)) return;
234
373
  /* Clear only current histogram. */
235
374
  ClearHistogramsLiteral(&self->histograms_[0], num_contexts);
236
375
  self->last_histogram_ix_[0] = self->last_histogram_ix_[1] = 0;
@@ -280,7 +419,7 @@ static void ContextBlockSplitterFinishBlock(
280
419
  double combined_entropy[2 * BROTLI_MAX_STATIC_CONTEXTS];
281
420
  double diff[2] = { 0.0 };
282
421
  size_t i;
283
- if (BROTLI_IS_OOM(m)) return;
422
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(combined_histo)) return;
284
423
  for (i = 0; i < num_contexts; ++i) {
285
424
  size_t curr_histo_ix = self->curr_histogram_ix_ + i;
286
425
  size_t j;
@@ -379,12 +518,12 @@ static void MapStaticContexts(MemoryManager* m,
379
518
  const uint32_t* static_context_map,
380
519
  MetaBlockSplit* mb) {
381
520
  size_t i;
382
- assert(mb->literal_context_map == 0);
521
+ BROTLI_DCHECK(mb->literal_context_map == 0);
383
522
  mb->literal_context_map_size =
384
523
  mb->literal_split.num_types << BROTLI_LITERAL_CONTEXT_BITS;
385
524
  mb->literal_context_map =
386
525
  BROTLI_ALLOC(m, uint32_t, mb->literal_context_map_size);
387
- if (BROTLI_IS_OOM(m)) return;
526
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->literal_context_map)) return;
388
527
 
389
528
  for (i = 0; i < mb->literal_split.num_types; ++i) {
390
529
  uint32_t offset = (uint32_t)(i * num_contexts);
@@ -398,9 +537,9 @@ static void MapStaticContexts(MemoryManager* m,
398
537
 
399
538
  static BROTLI_INLINE void BrotliBuildMetaBlockGreedyInternal(
400
539
  MemoryManager* m, const uint8_t* ringbuffer, size_t pos, size_t mask,
401
- uint8_t prev_byte, uint8_t prev_byte2, ContextType literal_context_mode,
540
+ uint8_t prev_byte, uint8_t prev_byte2, ContextLut literal_context_lut,
402
541
  const size_t num_contexts, const uint32_t* static_context_map,
403
- const Command *commands, size_t n_commands, MetaBlockSplit* mb) {
542
+ const Command* commands, size_t n_commands, MetaBlockSplit* mb) {
404
543
  union {
405
544
  BlockSplitterLiteral plain;
406
545
  ContextBlockSplitter ctx;
@@ -441,7 +580,8 @@ static BROTLI_INLINE void BrotliBuildMetaBlockGreedyInternal(
441
580
  if (num_contexts == 1) {
442
581
  BlockSplitterAddSymbolLiteral(&lit_blocks.plain, literal);
443
582
  } else {
444
- size_t context = Context(prev_byte, prev_byte2, literal_context_mode);
583
+ size_t context =
584
+ BROTLI_CONTEXT(prev_byte, prev_byte2, literal_context_lut);
445
585
  ContextBlockSplitterAddSymbol(&lit_blocks.ctx, m, literal,
446
586
  static_context_map[context]);
447
587
  if (BROTLI_IS_OOM(m)) return;
@@ -455,7 +595,7 @@ static BROTLI_INLINE void BrotliBuildMetaBlockGreedyInternal(
455
595
  prev_byte2 = ringbuffer[(pos - 2) & mask];
456
596
  prev_byte = ringbuffer[(pos - 1) & mask];
457
597
  if (cmd.cmd_prefix_ >= 128) {
458
- BlockSplitterAddSymbolDistance(&dist_blocks, cmd.dist_prefix_);
598
+ BlockSplitterAddSymbolDistance(&dist_blocks, cmd.dist_prefix_ & 0x3FF);
459
599
  }
460
600
  }
461
601
  }
@@ -482,7 +622,7 @@ void BrotliBuildMetaBlockGreedy(MemoryManager* m,
482
622
  size_t mask,
483
623
  uint8_t prev_byte,
484
624
  uint8_t prev_byte2,
485
- ContextType literal_context_mode,
625
+ ContextLut literal_context_lut,
486
626
  size_t num_contexts,
487
627
  const uint32_t* static_context_map,
488
628
  const Command* commands,
@@ -490,19 +630,17 @@ void BrotliBuildMetaBlockGreedy(MemoryManager* m,
490
630
  MetaBlockSplit* mb) {
491
631
  if (num_contexts == 1) {
492
632
  BrotliBuildMetaBlockGreedyInternal(m, ringbuffer, pos, mask, prev_byte,
493
- prev_byte2, literal_context_mode, 1, NULL, commands, n_commands, mb);
633
+ prev_byte2, literal_context_lut, 1, NULL, commands, n_commands, mb);
494
634
  } else {
495
635
  BrotliBuildMetaBlockGreedyInternal(m, ringbuffer, pos, mask, prev_byte,
496
- prev_byte2, literal_context_mode, num_contexts, static_context_map,
636
+ prev_byte2, literal_context_lut, num_contexts, static_context_map,
497
637
  commands, n_commands, mb);
498
638
  }
499
639
  }
500
640
 
501
- void BrotliOptimizeHistograms(size_t num_direct_distance_codes,
502
- size_t distance_postfix_bits,
641
+ void BrotliOptimizeHistograms(uint32_t num_distance_codes,
503
642
  MetaBlockSplit* mb) {
504
643
  uint8_t good_for_rle[BROTLI_NUM_COMMAND_SYMBOLS];
505
- size_t num_distance_codes;
506
644
  size_t i;
507
645
  for (i = 0; i < mb->literal_histograms_size; ++i) {
508
646
  BrotliOptimizeHuffmanCountsForRle(256, mb->literal_histograms[i].data_,
@@ -513,9 +651,6 @@ void BrotliOptimizeHistograms(size_t num_direct_distance_codes,
513
651
  mb->command_histograms[i].data_,
514
652
  good_for_rle);
515
653
  }
516
- num_distance_codes = BROTLI_NUM_DISTANCE_SHORT_CODES +
517
- num_direct_distance_codes +
518
- ((2 * BROTLI_MAX_DISTANCE_BITS) << distance_postfix_bits);
519
654
  for (i = 0; i < mb->distance_histograms_size; ++i) {
520
655
  BrotliOptimizeHuffmanCountsForRle(num_distance_codes,
521
656
  mb->distance_histograms[i].data_,
@@ -10,13 +10,13 @@
10
10
  #ifndef BROTLI_ENC_METABLOCK_H_
11
11
  #define BROTLI_ENC_METABLOCK_H_
12
12
 
13
+ #include "../common/context.h"
14
+ #include "../common/platform.h"
13
15
  #include <brotli/types.h>
14
16
  #include "./block_splitter.h"
15
17
  #include "./command.h"
16
- #include "./context.h"
17
18
  #include "./histogram.h"
18
19
  #include "./memory.h"
19
- #include "./port.h"
20
20
  #include "./quality.h"
21
21
 
22
22
  #if defined(__cplusplus) || defined(c_plusplus)
@@ -67,15 +67,18 @@ static BROTLI_INLINE void DestroyMetaBlockSplit(
67
67
  BROTLI_FREE(m, mb->distance_histograms);
68
68
  }
69
69
 
70
- /* Uses the slow shortest-path block splitter and does context clustering. */
70
+ /* Uses the slow shortest-path block splitter and does context clustering.
71
+ The distance parameters are dynamically selected based on the commands
72
+ which get recomputed under the new distance parameters. The new distance
73
+ parameters are stored into *params. */
71
74
  BROTLI_INTERNAL void BrotliBuildMetaBlock(MemoryManager* m,
72
75
  const uint8_t* ringbuffer,
73
76
  const size_t pos,
74
77
  const size_t mask,
75
- const BrotliEncoderParams* params,
78
+ BrotliEncoderParams* params,
76
79
  uint8_t prev_byte,
77
80
  uint8_t prev_byte2,
78
- const Command* cmds,
81
+ Command* cmds,
79
82
  size_t num_commands,
80
83
  ContextType literal_context_mode,
81
84
  MetaBlockSplit* mb);
@@ -85,14 +88,16 @@ BROTLI_INTERNAL void BrotliBuildMetaBlock(MemoryManager* m,
85
88
  is the same for all block types. */
86
89
  BROTLI_INTERNAL void BrotliBuildMetaBlockGreedy(
87
90
  MemoryManager* m, const uint8_t* ringbuffer, size_t pos, size_t mask,
88
- uint8_t prev_byte, uint8_t prev_byte2, ContextType literal_context_mode,
91
+ uint8_t prev_byte, uint8_t prev_byte2, ContextLut literal_context_lut,
89
92
  size_t num_contexts, const uint32_t* static_context_map,
90
93
  const Command* commands, size_t n_commands, MetaBlockSplit* mb);
91
94
 
92
- BROTLI_INTERNAL void BrotliOptimizeHistograms(size_t num_direct_distance_codes,
93
- size_t distance_postfix_bits,
95
+ BROTLI_INTERNAL void BrotliOptimizeHistograms(uint32_t num_distance_codes,
94
96
  MetaBlockSplit* mb);
95
97
 
98
+ BROTLI_INTERNAL void BrotliInitDistanceParams(BrotliEncoderParams* params,
99
+ uint32_t npostfix, uint32_t ndirect);
100
+
96
101
  #if defined(__cplusplus) || defined(c_plusplus)
97
102
  } /* extern "C" */
98
103
  #endif
@@ -67,11 +67,11 @@ static void FN(InitBlockSplitter)(
67
67
  split->lengths, split->lengths_alloc_size, max_num_blocks);
68
68
  if (BROTLI_IS_OOM(m)) return;
69
69
  self->split_->num_blocks = max_num_blocks;
70
- assert(*histograms == 0);
70
+ BROTLI_DCHECK(*histograms == 0);
71
71
  *histograms_size = max_num_types;
72
72
  *histograms = BROTLI_ALLOC(m, HistogramType, *histograms_size);
73
73
  self->histograms_ = *histograms;
74
- if (BROTLI_IS_OOM(m)) return;
74
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(*histograms)) return;
75
75
  /* Clear only current histogram. */
76
76
  FN(HistogramClear)(&self->histograms_[0]);
77
77
  self->last_histogram_ix_[0] = self->last_histogram_ix_[1] = 0;
@@ -0,0 +1,46 @@
1
+ /* Copyright 2017 Google Inc. All Rights Reserved.
2
+
3
+ Distributed under MIT license.
4
+ See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5
+ */
6
+
7
+ /* Parameters for the Brotli encoder with chosen quality levels. */
8
+
9
+ #ifndef BROTLI_ENC_PARAMS_H_
10
+ #define BROTLI_ENC_PARAMS_H_
11
+
12
+ #include <brotli/encode.h>
13
+ #include "./encoder_dict.h"
14
+
15
+ typedef struct BrotliHasherParams {
16
+ int type;
17
+ int bucket_bits;
18
+ int block_bits;
19
+ int hash_len;
20
+ int num_last_distances_to_check;
21
+ } BrotliHasherParams;
22
+
23
+ typedef struct BrotliDistanceParams {
24
+ uint32_t distance_postfix_bits;
25
+ uint32_t num_direct_distance_codes;
26
+ uint32_t alphabet_size_max;
27
+ uint32_t alphabet_size_limit;
28
+ size_t max_distance;
29
+ } BrotliDistanceParams;
30
+
31
+ /* Encoding parameters */
32
+ typedef struct BrotliEncoderParams {
33
+ BrotliEncoderMode mode;
34
+ int quality;
35
+ int lgwin;
36
+ int lgblock;
37
+ size_t stream_offset;
38
+ size_t size_hint;
39
+ BROTLI_BOOL disable_literal_context_modeling;
40
+ BROTLI_BOOL large_window;
41
+ BrotliHasherParams hasher;
42
+ BrotliDistanceParams dist;
43
+ BrotliEncoderDictionary dictionary;
44
+ } BrotliEncoderParams;
45
+
46
+ #endif /* BROTLI_ENC_PARAMS_H_ */