brotli 0.2.0 → 0.2.1

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 (106) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +1 -0
  3. data/Rakefile +6 -1
  4. data/brotli.gemspec +1 -1
  5. data/docs/Brotli.html +485 -0
  6. data/docs/Brotli/Error.html +124 -0
  7. data/docs/_index.html +122 -0
  8. data/docs/class_list.html +51 -0
  9. data/docs/css/common.css +1 -0
  10. data/docs/css/full_list.css +58 -0
  11. data/docs/css/style.css +496 -0
  12. data/docs/file.README.html +127 -0
  13. data/docs/file_list.html +56 -0
  14. data/docs/frames.html +17 -0
  15. data/docs/index.html +127 -0
  16. data/docs/js/app.js +292 -0
  17. data/docs/js/full_list.js +216 -0
  18. data/docs/js/jquery.js +4 -0
  19. data/docs/method_list.html +67 -0
  20. data/docs/top-level-namespace.html +110 -0
  21. data/ext/brotli/brotli.c +20 -0
  22. data/lib/brotli/version.rb +1 -1
  23. data/vendor/brotli/c/common/constants.h +13 -6
  24. data/vendor/brotli/c/{dec → common}/context.h +182 -172
  25. data/vendor/brotli/c/common/dictionary.bin +0 -0
  26. data/vendor/brotli/c/common/dictionary.bin.br +0 -0
  27. data/vendor/brotli/c/common/dictionary.c +1 -1
  28. data/vendor/brotli/c/common/dictionary.h +4 -4
  29. data/vendor/brotli/c/common/platform.h +509 -0
  30. data/vendor/brotli/c/common/transform.c +235 -0
  31. data/vendor/brotli/c/common/transform.h +80 -0
  32. data/vendor/brotli/c/common/version.h +8 -1
  33. data/vendor/brotli/c/dec/bit_reader.c +1 -1
  34. data/vendor/brotli/c/dec/bit_reader.h +35 -86
  35. data/vendor/brotli/c/dec/decode.c +322 -205
  36. data/vendor/brotli/c/dec/huffman.c +35 -37
  37. data/vendor/brotli/c/dec/huffman.h +13 -9
  38. data/vendor/brotli/c/dec/prefix.h +3 -4
  39. data/vendor/brotli/c/dec/state.c +26 -34
  40. data/vendor/brotli/c/dec/state.h +34 -23
  41. data/vendor/brotli/c/enc/backward_references.c +25 -15
  42. data/vendor/brotli/c/enc/backward_references.h +5 -6
  43. data/vendor/brotli/c/enc/backward_references_hq.c +94 -68
  44. data/vendor/brotli/c/enc/backward_references_hq.h +22 -25
  45. data/vendor/brotli/c/enc/backward_references_inc.h +10 -10
  46. data/vendor/brotli/c/enc/bit_cost.c +1 -1
  47. data/vendor/brotli/c/enc/bit_cost.h +5 -5
  48. data/vendor/brotli/c/enc/block_encoder_inc.h +7 -6
  49. data/vendor/brotli/c/enc/block_splitter.c +2 -3
  50. data/vendor/brotli/c/enc/block_splitter.h +1 -1
  51. data/vendor/brotli/c/enc/block_splitter_inc.h +11 -11
  52. data/vendor/brotli/c/enc/brotli_bit_stream.c +102 -101
  53. data/vendor/brotli/c/enc/brotli_bit_stream.h +19 -38
  54. data/vendor/brotli/c/enc/cluster.c +1 -1
  55. data/vendor/brotli/c/enc/cluster.h +1 -1
  56. data/vendor/brotli/c/enc/command.h +40 -30
  57. data/vendor/brotli/c/enc/compress_fragment.c +21 -22
  58. data/vendor/brotli/c/enc/compress_fragment.h +1 -1
  59. data/vendor/brotli/c/enc/compress_fragment_two_pass.c +101 -68
  60. data/vendor/brotli/c/enc/compress_fragment_two_pass.h +1 -1
  61. data/vendor/brotli/c/enc/dictionary_hash.c +1 -1
  62. data/vendor/brotli/c/enc/encode.c +262 -162
  63. data/vendor/brotli/c/enc/encoder_dict.c +32 -0
  64. data/vendor/brotli/c/enc/encoder_dict.h +41 -0
  65. data/vendor/brotli/c/enc/entropy_encode.c +14 -14
  66. data/vendor/brotli/c/enc/entropy_encode.h +5 -5
  67. data/vendor/brotli/c/enc/entropy_encode_static.h +3 -3
  68. data/vendor/brotli/c/enc/fast_log.h +4 -2
  69. data/vendor/brotli/c/enc/find_match_length.h +3 -3
  70. data/vendor/brotli/c/enc/hash.h +75 -24
  71. data/vendor/brotli/c/enc/hash_composite_inc.h +133 -0
  72. data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +9 -8
  73. data/vendor/brotli/c/enc/hash_longest_match64_inc.h +8 -8
  74. data/vendor/brotli/c/enc/hash_longest_match_inc.h +8 -8
  75. data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +10 -9
  76. data/vendor/brotli/c/enc/hash_rolling_inc.h +215 -0
  77. data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +9 -8
  78. data/vendor/brotli/c/enc/histogram.c +9 -6
  79. data/vendor/brotli/c/enc/histogram.h +6 -3
  80. data/vendor/brotli/c/enc/histogram_inc.h +1 -1
  81. data/vendor/brotli/c/enc/literal_cost.c +5 -5
  82. data/vendor/brotli/c/enc/literal_cost.h +2 -2
  83. data/vendor/brotli/c/enc/memory.c +5 -16
  84. data/vendor/brotli/c/enc/memory.h +40 -1
  85. data/vendor/brotli/c/enc/metablock.c +163 -25
  86. data/vendor/brotli/c/enc/metablock.h +13 -8
  87. data/vendor/brotli/c/enc/metablock_inc.h +1 -1
  88. data/vendor/brotli/c/enc/params.h +44 -0
  89. data/vendor/brotli/c/enc/prefix.h +3 -4
  90. data/vendor/brotli/c/enc/quality.h +29 -24
  91. data/vendor/brotli/c/enc/ringbuffer.h +15 -11
  92. data/vendor/brotli/c/enc/static_dict.c +49 -45
  93. data/vendor/brotli/c/enc/static_dict.h +4 -3
  94. data/vendor/brotli/c/enc/static_dict_lut.h +1 -1
  95. data/vendor/brotli/c/enc/utf8_util.c +20 -20
  96. data/vendor/brotli/c/enc/utf8_util.h +1 -1
  97. data/vendor/brotli/c/enc/write_bits.h +16 -21
  98. data/vendor/brotli/c/include/brotli/decode.h +13 -8
  99. data/vendor/brotli/c/include/brotli/encode.h +33 -8
  100. data/vendor/brotli/c/include/brotli/port.h +211 -83
  101. data/vendor/brotli/c/include/brotli/types.h +0 -7
  102. metadata +33 -12
  103. data/vendor/brotli/c/dec/port.h +0 -168
  104. data/vendor/brotli/c/dec/transform.h +0 -300
  105. data/vendor/brotli/c/enc/context.h +0 -184
  106. data/vendor/brotli/c/enc/port.h +0 -184
