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
@@ -10,11 +10,13 @@
10
10
  static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
11
11
  size_t num_bytes, size_t position,
12
12
  const uint8_t* ringbuffer, size_t ringbuffer_mask,
13
- const BrotliEncoderParams* params,
14
- HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
13
+ ContextLut literal_context_lut, const BrotliEncoderParams* params,
14
+ Hasher* hasher, int* dist_cache, size_t* last_insert_len,
15
15
  Command* commands, size_t* num_commands, size_t* num_literals) {
16
+ HASHER()* privat = &hasher->privat.FN(_);
16
17
  /* Set maximum distance, see section 9.1. of the spec. */
17
18
  const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
19
+ const size_t position_offset = params->stream_offset;
18
20
 
19
21
  const Command* const orig_commands = commands;
20
22
  size_t insert_length = *last_insert_len;
@@ -26,24 +28,42 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
26
28
  const size_t random_heuristics_window_size =
27
29
  LiteralSpreeLengthForSparseSearch(params);
28
30
  size_t apply_random_heuristics = position + random_heuristics_window_size;
29
- const size_t gap = 0;
31
+ const size_t gap = params->dictionary.compound.total_size;
30
32
 
31
33
  /* Minimum score to accept a backward reference. */
32
34
  const score_t kMinScore = BROTLI_SCORE_BASE + 100;
33
35
 
34
- FN(PrepareDistanceCache)(hasher, dist_cache);
36
+ FN(PrepareDistanceCache)(privat, dist_cache);
35
37
 
36
38
  while (position + FN(HashTypeLength)() < pos_end) {
37
39
  size_t max_length = pos_end - position;
38
40
  size_t max_distance = BROTLI_MIN(size_t, position, max_backward_limit);
41
+ size_t dictionary_start = BROTLI_MIN(size_t,
42
+ position + position_offset, max_backward_limit);
39
43
  HasherSearchResult sr;
44
+ int dict_id = 0;
45
+ uint8_t p1 = 0;
46
+ uint8_t p2 = 0;
47
+ if (params->dictionary.contextual.context_based) {
48
+ p1 = position >= 1 ?
49
+ ringbuffer[(size_t)(position - 1) & ringbuffer_mask] : 0;
50
+ p2 = position >= 2 ?
51
+ ringbuffer[(size_t)(position - 2) & ringbuffer_mask] : 0;
52
+ dict_id = params->dictionary.contextual.context_map[
53
+ BROTLI_CONTEXT(p1, p2, literal_context_lut)];
54
+ }
40
55
  sr.len = 0;
41
56
  sr.len_code_delta = 0;
42
57
  sr.distance = 0;
43
58
  sr.score = kMinScore;
44
- FN(FindLongestMatch)(hasher, &params->dictionary,
59
+ FN(FindLongestMatch)(privat, params->dictionary.contextual.dict[dict_id],
45
60
  ringbuffer, ringbuffer_mask, dist_cache, position, max_length,
46
- max_distance, gap, params->dist.max_distance, &sr);
61
+ max_distance, dictionary_start + gap, params->dist.max_distance, &sr);
62
+ if (ENABLE_COMPOUND_DICTIONARY) {
63
+ LookupCompoundDictionaryMatch(&params->dictionary.compound, ringbuffer,
64
+ ringbuffer_mask, dist_cache, position, max_length,
65
+ dictionary_start, params->dist.max_distance, &sr);
66
+ }
47
67
  if (sr.score > kMinScore) {
48
68
  /* Found a match. Let's look for something even better ahead. */
49
69
  int delayed_backward_references_in_row = 0;
@@ -57,10 +77,25 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
57
77
  sr2.distance = 0;
58
78
  sr2.score = kMinScore;
59
79
  max_distance = BROTLI_MIN(size_t, position + 1, max_backward_limit);
60
- FN(FindLongestMatch)(hasher,
61
- &params->dictionary,
80
+ dictionary_start = BROTLI_MIN(size_t,
81
+ position + 1 + position_offset, max_backward_limit);
82
+ if (params->dictionary.contextual.context_based) {
83
+ p2 = p1;
84
+ p1 = ringbuffer[position & ringbuffer_mask];
85
+ dict_id = params->dictionary.contextual.context_map[
86
+ BROTLI_CONTEXT(p1, p2, literal_context_lut)];
87
+ }
88
+ FN(FindLongestMatch)(privat,
89
+ params->dictionary.contextual.dict[dict_id],
62
90
  ringbuffer, ringbuffer_mask, dist_cache, position + 1, max_length,
63
- max_distance, gap, params->dist.max_distance, &sr2);
91
+ max_distance, dictionary_start + gap, params->dist.max_distance,
92
+ &sr2);
93
+ if (ENABLE_COMPOUND_DICTIONARY) {
94
+ LookupCompoundDictionaryMatch(
95
+ &params->dictionary.compound, ringbuffer,
96
+ ringbuffer_mask, dist_cache, position + 1, max_length,
97
+ dictionary_start, params->dist.max_distance, &sr2);
98
+ }
64
99
  if (sr2.score >= sr.score + cost_diff_lazy) {
65
100
  /* Ok, let's just write one byte for now and start a match from the
66
101
  next byte. */
@@ -76,18 +111,19 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
76
111
  }
77
112
  apply_random_heuristics =
78
113
  position + 2 * sr.len + random_heuristics_window_size;
79
- max_distance = BROTLI_MIN(size_t, position, max_backward_limit);
114
+ dictionary_start = BROTLI_MIN(size_t,
115
+ position + position_offset, max_backward_limit);
80
116
  {
81
117
  /* The first 16 codes are special short-codes,
82
118
  and the minimum offset is 1. */
83
119
  size_t distance_code = ComputeDistanceCode(
84
- sr.distance, max_distance + gap, dist_cache);
85
- if ((sr.distance <= (max_distance + gap)) && distance_code > 0) {
120
+ sr.distance, dictionary_start + gap, dist_cache);
121
+ if ((sr.distance <= (dictionary_start + gap)) && distance_code > 0) {
86
122
  dist_cache[3] = dist_cache[2];
87
123
  dist_cache[2] = dist_cache[1];
88
124
  dist_cache[1] = dist_cache[0];
89
125
  dist_cache[0] = (int)sr.distance;
90
- FN(PrepareDistanceCache)(hasher, dist_cache);
126
+ FN(PrepareDistanceCache)(privat, dist_cache);
91
127
  }
92
128
  InitCommand(commands++, &params->dist, insert_length,
93
129
  sr.len, sr.len_code_delta, distance_code);
@@ -105,7 +141,7 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
105
141
  range_start = BROTLI_MIN(size_t, range_end, BROTLI_MAX(size_t,
106
142
  range_start, position + sr.len - (sr.distance << 2)));
107
143
  }
108
- FN(StoreRange)(hasher, ringbuffer, ringbuffer_mask, range_start,
144
+ FN(StoreRange)(privat, ringbuffer, ringbuffer_mask, range_start,
109
145
  range_end);
110
146
  }
111
147
  position += sr.len;
@@ -131,7 +167,7 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
131
167
  size_t pos_jump =
132
168
  BROTLI_MIN(size_t, position + 16, pos_end - kMargin);
133
169
  for (; position < pos_jump; position += 4) {
134
- FN(Store)(hasher, ringbuffer, ringbuffer_mask, position);
170
+ FN(Store)(privat, ringbuffer, ringbuffer_mask, position);
135
171
  insert_length += 4;
136
172
  }
137
173
  } else {
@@ -140,7 +176,7 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
140
176
  size_t pos_jump =
141
177
  BROTLI_MIN(size_t, position + 8, pos_end - kMargin);
142
178
  for (; position < pos_jump; position += 2) {
143
- FN(Store)(hasher, ringbuffer, ringbuffer_mask, position);
179
+ FN(Store)(privat, ringbuffer, ringbuffer_mask, position);
144
180
  insert_length += 2;
145
181
  }
146
182
  }
@@ -6,28 +6,29 @@
6
6
 
7
7
  /* Functions to estimate the bit cost of Huffman trees. */
8
8
 
9
- #include "./bit_cost.h"
9
+ #include "bit_cost.h"
10
+
11
+ #include <brotli/types.h>
10
12
 
11
13
  #include "../common/constants.h"
12
14
  #include "../common/platform.h"
13
- #include <brotli/types.h>
14
- #include "./fast_log.h"
15
- #include "./histogram.h"
15
+ #include "fast_log.h"
16
+ #include "histogram.h"
16
17
 
17
18
  #if defined(__cplusplus) || defined(c_plusplus)
18
19
  extern "C" {
19
20
  #endif
20
21
 
21
22
  #define FN(X) X ## Literal
22
- #include "./bit_cost_inc.h" /* NOLINT(build/include) */
23
+ #include "bit_cost_inc.h" /* NOLINT(build/include) */
23
24
  #undef FN
24
25
 
25
26
  #define FN(X) X ## Command
26
- #include "./bit_cost_inc.h" /* NOLINT(build/include) */
27
+ #include "bit_cost_inc.h" /* NOLINT(build/include) */
27
28
  #undef FN
28
29
 
29
30
  #define FN(X) X ## Distance
30
- #include "./bit_cost_inc.h" /* NOLINT(build/include) */
31
+ #include "bit_cost_inc.h" /* NOLINT(build/include) */
31
32
  #undef FN
32
33
 
33
34
  #if defined(__cplusplus) || defined(c_plusplus)
@@ -9,10 +9,11 @@
9
9
  #ifndef BROTLI_ENC_BIT_COST_H_
10
10
  #define BROTLI_ENC_BIT_COST_H_
11
11
 
12
- #include "../common/platform.h"
13
12
  #include <brotli/types.h>
14
- #include "./fast_log.h"
15
- #include "./histogram.h"
13
+
14
+ #include "../common/platform.h"
15
+ #include "fast_log.h"
16
+ #include "histogram.h"
16
17
 
17
18
  #if defined(__cplusplus) || defined(c_plusplus)
18
19
  extern "C" {
@@ -45,7 +46,7 @@ static BROTLI_INLINE double BitsEntropy(
45
46
  const uint32_t* population, size_t size) {
46
47
  size_t sum;
47
48
  double retval = ShannonEntropy(population, size, &sum);
48
- if (retval < sum) {
49
+ if (retval < (double)sum) {
49
50
  /* At least one bit per literal is needed. */
50
51
  retval = (double)sum;
51
52
  }
@@ -6,18 +6,18 @@
6
6
 
7
7
  /* Block split point selection utilities. */
8
8
 
9
- #include "./block_splitter.h"
9
+ #include "block_splitter.h"
10
10
 
11
11
  #include <string.h> /* memcpy, memset */
12
12
 
13
13
  #include "../common/platform.h"
14
- #include "./bit_cost.h"
15
- #include "./cluster.h"
16
- #include "./command.h"
17
- #include "./fast_log.h"
18
- #include "./histogram.h"
19
- #include "./memory.h"
20
- #include "./quality.h"
14
+ #include "bit_cost.h"
15
+ #include "cluster.h"
16
+ #include "command.h"
17
+ #include "fast_log.h"
18
+ #include "histogram.h"
19
+ #include "memory.h"
20
+ #include "quality.h"
21
21
 
22
22
  #if defined(__cplusplus) || defined(c_plusplus)
23
23
  extern "C" {
@@ -30,6 +30,7 @@ static const double kCommandBlockSwitchCost = 13.5;
30
30
  static const double kDistanceBlockSwitchCost = 14.6;
31
31
  static const size_t kLiteralStrideLength = 70;
32
32
  static const size_t kCommandStrideLength = 40;
33
+ static const size_t kDistanceStrideLength = 40;
33
34
  static const size_t kSymbolsPerLiteralHistogram = 544;
34
35
  static const size_t kSymbolsPerCommandHistogram = 530;
35
36
  static const size_t kSymbolsPerDistanceHistogram = 544;
@@ -89,19 +90,19 @@ static BROTLI_INLINE double BitCost(size_t count) {
89
90
  #define FN(X) X ## Literal
90
91
  #define DataType uint8_t
91
92
  /* NOLINTNEXTLINE(build/include) */
92
- #include "./block_splitter_inc.h"
93
+ #include "block_splitter_inc.h"
93
94
  #undef DataType
94
95
  #undef FN
95
96
 
96
97
  #define FN(X) X ## Command
97
98
  #define DataType uint16_t
98
99
  /* NOLINTNEXTLINE(build/include) */
99
- #include "./block_splitter_inc.h"
100
+ #include "block_splitter_inc.h"
100
101
  #undef FN
101
102
 
102
103
  #define FN(X) X ## Distance
103
104
  /* NOLINTNEXTLINE(build/include) */
104
- #include "./block_splitter_inc.h"
105
+ #include "block_splitter_inc.h"
105
106
  #undef DataType
106
107
  #undef FN
107
108
 
@@ -119,6 +120,8 @@ void BrotliDestroyBlockSplit(MemoryManager* m, BlockSplit* self) {
119
120
  BROTLI_FREE(m, self->lengths);
120
121
  }
121
122
 
123
+ /* Extracts literals, command distance and prefix codes, then applies
124
+ * SplitByteVector to create partitioning. */
122
125
  void BrotliSplitBlock(MemoryManager* m,
123
126
  const Command* cmds,
124
127
  const size_t num_commands,
@@ -132,11 +135,13 @@ void BrotliSplitBlock(MemoryManager* m,
132
135
  {
133
136
  size_t literals_count = CountLiterals(cmds, num_commands);
134
137
  uint8_t* literals = BROTLI_ALLOC(m, uint8_t, literals_count);
135
- if (BROTLI_IS_OOM(m)) return;
138
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(literals)) return;
136
139
  /* Create a continuous array of literals. */
137
140
  CopyLiteralsToByteArray(cmds, num_commands, data, pos, mask, literals);
138
141
  /* Create the block split on the array of literals.
139
- Literal histograms have alphabet size 256. */
142
+ * Literal histograms can have alphabet size up to 256.
143
+ * Though, to accomodate context modeling, less than half of maximum size
144
+ * is allowed. */
140
145
  SplitByteVectorLiteral(
141
146
  m, literals, literals_count,
142
147
  kSymbolsPerLiteralHistogram, kMaxLiteralHistograms,
@@ -144,13 +149,17 @@ void BrotliSplitBlock(MemoryManager* m,
144
149
  literal_split);
145
150
  if (BROTLI_IS_OOM(m)) return;
146
151
  BROTLI_FREE(m, literals);
152
+ /* NB: this might be a good place for injecting extra splitting without
153
+ * increasing encoder complexity; however, output parition would be less
154
+ * optimal than one produced with forced splitting inside
155
+ * SplitByteVector (FindBlocks / ClusterBlocks). */
147
156
  }
148
157
 
149
158
  {
150
159
  /* Compute prefix codes for commands. */
151
160
  uint16_t* insert_and_copy_codes = BROTLI_ALLOC(m, uint16_t, num_commands);
152
161
  size_t i;
153
- if (BROTLI_IS_OOM(m)) return;
162
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(insert_and_copy_codes)) return;
154
163
  for (i = 0; i < num_commands; ++i) {
155
164
  insert_and_copy_codes[i] = cmds[i].cmd_prefix_;
156
165
  }
@@ -161,7 +170,7 @@ void BrotliSplitBlock(MemoryManager* m,
161
170
  kCommandStrideLength, kCommandBlockSwitchCost, params,
162
171
  insert_and_copy_split);
163
172
  if (BROTLI_IS_OOM(m)) return;
164
- /* TODO: reuse for distances? */
173
+ /* TODO(eustas): reuse for distances? */
165
174
  BROTLI_FREE(m, insert_and_copy_codes);
166
175
  }
167
176
 
@@ -170,7 +179,7 @@ void BrotliSplitBlock(MemoryManager* m,
170
179
  uint16_t* distance_prefixes = BROTLI_ALLOC(m, uint16_t, num_commands);
171
180
  size_t j = 0;
172
181
  size_t i;
173
- if (BROTLI_IS_OOM(m)) return;
182
+ if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(distance_prefixes)) return;
174
183
  for (i = 0; i < num_commands; ++i) {
175
184
  const Command* cmd = &cmds[i];
176
185
  if (CommandCopyLen(cmd) && cmd->cmd_prefix_ >= 128) {
@@ -181,13 +190,27 @@ void BrotliSplitBlock(MemoryManager* m,
181
190
  SplitByteVectorDistance(
182
191
  m, distance_prefixes, j,
183
192
  kSymbolsPerDistanceHistogram, kMaxCommandHistograms,
184
- kCommandStrideLength, kDistanceBlockSwitchCost, params,
193
+ kDistanceStrideLength, kDistanceBlockSwitchCost, params,
185
194
  dist_split);
186
195
  if (BROTLI_IS_OOM(m)) return;
187
196
  BROTLI_FREE(m, distance_prefixes);
188
197
  }
189
198
  }
190
199
 
200
+ #if defined(BROTLI_TEST)
201
+ size_t CountLiteralsForTest(const Command*, const size_t);
202
+ size_t CountLiteralsForTest(const Command* cmds, const size_t num_commands) {
203
+ return CountLiterals(cmds, num_commands);
204
+ }
205
+
206
+ void CopyLiteralsToByteArrayForTest(const Command*,
207
+ const size_t, const uint8_t*, const size_t, const size_t, uint8_t*);
208
+ void CopyLiteralsToByteArrayForTest(const Command* cmds,
209
+ const size_t num_commands, const uint8_t* data, const size_t offset,
210
+ const size_t mask, uint8_t* literals) {
211
+ CopyLiteralsToByteArray(cmds, num_commands, data, offset, mask, literals);
212
+ }
213
+ #endif
191
214
 
192
215
  #if defined(__cplusplus) || defined(c_plusplus)
193
216
  } /* extern "C" */
@@ -9,11 +9,12 @@
9
9
  #ifndef BROTLI_ENC_BLOCK_SPLITTER_H_
10
10
  #define BROTLI_ENC_BLOCK_SPLITTER_H_
11
11
 
12
- #include "../common/platform.h"
13
12
  #include <brotli/types.h>
14
- #include "./command.h"
15
- #include "./memory.h"
16
- #include "./quality.h"
13
+
14
+ #include "../common/platform.h"
15
+ #include "command.h"
16
+ #include "memory.h"
17
+ #include "quality.h"
17
18
 
18
19
  #if defined(__cplusplus) || defined(c_plusplus)
19
20
  extern "C" {