@@ -10,11 +10,11 @@
10
10
 
11
11
  #include "../common/constants.h"
12
12
  #include "../common/dictionary.h"
13
+ #include "../common/platform.h"
13
14
  #include <brotli/types.h>
14
15
  #include "./command.h"
15
16
  #include "./dictionary_hash.h"
16
17
  #include "./memory.h"
17
- #include "./port.h"
18
18
  #include "./quality.h"
19
19
 
20
20
  #if defined(__cplusplus) || defined(c_plusplus)
@@ -49,6 +49,7 @@ static BROTLI_INLINE size_t ComputeDistanceCode(size_t distance,
49
49
  #define CAT(a, b) a ## b
50
50
  #define FN(X) EXPAND_CAT(X, HASHER())
51
51
  #define EXPORT_FN(X) EXPAND_CAT(X, EXPAND_CAT(PREFIX(), HASHER()))
52
+
52
53
  #define PREFIX() N
53
54
 
54
55
  #define HASHER() H2
@@ -96,29 +97,38 @@ static BROTLI_INLINE size_t ComputeDistanceCode(size_t distance,
96
97
  #include "./backward_references_inc.h"
97
98
  #undef HASHER
98
99
 
100
+ #define HASHER() H35
101
+ /* NOLINTNEXTLINE(build/include) */
102
+ #include "./backward_references_inc.h"
103
+ #undef HASHER
104
+
105
+ #define HASHER() H55
106
+ /* NOLINTNEXTLINE(build/include) */
107
+ #include "./backward_references_inc.h"
108
+ #undef HASHER
109
+
110
+ #define HASHER() H65
111
+ /* NOLINTNEXTLINE(build/include) */
112
+ #include "./backward_references_inc.h"
113
+ #undef HASHER
114
+
99
115
  #undef PREFIX
116
+
100
117
  #undef EXPORT_FN
101
118
  #undef FN
102
119
  #undef CAT
103
120
  #undef EXPAND_CAT
104
121
 
105
- void BrotliCreateBackwardReferences(const BrotliDictionary* dictionary,
106
- size_t num_bytes,
107
- size_t position,
108
- const uint8_t* ringbuffer,
109
- size_t ringbuffer_mask,
110
- const BrotliEncoderParams* params,
111
- HasherHandle hasher,
112
- int* dist_cache,
113
- size_t* last_insert_len,
114
- Command* commands,
115
- size_t* num_commands,
116
- size_t* num_literals) {
122
+ void BrotliCreateBackwardReferences(
123
+ size_t num_bytes, size_t position, const uint8_t* ringbuffer,
124
+ size_t ringbuffer_mask, const BrotliEncoderParams* params,
125
+ HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
126
+ Command* commands, size_t* num_commands, size_t* num_literals) {
117
127
  switch (params->hasher.type) {
118
128
  #define CASE_(N) \
119
129
  case N: \
120
- CreateBackwardReferencesNH ## N(dictionary, \
121
- kStaticDictionaryHash, num_bytes, position, ringbuffer, \
130
+ CreateBackwardReferencesNH ## N( \
131
+ num_bytes, position, ringbuffer, \
122
132
  ringbuffer_mask, params, hasher, dist_cache, \
123
133
  last_insert_len, commands, num_commands, num_literals); \
124
134
  return;
@@ -11,10 +11,10 @@
11
11
 
12
12
  #include "../common/constants.h"
13
13
  #include "../common/dictionary.h"
14
+ #include "../common/platform.h"
14
15
  #include <brotli/types.h>
15
16
  #include "./command.h"
16
17
  #include "./hash.h"
17
- #include "./port.h"
18
18
  #include "./quality.h"
19
19
 
20
20
  #if defined(__cplusplus) || defined(c_plusplus)
@@ -26,11 +26,10 @@ extern "C" {
26
26
  CreateBackwardReferences calls, and must be incremented by the amount written
27
27
  by this call. */
28
28
  BROTLI_INTERNAL void BrotliCreateBackwardReferences(
29
- const BrotliDictionary* dictionary, size_t num_bytes, size_t position,
30
- const uint8_t* ringbuffer, size_t ringbuffer_mask,
31
- const BrotliEncoderParams* params, HasherHandle hasher, int* dist_cache,
32
- size_t* last_insert_len, Command* commands, size_t* num_commands,
33
- size_t* num_literals);
29
+ size_t num_bytes, size_t position, const uint8_t* ringbuffer,
30
+ size_t ringbuffer_mask, const BrotliEncoderParams* params,
31
+ HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
32
+ Command* commands, size_t* num_commands, size_t* num_literals);
34
33
 
35
34
  #if defined(__cplusplus) || defined(c_plusplus)
36
35
  } /* extern "C" */
@@ -11,13 +11,14 @@
11
11
  #include <string.h> /* memcpy, memset */
12
12
 
13
13
  #include "../common/constants.h"
14
+ #include "../common/platform.h"
14
15
  #include <brotli/types.h>
15
16
  #include "./command.h"
16
17
  #include "./fast_log.h"
17
18
  #include "./find_match_length.h"
18
19
  #include "./literal_cost.h"
19
20
  #include "./memory.h"
20
- #include "./port.h"
21
+ #include "./params.h"
21
22
  #include "./prefix.h"
22
23
  #include "./quality.h"
23
24
 
@@ -25,6 +26,8 @@
25
26
  extern "C" {
26
27
  #endif
27
28
 
29
+ #define BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE 544
30
+
28
31
  static const float kInfinity = 1.7e38f; /* ~= 2 ^ 127 */
29
32
 
30
33
  static const uint32_t kDistanceCacheIndex[] = {
@@ -39,40 +42,41 @@ void BrotliInitZopfliNodes(ZopfliNode* array, size_t length) {
39
42
  size_t i;
40
43
  stub.length = 1;
41
44
  stub.distance = 0;
42
- stub.insert_length = 0;
45
+ stub.dcode_insert_length = 0;
43
46
  stub.u.cost = kInfinity;
44
47
  for (i = 0; i < length; ++i) array[i] = stub;
45
48
  }
46
49
 
47
50
  static BROTLI_INLINE uint32_t ZopfliNodeCopyLength(const ZopfliNode* self) {
48
- return self->length & 0xffffff;
51
+ return self->length & 0x1FFFFFF;
49
52
  }
50
53
 
51
54
  static BROTLI_INLINE uint32_t ZopfliNodeLengthCode(const ZopfliNode* self) {
52
- const uint32_t modifier = self->length >> 24;
55
+ const uint32_t modifier = self->length >> 25;
53
56
  return ZopfliNodeCopyLength(self) + 9u - modifier;
54
57
  }
55
58
 
56
59
  static BROTLI_INLINE uint32_t ZopfliNodeCopyDistance(const ZopfliNode* self) {
57
- return self->distance & 0x1ffffff;
60
+ return self->distance;
58
61
  }
59
62
 
60
63
  static BROTLI_INLINE uint32_t ZopfliNodeDistanceCode(const ZopfliNode* self) {
61
- const uint32_t short_code = self->distance >> 25;
64
+ const uint32_t short_code = self->dcode_insert_length >> 27;
62
65
  return short_code == 0 ?
63
66
  ZopfliNodeCopyDistance(self) + BROTLI_NUM_DISTANCE_SHORT_CODES - 1 :
64
67
  short_code - 1;
65
68
  }
66
69
 
67
70
  static BROTLI_INLINE uint32_t ZopfliNodeCommandLength(const ZopfliNode* self) {
68
- return ZopfliNodeCopyLength(self) + self->insert_length;
71
+ return ZopfliNodeCopyLength(self) + (self->dcode_insert_length & 0x7FFFFFF);
69
72
  }
70
73
 
71
74
  /* Histogram based cost model for zopflification. */
72
75
  typedef struct ZopfliCostModel {
73
76
  /* The insert and copy length symbols. */
74
77
  float cost_cmd_[BROTLI_NUM_COMMAND_SYMBOLS];
75
- float cost_dist_[BROTLI_NUM_DISTANCE_SYMBOLS];
78
+ float* cost_dist_;
79
+ uint32_t distance_histogram_size;
76
80
  /* Cumulative costs of literals per position in the stream. */
77
81
  float* literal_costs_;
78
82
  float min_cost_cmd_;
@@ -80,28 +84,45 @@ typedef struct ZopfliCostModel {
80
84
  } ZopfliCostModel;
81
85
 
82
86
  static void InitZopfliCostModel(
83
- MemoryManager* m, ZopfliCostModel* self, size_t num_bytes) {
87
+ MemoryManager* m, ZopfliCostModel* self, const BrotliDistanceParams* dist,
88
+ size_t num_bytes) {
89
+ uint32_t distance_histogram_size = dist->alphabet_size;
90
+ if (distance_histogram_size > BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE) {
91
+ distance_histogram_size = BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE;
92
+ }
84
93
  self->num_bytes_ = num_bytes;
85
94
  self->literal_costs_ = BROTLI_ALLOC(m, float, num_bytes + 2);
95
+ self->cost_dist_ = BROTLI_ALLOC(m, float, dist->alphabet_size);
96
+ self->distance_histogram_size = distance_histogram_size;
86
97
  if (BROTLI_IS_OOM(m)) return;
87
98
  }
88
99
 
89
100
  static void CleanupZopfliCostModel(MemoryManager* m, ZopfliCostModel* self) {
90
101
  BROTLI_FREE(m, self->literal_costs_);
102
+ BROTLI_FREE(m, self->cost_dist_);
91
103
  }
92
104
 
93
105
  static void SetCost(const uint32_t* histogram, size_t histogram_size,
94
- float* cost) {
106
+ BROTLI_BOOL literal_histogram, float* cost) {
95
107
  size_t sum = 0;
108
+ size_t missing_symbol_sum;
96
109
  float log2sum;
110
+ float missing_symbol_cost;
97
111
  size_t i;
98
112
  for (i = 0; i < histogram_size; i++) {
99
113
  sum += histogram[i];
100
114
  }
101
115
  log2sum = (float)FastLog2(sum);
116
+ missing_symbol_sum = sum;
117
+ if (!literal_histogram) {
118
+ for (i = 0; i < histogram_size; i++) {
119
+ if (histogram[i] == 0) missing_symbol_sum++;
120
+ }
121
+ }
122
+ missing_symbol_cost = (float)FastLog2(missing_symbol_sum) + 2;
102
123
  for (i = 0; i < histogram_size; i++) {
103
124
  if (histogram[i] == 0) {
104
- cost[i] = log2sum + 2;
125
+ cost[i] = missing_symbol_cost;
105
126
  continue;
106
127
  }
107
128
 
@@ -122,7 +143,7 @@ static void ZopfliCostModelSetFromCommands(ZopfliCostModel* self,
122
143
  size_t last_insert_len) {
123
144
  uint32_t histogram_literal[BROTLI_NUM_LITERAL_SYMBOLS];
124
145
  uint32_t histogram_cmd[BROTLI_NUM_COMMAND_SYMBOLS];
125
- uint32_t histogram_dist[BROTLI_NUM_DISTANCE_SYMBOLS];
146
+ uint32_t histogram_dist[BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE];
126
147
  float cost_literal[BROTLI_NUM_LITERAL_SYMBOLS];
127
148
  size_t pos = position - last_insert_len;
128
149
  float min_cost_cmd = kInfinity;
@@ -136,7 +157,7 @@ static void ZopfliCostModelSetFromCommands(ZopfliCostModel* self,
136
157
  for (i = 0; i < num_commands; i++) {
137
158
  size_t inslength = commands[i].insert_len_;
138
159
  size_t copylength = CommandCopyLen(&commands[i]);
139
- size_t distcode = commands[i].dist_prefix_;
160
+ size_t distcode = commands[i].dist_prefix_ & 0x3FF;
140
161
  size_t cmdcode = commands[i].cmd_prefix_;
141
162
  size_t j;
142
163
 
@@ -150,9 +171,12 @@ static void ZopfliCostModelSetFromCommands(ZopfliCostModel* self,
150
171
  pos += inslength + copylength;
151
172
  }
152
173
 
153
- SetCost(histogram_literal, BROTLI_NUM_LITERAL_SYMBOLS, cost_literal);
154
- SetCost(histogram_cmd, BROTLI_NUM_COMMAND_SYMBOLS, cost_cmd);
155
- SetCost(histogram_dist, BROTLI_NUM_DISTANCE_SYMBOLS, self->cost_dist_);
174
+ SetCost(histogram_literal, BROTLI_NUM_LITERAL_SYMBOLS, BROTLI_TRUE,
175
+ cost_literal);
176
+ SetCost(histogram_cmd, BROTLI_NUM_COMMAND_SYMBOLS, BROTLI_FALSE,
177
+ cost_cmd);
178
+ SetCost(histogram_dist, self->distance_histogram_size, BROTLI_FALSE,
179
+ self->cost_dist_);
156
180
 
157
181
  for (i = 0; i < BROTLI_NUM_COMMAND_SYMBOLS; ++i) {
158
182
  min_cost_cmd = BROTLI_MIN(float, min_cost_cmd, cost_cmd[i]);
@@ -161,11 +185,14 @@ static void ZopfliCostModelSetFromCommands(ZopfliCostModel* self,
161
185
 
162
186
  {
163
187
  float* literal_costs = self->literal_costs_;
188
+ float literal_carry = 0.0;
164
189
  size_t num_bytes = self->num_bytes_;
165
190
  literal_costs[0] = 0.0;
166
191
  for (i = 0; i < num_bytes; ++i) {
167
- literal_costs[i + 1] = literal_costs[i] +
192
+ literal_carry +=
168
193
  cost_literal[ringbuffer[(position + i) & ringbuffer_mask]];
194
+ literal_costs[i + 1] = literal_costs[i] + literal_carry;
195
+ literal_carry -= literal_costs[i + 1] - literal_costs[i];
169
196
  }
170
197
  }
171
198
  }
@@ -175,6 +202,7 @@ static void ZopfliCostModelSetFromLiteralCosts(ZopfliCostModel* self,
175
202
  const uint8_t* ringbuffer,
176
203
  size_t ringbuffer_mask) {
177
204
  float* literal_costs = self->literal_costs_;
205
+ float literal_carry = 0.0;
178
206
  float* cost_dist = self->cost_dist_;
179
207
  float* cost_cmd = self->cost_cmd_;
180
208
  size_t num_bytes = self->num_bytes_;
@@ -183,12 +211,14 @@ static void ZopfliCostModelSetFromLiteralCosts(ZopfliCostModel* self,
183
211
  ringbuffer, &literal_costs[1]);
184
212
  literal_costs[0] = 0.0;
185
213
  for (i = 0; i < num_bytes; ++i) {
186
- literal_costs[i + 1] += literal_costs[i];
214
+ literal_carry += literal_costs[i + 1];
215
+ literal_costs[i + 1] = literal_costs[i] + literal_carry;
216
+ literal_carry -= literal_costs[i + 1] - literal_costs[i];
187
217
  }
188
218
  for (i = 0; i < BROTLI_NUM_COMMAND_SYMBOLS; ++i) {
189
219
  cost_cmd[i] = (float)FastLog2(11 + (uint32_t)i);
190
220
  }
191
- for (i = 0; i < BROTLI_NUM_DISTANCE_SYMBOLS; ++i) {
221
+ for (i = 0; i < self->distance_histogram_size; ++i) {
192
222
  cost_dist[i] = (float)FastLog2(20 + (uint32_t)i);
193
223
  }
194
224
  self->min_cost_cmd_ = (float)FastLog2(11);
@@ -221,9 +251,10 @@ static BROTLI_INLINE void UpdateZopfliNode(ZopfliNode* nodes, size_t pos,
221
251
  size_t start_pos, size_t len, size_t len_code, size_t dist,
222
252
  size_t short_code, float cost) {
223
253
  ZopfliNode* next = &nodes[pos + len];
224
- next->length = (uint32_t)(len | ((len + 9u - len_code) << 24));
225
- next->distance = (uint32_t)(dist | (short_code << 25));
226
- next->insert_length = (uint32_t)(pos - start_pos);
254
+ next->length = (uint32_t)(len | ((len + 9u - len_code) << 25));
255
+ next->distance = (uint32_t)dist;
256
+ next->dcode_insert_length = (uint32_t)(
257
+ (short_code << 27) | (pos - start_pos));
227
258
  next->u.cost = cost;
228
259
  }
229
260
 
@@ -303,7 +334,7 @@ static uint32_t ComputeDistanceShortcut(const size_t block_start,
303
334
  const size_t gap,
304
335
  const ZopfliNode* nodes) {
305
336
  const size_t clen = ZopfliNodeCopyLength(&nodes[pos]);
306
- const size_t ilen = nodes[pos].insert_length;
337
+ const size_t ilen = nodes[pos].dcode_insert_length & 0x7FFFFFF;
307
338
  const size_t dist = ZopfliNodeCopyDistance(&nodes[pos]);
308
339
  /* Since |block_start + pos| is the end position of the command, the copy part
309
340
  starts from |block_start + pos - clen|. Distances that are greater than
@@ -335,7 +366,7 @@ static void ComputeDistanceCache(const size_t pos,
335
366
  int idx = 0;
336
367
  size_t p = nodes[pos].u.shortcut;
337
368
  while (idx < 4 && p > 0) {
338
- const size_t ilen = nodes[p].insert_length;
369
+ const size_t ilen = nodes[p].dcode_insert_length & 0x7FFFFFF;
339
370
  const size_t clen = ZopfliNodeCopyLength(&nodes[p]);
340
371
  const size_t dist = ZopfliNodeCopyDistance(&nodes[p]);
341
372
  dist_cache[idx++] = (int)dist;
@@ -482,10 +513,12 @@ static size_t UpdateNodes(
482
513
  uint32_t distnumextra;
483
514
  float dist_cost;
484
515
  size_t max_match_len;
485
- PrefixEncodeCopyDistance(dist_code, 0, 0, &dist_symbol, &distextra);
486
- distnumextra = distextra >> 24;
516
+ PrefixEncodeCopyDistance(
517
+ dist_code, params->dist.num_direct_distance_codes,
518
+ params->dist.distance_postfix_bits, &dist_symbol, &distextra);
519
+ distnumextra = dist_symbol >> 10;
487
520
  dist_cost = base_cost + (float)distnumextra +
488
- ZopfliCostModelGetDistanceCost(model, dist_symbol);
521
+ ZopfliCostModelGetDistanceCost(model, dist_symbol & 0x3FF);
489
522
 
490
523
  /* Try all copy lengths up until the maximum copy length corresponding
491
524
  to this distance. If the distance refers to the static dictionary, or
@@ -517,7 +550,8 @@ static size_t ComputeShortestPathFromNodes(size_t num_bytes,
517
550
  ZopfliNode* nodes) {
518
551
  size_t index = num_bytes;
519
552
  size_t num_commands = 0;
520
- while (nodes[index].insert_length == 0 && nodes[index].length == 1) --index;
553
+ while ((nodes[index].dcode_insert_length & 0x7FFFFFF) == 0 &&
554
+ nodes[index].length == 1) --index;
521
555
  nodes[index].u.next = BROTLI_UINT32_MAX;
522
556
  while (index != 0) {
523
557
  size_t len = ZopfliNodeCommandLength(&nodes[index]);
@@ -542,11 +576,10 @@ void BrotliZopfliCreateCommands(const size_t num_bytes,
542
576
  uint32_t offset = nodes[0].u.next;
543
577
  size_t i;
544
578
  size_t gap = 0;
545
- BROTLI_UNUSED(params);
546
579
  for (i = 0; offset != BROTLI_UINT32_MAX; i++) {
547
580
  const ZopfliNode* next = &nodes[pos + offset];
548
581
  size_t copy_length = ZopfliNodeCopyLength(next);
549
- size_t insert_length = next->insert_length;
582
+ size_t insert_length = next->dcode_insert_length & 0x7FFFFFF;
550
583
  pos += insert_length;
551
584
  offset = next->u.next;
552
585
  if (i == 0) {
@@ -560,8 +593,7 @@ void BrotliZopfliCreateCommands(const size_t num_bytes,
560
593
  BROTLI_MIN(size_t, block_start + pos, max_backward_limit);
561
594
  BROTLI_BOOL is_dictionary = TO_BROTLI_BOOL(distance > max_distance + gap);
562
595
  size_t dist_code = ZopfliNodeDistanceCode(next);
563
-
564
- InitCommand(&commands[i], insert_length,
596
+ InitCommand(&commands[i], &params->dist, insert_length,
565
597
  copy_length, (int)len_code - (int)copy_length, dist_code);
566
598
 
567
599
  if (!is_dictionary && dist_code > 0) {
@@ -625,27 +657,22 @@ static size_t ZopfliIterate(size_t num_bytes,
625
657
 
626
658
  /* REQUIRES: nodes != NULL and len(nodes) >= num_bytes + 1 */
627
659
  size_t BrotliZopfliComputeShortestPath(MemoryManager* m,
628
- const BrotliDictionary* dictionary,
629
- size_t num_bytes,
630
- size_t position,
631
- const uint8_t* ringbuffer,
632
- size_t ringbuffer_mask,
633
- const BrotliEncoderParams* params,
634
- const size_t max_backward_limit,
635
- const int* dist_cache,
636
- HasherHandle hasher,
637
- ZopfliNode* nodes) {
660
+ size_t num_bytes, size_t position, const uint8_t* ringbuffer,
661
+ size_t ringbuffer_mask, const BrotliEncoderParams* params,
662
+ const size_t max_backward_limit, const int* dist_cache, HasherHandle hasher,
663
+ ZopfliNode* nodes) {
638
664
  const size_t max_zopfli_len = MaxZopfliLen(params);
639
665
  ZopfliCostModel model;
640
666
  StartPosQueue queue;
641
- BackwardMatch matches[MAX_NUM_MATCHES_H10];
667
+ BackwardMatch matches[2 * (MAX_NUM_MATCHES_H10 + 64)];
642
668
  const size_t store_end = num_bytes >= StoreLookaheadH10() ?
643
669
  position + num_bytes - StoreLookaheadH10() + 1 : position;
644
670
  size_t i;
645
671
  size_t gap = 0;
672
+ size_t lz_matches_offset = 0;
646
673
  nodes[0].length = 0;
647
674
  nodes[0].u.cost = 0;
648
- InitZopfliCostModel(m, &model, num_bytes);
675
+ InitZopfliCostModel(m, &model, &params->dist, num_bytes);
649
676
  if (BROTLI_IS_OOM(m)) return 0;
650
677
  ZopfliCostModelSetFromLiteralCosts(
651
678
  &model, position, ringbuffer, ringbuffer_mask);
@@ -653,10 +680,10 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m,
653
680
  for (i = 0; i + HashTypeLengthH10() - 1 < num_bytes; i++) {
654
681
  const size_t pos = position + i;
655
682
  const size_t max_distance = BROTLI_MIN(size_t, pos, max_backward_limit);
656
- size_t num_matches = FindAllMatchesH10(hasher, dictionary, ringbuffer,
657
- ringbuffer_mask, pos, num_bytes - i, max_distance, gap, params,
658
- matches);
659
683
  size_t skip;
684
+ size_t num_matches = FindAllMatchesH10(hasher, &params->dictionary,
685
+ ringbuffer, ringbuffer_mask, pos, num_bytes - i, max_distance, gap,
686
+ params, &matches[lz_matches_offset]);
660
687
  if (num_matches > 0 &&
661
688
  BackwardMatchLength(&matches[num_matches - 1]) > max_zopfli_len) {
662
689
  matches[0] = matches[num_matches - 1];
@@ -687,32 +714,30 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m,
687
714
  return ComputeShortestPathFromNodes(num_bytes, nodes);
688
715
  }
689
716
 
690
- void BrotliCreateZopfliBackwardReferences(
691
- MemoryManager* m, const BrotliDictionary* dictionary, size_t num_bytes,
692
- size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
693
- const BrotliEncoderParams* params, HasherHandle hasher, int* dist_cache,
694
- size_t* last_insert_len, Command* commands, size_t* num_commands,
695
- size_t* num_literals) {
717
+ void BrotliCreateZopfliBackwardReferences(MemoryManager* m,
718
+ size_t num_bytes, size_t position, const uint8_t* ringbuffer,
719
+ size_t ringbuffer_mask, const BrotliEncoderParams* params,
720
+ HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
721
+ Command* commands, size_t* num_commands, size_t* num_literals) {
696
722
  const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
697
723
  ZopfliNode* nodes;
698
724
  nodes = BROTLI_ALLOC(m, ZopfliNode, num_bytes + 1);
699
725
  if (BROTLI_IS_OOM(m)) return;
700
726
  BrotliInitZopfliNodes(nodes, num_bytes + 1);
701
- *num_commands += BrotliZopfliComputeShortestPath(m, dictionary, num_bytes,
702
- position, ringbuffer, ringbuffer_mask, params, max_backward_limit,
703
- dist_cache, hasher, nodes);
727
+ *num_commands += BrotliZopfliComputeShortestPath(m,
728
+ num_bytes, position, ringbuffer, ringbuffer_mask,
729
+ params, max_backward_limit, dist_cache, hasher, nodes);
704
730
  if (BROTLI_IS_OOM(m)) return;
705
731
  BrotliZopfliCreateCommands(num_bytes, position, max_backward_limit, nodes,
706
732
  dist_cache, last_insert_len, params, commands, num_literals);
707
733
  BROTLI_FREE(m, nodes);
708
734
  }
709
735
 
710
- void BrotliCreateHqZopfliBackwardReferences(
711
- MemoryManager* m, const BrotliDictionary* dictionary, size_t num_bytes,
712
- size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
713
- const BrotliEncoderParams* params, HasherHandle hasher, int* dist_cache,
714
- size_t* last_insert_len, Command* commands, size_t* num_commands,
715
- size_t* num_literals) {
736
+ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m,
737
+ size_t num_bytes, size_t position, const uint8_t* ringbuffer,
738
+ size_t ringbuffer_mask, const BrotliEncoderParams* params,
739
+ HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
740
+ Command* commands, size_t* num_commands, size_t* num_literals) {
716
741
  const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
717
742
  uint32_t* num_matches = BROTLI_ALLOC(m, uint32_t, num_bytes);
718
743
  size_t matches_size = 4 * num_bytes;
@@ -728,6 +753,7 @@ void BrotliCreateHqZopfliBackwardReferences(
728
753
  ZopfliNode* nodes;
729
754
  BackwardMatch* matches = BROTLI_ALLOC(m, BackwardMatch, matches_size);
730
755
  size_t gap = 0;
756
+ size_t shadow_matches = 0;
731
757
  if (BROTLI_IS_OOM(m)) return;
732
758
  for (i = 0; i + HashTypeLengthH10() - 1 < num_bytes; ++i) {
733
759
  const size_t pos = position + i;
@@ -738,14 +764,14 @@ void BrotliCreateHqZopfliBackwardReferences(
738
764
  size_t j;
739
765
  /* Ensure that we have enough free slots. */
740
766
  BROTLI_ENSURE_CAPACITY(m, BackwardMatch, matches, matches_size,
741
- cur_match_pos + MAX_NUM_MATCHES_H10);
767
+ cur_match_pos + MAX_NUM_MATCHES_H10 + shadow_matches);
742
768
  if (BROTLI_IS_OOM(m)) return;
743
- num_found_matches = FindAllMatchesH10(hasher, dictionary, ringbuffer,
744
- ringbuffer_mask, pos, max_length, max_distance, gap, params,
745
- &matches[cur_match_pos]);
769
+ num_found_matches = FindAllMatchesH10(hasher,
770
+ &params->dictionary, ringbuffer, ringbuffer_mask, pos, max_length,
771
+ max_distance, gap, params, &matches[cur_match_pos + shadow_matches]);
746
772
  cur_match_end = cur_match_pos + num_found_matches;
747
773
  for (j = cur_match_pos; j + 1 < cur_match_end; ++j) {
748
- assert(BackwardMatchLength(&matches[j]) <=
774
+ BROTLI_DCHECK(BackwardMatchLength(&matches[j]) <=
749
775
  BackwardMatchLength(&matches[j + 1]));
750
776
  }
751
777
  num_matches[i] = (uint32_t)num_found_matches;
@@ -771,7 +797,7 @@ void BrotliCreateHqZopfliBackwardReferences(
771
797
  orig_num_commands = *num_commands;
772
798
  nodes = BROTLI_ALLOC(m, ZopfliNode, num_bytes + 1);
773
799
  if (BROTLI_IS_OOM(m)) return;
774
- InitZopfliCostModel(m, &model, num_bytes);
800
+ InitZopfliCostModel(m, &model, &params->dist, num_bytes);
775
801
  if (BROTLI_IS_OOM(m)) return;
776
802
  for (i = 0; i < 2; i++) {
777
803
  BrotliInitZopfliNodes(nodes, num_bytes + 1);