brotli 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -16,13 +16,13 @@
16
16
  #ifndef BROTLI_ENC_BROTLI_BIT_STREAM_H_
17
17
  #define BROTLI_ENC_BROTLI_BIT_STREAM_H_
18
18
 
19
+ #include "../common/context.h"
20
+ #include "../common/platform.h"
19
21
  #include <brotli/types.h>
20
22
  #include "./command.h"
21
- #include "./context.h"
22
23
  #include "./entropy_encode.h"
23
24
  #include "./memory.h"
24
25
  #include "./metablock.h"
25
- #include "./port.h"
26
26
 
27
27
  #if defined(__cplusplus) || defined(c_plusplus)
28
28
  extern "C" {
@@ -32,7 +32,7 @@ extern "C" {
32
32
  position for the current storage. */
33
33
 
34
34
  BROTLI_INTERNAL void BrotliStoreHuffmanTree(const uint8_t* depths, size_t num,
35
- HuffmanTree* tree, size_t *storage_ix, uint8_t *storage);
35
+ HuffmanTree* tree, size_t* storage_ix, uint8_t* storage);
36
36
 
37
37
  BROTLI_INTERNAL void BrotliBuildAndStoreHuffmanTreeFast(
38
38
  MemoryManager* m, const uint32_t* histogram, const size_t histogram_total,
@@ -42,59 +42,40 @@ BROTLI_INTERNAL void BrotliBuildAndStoreHuffmanTreeFast(
42
42
  /* REQUIRES: length > 0 */
43
43
  /* REQUIRES: length <= (1 << 24) */
44
44
  BROTLI_INTERNAL void BrotliStoreMetaBlock(MemoryManager* m,
45
- const uint8_t* input,
46
- size_t start_pos,
47
- size_t length,
48
- size_t mask,
49
- uint8_t prev_byte,
50
- uint8_t prev_byte2,
51
- BROTLI_BOOL is_final_block,
52
- uint32_t num_direct_distance_codes,
53
- uint32_t distance_postfix_bits,
54
- ContextType literal_context_mode,
55
- const Command* commands,
56
- size_t n_commands,
57
- const MetaBlockSplit* mb,
58
- size_t* storage_ix,
59
- uint8_t* storage);
45
+ const uint8_t* input, size_t start_pos, size_t length, size_t mask,
46
+ uint8_t prev_byte, uint8_t prev_byte2, BROTLI_BOOL is_last,
47
+ const BrotliEncoderParams* params, ContextType literal_context_mode,
48
+ const Command* commands, size_t n_commands, const MetaBlockSplit* mb,
49
+ size_t* storage_ix, uint8_t* storage);
60
50
 
61
51
  /* Stores the meta-block without doing any block splitting, just collects
62
52
  one histogram per block category and uses that for entropy coding.
63
53
  REQUIRES: length > 0
64
54
  REQUIRES: length <= (1 << 24) */
65
55
  BROTLI_INTERNAL void BrotliStoreMetaBlockTrivial(MemoryManager* m,
66
- const uint8_t* input,
67
- size_t start_pos,
68
- size_t length,
69
- size_t mask,
70
- BROTLI_BOOL is_last,
71
- const Command *commands,
72
- size_t n_commands,
73
- size_t* storage_ix,
74
- uint8_t* storage);
56
+ const uint8_t* input, size_t start_pos, size_t length, size_t mask,
57
+ BROTLI_BOOL is_last, const BrotliEncoderParams* params,
58
+ const Command* commands, size_t n_commands,
59
+ size_t* storage_ix, uint8_t* storage);
75
60
 
76
61
  /* Same as above, but uses static prefix codes for histograms with a only a few
77
62
  symbols, and uses static code length prefix codes for all other histograms.
78
63
  REQUIRES: length > 0
79
64
  REQUIRES: length <= (1 << 24) */
80
65
  BROTLI_INTERNAL void BrotliStoreMetaBlockFast(MemoryManager* m,
81
- const uint8_t* input,
82
- size_t start_pos,
83
- size_t length,
84
- size_t mask,
85
- BROTLI_BOOL is_last,
86
- const Command *commands,
87
- size_t n_commands,
88
- size_t* storage_ix,
89
- uint8_t* storage);
66
+ const uint8_t* input, size_t start_pos, size_t length, size_t mask,
67
+ BROTLI_BOOL is_last, const BrotliEncoderParams* params,
68
+ const Command* commands, size_t n_commands,
69
+ size_t* storage_ix, uint8_t* storage);
90
70
 
91
71
  /* This is for storing uncompressed blocks (simple raw storage of
92
72
  bytes-as-bytes).
93
73
  REQUIRES: length > 0
94
74
  REQUIRES: length <= (1 << 24) */
95
75
  BROTLI_INTERNAL void BrotliStoreUncompressedMetaBlock(
96
- BROTLI_BOOL is_final_block, const uint8_t* input, size_t position,
97
- size_t mask, size_t len, size_t* storage_ix, uint8_t* storage);
76
+ BROTLI_BOOL is_final_block, const uint8_t* BROTLI_RESTRICT input,
77
+ size_t position, size_t mask, size_t len,
78
+ size_t* BROTLI_RESTRICT storage_ix, uint8_t* BROTLI_RESTRICT storage);
98
79
 
99
80
  #if defined(__cplusplus) || defined(c_plusplus)
100
81
  } /* extern "C" */
@@ -8,12 +8,12 @@
8
8
 
9
9
  #include "./cluster.h"
10
10
 
11
+ #include "../common/platform.h"
11
12
  #include <brotli/types.h>
12
13
  #include "./bit_cost.h" /* BrotliPopulationCost */
13
14
  #include "./fast_log.h"
14
15
  #include "./histogram.h"
15
16
  #include "./memory.h"
16
- #include "./port.h"
17
17
 
18
18
  #if defined(__cplusplus) || defined(c_plusplus)
19
19
  extern "C" {
@@ -9,10 +9,10 @@
9
9
  #ifndef BROTLI_ENC_CLUSTER_H_
10
10
  #define BROTLI_ENC_CLUSTER_H_
11
11
 
12
+ #include "../common/platform.h"
12
13
  #include <brotli/types.h>
13
14
  #include "./histogram.h"
14
15
  #include "./memory.h"
15
- #include "./port.h"
16
16
 
17
17
  #if defined(__cplusplus) || defined(c_plusplus)
18
18
  extern "C" {
@@ -10,9 +10,10 @@
10
10
  #define BROTLI_ENC_COMMAND_H_
11
11
 
12
12
  #include "../common/constants.h"
13
- #include <brotli/port.h>
13
+ #include "../common/platform.h"
14
14
  #include <brotli/types.h>
15
15
  #include "./fast_log.h"
16
+ #include "./params.h"
16
17
  #include "./prefix.h"
17
18
 
18
19
  #if defined(__cplusplus) || defined(c_plusplus)
@@ -61,21 +62,21 @@ static BROTLI_INLINE uint16_t GetCopyLengthCode(size_t copylen) {
61
62
  static BROTLI_INLINE uint16_t CombineLengthCodes(
62
63
  uint16_t inscode, uint16_t copycode, BROTLI_BOOL use_last_distance) {
63
64
  uint16_t bits64 =
64
- (uint16_t)((copycode & 0x7u) | ((inscode & 0x7u) << 3));
65
- if (use_last_distance && inscode < 8 && copycode < 16) {
66
- return (copycode < 8) ? bits64 : (bits64 | 64);
65
+ (uint16_t)((copycode & 0x7u) | ((inscode & 0x7u) << 3u));
66
+ if (use_last_distance && inscode < 8u && copycode < 16u) {
67
+ return (copycode < 8u) ? bits64 : (bits64 | 64u);
67
68
  } else {
68
69
  /* Specification: 5 Encoding of ... (last table) */
69
70
  /* offset = 2 * index, where index is in range [0..8] */
70
- int offset = 2 * ((copycode >> 3) + 3 * (inscode >> 3));
71
+ uint32_t offset = 2u * ((copycode >> 3u) + 3u * (inscode >> 3u));
71
72
  /* All values in specification are K * 64,
72
73
  where K = [2, 3, 6, 4, 5, 8, 7, 9, 10],
73
74
  i + 1 = [1, 2, 3, 4, 5, 6, 7, 8, 9],
74
75
  K - i - 1 = [1, 1, 3, 0, 0, 2, 0, 1, 2] = D.
75
76
  All values in D require only 2 bits to encode.
76
77
  Magic constant is shifted 6 bits left, to avoid final multiplication. */
77
- offset = (offset << 5) + 0x40 + ((0x520D40 >> offset) & 0xC0);
78
- return (uint16_t)offset | bits64;
78
+ offset = (offset << 5u) + 0x40u + ((0x520D40u >> offset) & 0xC0u);
79
+ return (uint16_t)(offset | bits64);
79
80
  }
80
81
  }
81
82
 
@@ -105,53 +106,61 @@ static BROTLI_INLINE uint32_t GetCopyExtra(uint16_t copycode) {
105
106
 
106
107
  typedef struct Command {
107
108
  uint32_t insert_len_;
108
- /* Stores copy_len in low 24 bits and copy_len XOR copy_code in high 8 bit. */
109
+ /* Stores copy_len in low 25 bits and copy_code - copy_len in high 7 bit. */
109
110
  uint32_t copy_len_;
111
+ /* Stores distance extra bits. */
110
112
  uint32_t dist_extra_;
111
113
  uint16_t cmd_prefix_;
114
+ /* Stores distance code in low 10 bits
115
+ and number of extra bits in high 6 bits. */
112
116
  uint16_t dist_prefix_;
113
117
  } Command;
114
118
 
115
119
  /* distance_code is e.g. 0 for same-as-last short code, or 16 for offset 1. */
116
- static BROTLI_INLINE void InitCommand(Command* self, size_t insertlen,
120
+ static BROTLI_INLINE void InitCommand(Command* self,
121
+ const BrotliDistanceParams* dist, size_t insertlen,
117
122
  size_t copylen, int copylen_code_delta, size_t distance_code) {
118
123
  /* Don't rely on signed int representation, use honest casts. */
119
124
  uint32_t delta = (uint8_t)((int8_t)copylen_code_delta);
120
125
  self->insert_len_ = (uint32_t)insertlen;
121
- self->copy_len_ = (uint32_t)(copylen | (delta << 24));
126
+ self->copy_len_ = (uint32_t)(copylen | (delta << 25));
122
127
  /* The distance prefix and extra bits are stored in this Command as if
123
128
  npostfix and ndirect were 0, they are only recomputed later after the
124
129
  clustering if needed. */
125
130
  PrefixEncodeCopyDistance(
126
- distance_code, 0, 0, &self->dist_prefix_, &self->dist_extra_);
131
+ distance_code, dist->num_direct_distance_codes,
132
+ dist->distance_postfix_bits, &self->dist_prefix_, &self->dist_extra_);
127
133
  GetLengthCode(
128
134
  insertlen, (size_t)((int)copylen + copylen_code_delta),
129
- TO_BROTLI_BOOL(self->dist_prefix_ == 0), &self->cmd_prefix_);
135
+ TO_BROTLI_BOOL((self->dist_prefix_ & 0x3FF) == 0), &self->cmd_prefix_);
130
136
  }
131
137
 
132
138
  static BROTLI_INLINE void InitInsertCommand(Command* self, size_t insertlen) {
133
139
  self->insert_len_ = (uint32_t)insertlen;
134
- self->copy_len_ = 4 << 24;
140
+ self->copy_len_ = 4 << 25;
135
141
  self->dist_extra_ = 0;
136
142
  self->dist_prefix_ = BROTLI_NUM_DISTANCE_SHORT_CODES;
137
143
  GetLengthCode(insertlen, 4, BROTLI_FALSE, &self->cmd_prefix_);
138
144
  }
139
145
 
140
- static BROTLI_INLINE uint32_t CommandRestoreDistanceCode(const Command* self) {
141
- if (self->dist_prefix_ < BROTLI_NUM_DISTANCE_SHORT_CODES) {
142
- return self->dist_prefix_;
146
+ static BROTLI_INLINE uint32_t CommandRestoreDistanceCode(
147
+ const Command* self, const BrotliDistanceParams* dist) {
148
+ if ((self->dist_prefix_ & 0x3FFu) <
149
+ BROTLI_NUM_DISTANCE_SHORT_CODES + dist->num_direct_distance_codes) {
150
+ return self->dist_prefix_ & 0x3FFu;
143
151
  } else {
144
- uint32_t nbits = self->dist_extra_ >> 24;
145
- uint32_t extra = self->dist_extra_ & 0xffffff;
146
- /* It is assumed that the distance was first encoded with NPOSTFIX = 0 and
147
- NDIRECT = 0, so the code itself is of this form:
148
- BROTLI_NUM_DISTANCE_SHORT_CODES + 2 * (nbits - 1) + prefix_bit
149
- Therefore, the following expression results in (2 + prefix_bit). */
150
- uint32_t prefix =
151
- self->dist_prefix_ + 4u - BROTLI_NUM_DISTANCE_SHORT_CODES - 2u * nbits;
152
- /* Subtract 4 for offset (Chapter 4.) and
153
- increase by BROTLI_NUM_DISTANCE_SHORT_CODES - 1 */
154
- return (prefix << nbits) + extra + BROTLI_NUM_DISTANCE_SHORT_CODES - 4u;
152
+ uint32_t dcode = self->dist_prefix_ & 0x3FFu;
153
+ uint32_t nbits = self->dist_prefix_ >> 10;
154
+ uint32_t extra = self->dist_extra_;
155
+ uint32_t postfix_mask = (1U << dist->distance_postfix_bits) - 1U;
156
+ uint32_t hcode = (dcode - dist->num_direct_distance_codes -
157
+ BROTLI_NUM_DISTANCE_SHORT_CODES) >>
158
+ dist->distance_postfix_bits;
159
+ uint32_t lcode = (dcode - dist->num_direct_distance_codes -
160
+ BROTLI_NUM_DISTANCE_SHORT_CODES) & postfix_mask;
161
+ uint32_t offset = ((2U + (hcode & 1U)) << nbits) - 4U;
162
+ return ((offset + extra) << dist->distance_postfix_bits) + lcode +
163
+ dist->num_direct_distance_codes + BROTLI_NUM_DISTANCE_SHORT_CODES;
155
164
  }
156
165
  }
157
166
 
@@ -165,12 +174,13 @@ static BROTLI_INLINE uint32_t CommandDistanceContext(const Command* self) {
165
174
  }
166
175
 
167
176
  static BROTLI_INLINE uint32_t CommandCopyLen(const Command* self) {
168
- return self->copy_len_ & 0xFFFFFF;
177
+ return self->copy_len_ & 0x1FFFFFF;
169
178
  }
170
179
 
171
180
  static BROTLI_INLINE uint32_t CommandCopyLenCode(const Command* self) {
172
- int32_t delta = (int8_t)((uint8_t)(self->copy_len_ >> 24));
173
- return (uint32_t)((int32_t)(self->copy_len_ & 0xFFFFFF) + delta);
181
+ uint32_t modifier = self->copy_len_ >> 25;
182
+ int32_t delta = (int8_t)((uint8_t)(modifier | ((modifier & 0x40) << 1)));
183
+ return (uint32_t)((int32_t)(self->copy_len_ & 0x1FFFFFF) + delta);
174
184
  }
175
185
 
176
186
  #if defined(__cplusplus) || defined(c_plusplus)
@@ -17,16 +17,15 @@
17
17
  #include <string.h> /* memcmp, memcpy, memset */
18
18
 
19
19
  #include "../common/constants.h"
20
+ #include "../common/platform.h"
20
21
  #include <brotli/types.h>
21
22
  #include "./brotli_bit_stream.h"
22
23
  #include "./entropy_encode.h"
23
24
  #include "./fast_log.h"
24
25
  #include "./find_match_length.h"
25
26
  #include "./memory.h"
26
- #include "./port.h"
27
27
  #include "./write_bits.h"
28
28
 
29
-
30
29
  #if defined(__cplusplus) || defined(c_plusplus)
31
30
  extern "C" {
32
31
  #endif
@@ -39,7 +38,7 @@ extern "C" {
39
38
  * There is no effort to ensure that it is a prime, the oddity is enough
40
39
  for this use.
41
40
  * The number has been tuned heuristically against compression benchmarks. */
42
- static const uint32_t kHashMul32 = 0x1e35a7bd;
41
+ static const uint32_t kHashMul32 = 0x1E35A7BD;
43
42
 
44
43
  static BROTLI_INLINE uint32_t Hash(const uint8_t* p, size_t shift) {
45
44
  const uint64_t h = (BROTLI_UNALIGNED_LOAD64LE(p) << 24) * kHashMul32;
@@ -48,8 +47,8 @@ static BROTLI_INLINE uint32_t Hash(const uint8_t* p, size_t shift) {
48
47
 
49
48
  static BROTLI_INLINE uint32_t HashBytesAtOffset(
50
49
  uint64_t v, int offset, size_t shift) {
51
- assert(offset >= 0);
52
- assert(offset <= 3);
50
+ BROTLI_DCHECK(offset >= 0);
51
+ BROTLI_DCHECK(offset <= 3);
53
52
  {
54
53
  const uint64_t h = ((v >> (8 * offset)) << 24) * kHashMul32;
55
54
  return (uint32_t)(h >> shift);
@@ -58,7 +57,7 @@ static BROTLI_INLINE uint32_t HashBytesAtOffset(
58
57
 
59
58
  static BROTLI_INLINE BROTLI_BOOL IsMatch(const uint8_t* p1, const uint8_t* p2) {
60
59
  return TO_BROTLI_BOOL(
61
- BROTLI_UNALIGNED_LOAD32(p1) == BROTLI_UNALIGNED_LOAD32(p2) &&
60
+ BrotliUnalignedRead32(p1) == BrotliUnalignedRead32(p2) &&
62
61
  p1[4] == p2[4]);
63
62
  }
64
63
 
@@ -203,7 +202,7 @@ static BROTLI_INLINE void EmitInsertLen(size_t insertlen,
203
202
  } else {
204
203
  BrotliWriteBits(depth[61], bits[61], storage_ix, storage);
205
204
  BrotliWriteBits(12, insertlen - 2114, storage_ix, storage);
206
- ++histo[21];
205
+ ++histo[61];
207
206
  }
208
207
  }
209
208
 
@@ -216,11 +215,11 @@ static BROTLI_INLINE void EmitLongInsertLen(size_t insertlen,
216
215
  if (insertlen < 22594) {
217
216
  BrotliWriteBits(depth[62], bits[62], storage_ix, storage);
218
217
  BrotliWriteBits(14, insertlen - 6210, storage_ix, storage);
219
- ++histo[22];
218
+ ++histo[62];
220
219
  } else {
221
220
  BrotliWriteBits(depth[63], bits[63], storage_ix, storage);
222
221
  BrotliWriteBits(24, insertlen - 22594, storage_ix, storage);
223
- ++histo[23];
222
+ ++histo[63];
224
223
  }
225
224
  }
226
225
 
@@ -252,7 +251,7 @@ static BROTLI_INLINE void EmitCopyLen(size_t copylen,
252
251
  } else {
253
252
  BrotliWriteBits(depth[39], bits[39], storage_ix, storage);
254
253
  BrotliWriteBits(24, copylen - 2118, storage_ix, storage);
255
- ++histo[47];
254
+ ++histo[39];
256
255
  }
257
256
  }
258
257
 
@@ -294,7 +293,7 @@ static BROTLI_INLINE void EmitCopyLenLastDistance(size_t copylen,
294
293
  BrotliWriteBits(depth[39], bits[39], storage_ix, storage);
295
294
  BrotliWriteBits(24, copylen - 2120, storage_ix, storage);
296
295
  BrotliWriteBits(depth[64], bits[64], storage_ix, storage);
297
- ++histo[47];
296
+ ++histo[39];
298
297
  ++histo[64];
299
298
  }
300
299
  }
@@ -344,7 +343,7 @@ static void BrotliStoreMetaBlockHeader(
344
343
  }
345
344
 
346
345
  static void UpdateBits(size_t n_bits, uint32_t bits, size_t pos,
347
- uint8_t *array) {
346
+ uint8_t* array) {
348
347
  while (n_bits > 0) {
349
348
  size_t byte_pos = pos >> 3;
350
349
  size_t n_unchanged_bits = pos & 7;
@@ -522,12 +521,12 @@ static BROTLI_INLINE void BrotliCompressFragmentFastImpl(
522
521
 
523
522
  const uint8_t* next_ip = ip;
524
523
  const uint8_t* candidate;
525
- assert(next_emit < ip);
524
+ BROTLI_DCHECK(next_emit < ip);
526
525
  trawl:
527
526
  do {
528
527
  uint32_t hash = next_hash;
529
528
  uint32_t bytes_between_hash_lookups = skip++ >> 5;
530
- assert(hash == Hash(next_ip, shift));
529
+ BROTLI_DCHECK(hash == Hash(next_ip, shift));
531
530
  ip = next_ip;
532
531
  next_ip = ip + bytes_between_hash_lookups;
533
532
  if (BROTLI_PREDICT_FALSE(next_ip > ip_limit)) {
@@ -542,8 +541,8 @@ trawl:
542
541
  }
543
542
  }
544
543
  candidate = base_ip + table[hash];
545
- assert(candidate >= base_ip);
546
- assert(candidate < ip);
544
+ BROTLI_DCHECK(candidate >= base_ip);
545
+ BROTLI_DCHECK(candidate < ip);
547
546
 
548
547
  table[hash] = (int)(ip - base_ip);
549
548
  } while (BROTLI_PREDICT_TRUE(!IsMatch(ip, candidate)));
@@ -566,7 +565,7 @@ trawl:
566
565
  int distance = (int)(base - candidate); /* > 0 */
567
566
  size_t insert = (size_t)(base - next_emit);
568
567
  ip += matched;
569
- assert(0 == memcmp(base, candidate, matched));
568
+ BROTLI_DCHECK(0 == memcmp(base, candidate, matched));
570
569
  if (BROTLI_PREDICT_TRUE(insert < 6210)) {
571
570
  EmitInsertLen(insert, cmd_depth, cmd_bits, cmd_histo,
572
571
  storage_ix, storage);
@@ -626,7 +625,7 @@ trawl:
626
625
  if (ip - candidate > MAX_DISTANCE) break;
627
626
  ip += matched;
628
627
  last_distance = (int)(base - candidate); /* > 0 */
629
- assert(0 == memcmp(base, candidate, matched));
628
+ BROTLI_DCHECK(0 == memcmp(base, candidate, matched));
630
629
  EmitCopyLen(matched, cmd_depth, cmd_bits, cmd_histo,
631
630
  storage_ix, storage);
632
631
  EmitDistance((size_t)last_distance, cmd_depth, cmd_bits,
@@ -659,7 +658,7 @@ trawl:
659
658
  }
660
659
 
661
660
  emit_remainder:
662
- assert(next_emit <= ip_end);
661
+ BROTLI_DCHECK(next_emit <= ip_end);
663
662
  input += block_size;
664
663
  input_size -= block_size;
665
664
  block_size = BROTLI_MIN(size_t, input_size, kMergeBlockSize);
@@ -669,7 +668,7 @@ trawl:
669
668
  if (input_size > 0 &&
670
669
  total_block_size + block_size <= (1 << 20) &&
671
670
  ShouldMergeBlock(input, block_size, lit_depth)) {
672
- assert(total_block_size > (1 << 16));
671
+ BROTLI_DCHECK(total_block_size > (1 << 16));
673
672
  /* Update the size of the current meta-block and continue emitting commands.
674
673
  We can do this because the current size and the new size both have 5
675
674
  nibbles. */
@@ -752,7 +751,7 @@ void BrotliCompressFragmentFast(
752
751
  const size_t table_bits = Log2FloorNonZero(table_size);
753
752
 
754
753
  if (input_size == 0) {
755
- assert(is_last);
754
+ BROTLI_DCHECK(is_last);
756
755
  BrotliWriteBits(1, 1, storage_ix, storage); /* islast */
757
756
  BrotliWriteBits(1, 1, storage_ix, storage); /* isempty */
758
757
  *storage_ix = (*storage_ix + 7u) & ~7u;
@@ -768,7 +767,7 @@ void BrotliCompressFragmentFast(
768
767
  break;
769
768
  FOR_TABLE_BITS_(CASE_)
770
769
  #undef CASE_
771
- default: assert(0); break;
770
+ default: BROTLI_DCHECK(0); break;
772
771
  }
773
772
 
774
773
  /* If output is larger than single uncompressed block, rewrite it. */
@@ -12,9 +12,9 @@
12
12
  #ifndef BROTLI_ENC_COMPRESS_FRAGMENT_H_
13
13
  #define BROTLI_ENC_COMPRESS_FRAGMENT_H_
14
14
 
15
+ #include "../common/platform.h"
15
16
  #include <brotli/types.h>
16
17
  #include "./memory.h"
17
- #include "./port.h"
18
18
 
19
19
  #if defined(__cplusplus) || defined(c_plusplus)
20
20
  extern "C" {
@@ -15,6 +15,7 @@
15
15
  #include <string.h> /* memcmp, memcpy, memset */
16
16
 
17
17
  #include "../common/constants.h"
18
+ #include "../common/platform.h"
18
19
  #include <brotli/types.h>
19
20
  #include "./bit_cost.h"
20
21
  #include "./brotli_bit_stream.h"
@@ -22,10 +23,8 @@
22
23
  #include "./fast_log.h"
23
24
  #include "./find_match_length.h"
24
25
  #include "./memory.h"
25
- #include "./port.h"
26
26
  #include "./write_bits.h"
27
27
 
28
-
29
28
  #if defined(__cplusplus) || defined(c_plusplus)
30
29
  extern "C" {
31
30
  #endif
@@ -38,28 +37,31 @@ extern "C" {
38
37
  * There is no effort to ensure that it is a prime, the oddity is enough
39
38
  for this use.
40
39
  * The number has been tuned heuristically against compression benchmarks. */
41
- static const uint32_t kHashMul32 = 0x1e35a7bd;
40
+ static const uint32_t kHashMul32 = 0x1E35A7BD;
42
41
 
43
- static BROTLI_INLINE uint32_t Hash(const uint8_t* p, size_t shift) {
44
- const uint64_t h = (BROTLI_UNALIGNED_LOAD64LE(p) << 16) * kHashMul32;
42
+ static BROTLI_INLINE uint32_t Hash(const uint8_t* p,
43
+ size_t shift, size_t length) {
44
+ const uint64_t h =
45
+ (BROTLI_UNALIGNED_LOAD64LE(p) << ((8 - length) * 8)) * kHashMul32;
45
46
  return (uint32_t)(h >> shift);
46
47
  }
47
48
 
48
- static BROTLI_INLINE uint32_t HashBytesAtOffset(
49
- uint64_t v, int offset, size_t shift) {
50
- assert(offset >= 0);
51
- assert(offset <= 2);
49
+ static BROTLI_INLINE uint32_t HashBytesAtOffset(uint64_t v, size_t offset,
50
+ size_t shift, size_t length) {
51
+ BROTLI_DCHECK(offset <= 8 - length);
52
52
  {
53
- const uint64_t h = ((v >> (8 * offset)) << 16) * kHashMul32;
53
+ const uint64_t h = ((v >> (8 * offset)) << ((8 - length) * 8)) * kHashMul32;
54
54
  return (uint32_t)(h >> shift);
55
55
  }
56
56
  }
57
57
 
58
- static BROTLI_INLINE BROTLI_BOOL IsMatch(const uint8_t* p1, const uint8_t* p2) {
59
- return TO_BROTLI_BOOL(
60
- BROTLI_UNALIGNED_LOAD32(p1) == BROTLI_UNALIGNED_LOAD32(p2) &&
61
- p1[4] == p2[4] &&
62
- p1[5] == p2[5]);
58
+ static BROTLI_INLINE BROTLI_BOOL IsMatch(const uint8_t* p1, const uint8_t* p2,
59
+ size_t length) {
60
+ if (BrotliUnalignedRead32(p1) == BrotliUnalignedRead32(p2)) {
61
+ if (length == 4) return BROTLI_TRUE;
62
+ return TO_BROTLI_BOOL(p1[4] == p2[4] && p1[5] == p2[5]);
63
+ }
64
+ return BROTLI_FALSE;
63
65
  }
64
66
 
65
67
  /* Builds a command and distance prefix code (each 64 symbols) into "depth" and
@@ -236,7 +238,8 @@ static void BrotliStoreMetaBlockHeader(
236
238
 
237
239
  static BROTLI_INLINE void CreateCommands(const uint8_t* input,
238
240
  size_t block_size, size_t input_size, const uint8_t* base_ip, int* table,
239
- size_t table_bits, uint8_t** literals, uint32_t** commands) {
241
+ size_t table_bits, size_t min_match,
242
+ uint8_t** literals, uint32_t** commands) {
240
243
  /* "ip" is the input pointer. */
241
244
  const uint8_t* ip = input;
242
245
  const size_t shift = 64u - table_bits;
@@ -248,19 +251,18 @@ static BROTLI_INLINE void CreateCommands(const uint8_t* input,
248
251
 
249
252
  int last_distance = -1;
250
253
  const size_t kInputMarginBytes = BROTLI_WINDOW_GAP;
251
- const size_t kMinMatchLen = 6;
252
254
 
253
255
  if (BROTLI_PREDICT_TRUE(block_size >= kInputMarginBytes)) {
254
256
  /* For the last block, we need to keep a 16 bytes margin so that we can be
255
257
  sure that all distances are at most window size - 16.
256
258
  For all other blocks, we only need to keep a margin of 5 bytes so that
257
259
  we don't go over the block size with a copy. */
258
- const size_t len_limit = BROTLI_MIN(size_t, block_size - kMinMatchLen,
260
+ const size_t len_limit = BROTLI_MIN(size_t, block_size - min_match,
259
261
  input_size - kInputMarginBytes);
260
262
  const uint8_t* ip_limit = input + len_limit;
261
263
 
262
264
  uint32_t next_hash;
263
- for (next_hash = Hash(++ip, shift); ; ) {
265
+ for (next_hash = Hash(++ip, shift, min_match); ; ) {
264
266
  /* Step 1: Scan forward in the input looking for a 6-byte-long match.
265
267
  If we get close to exhausting the input then goto emit_remainder.
266
268
 
@@ -281,31 +283,31 @@ static BROTLI_INLINE void CreateCommands(const uint8_t* input,
281
283
  const uint8_t* next_ip = ip;
282
284
  const uint8_t* candidate;
283
285
 
284
- assert(next_emit < ip);
286
+ BROTLI_DCHECK(next_emit < ip);
285
287
  trawl:
286
288
  do {
287
289
  uint32_t hash = next_hash;
288
290
  uint32_t bytes_between_hash_lookups = skip++ >> 5;
289
291
  ip = next_ip;
290
- assert(hash == Hash(ip, shift));
292
+ BROTLI_DCHECK(hash == Hash(ip, shift, min_match));
291
293
  next_ip = ip + bytes_between_hash_lookups;
292
294
  if (BROTLI_PREDICT_FALSE(next_ip > ip_limit)) {
293
295
  goto emit_remainder;
294
296
  }
295
- next_hash = Hash(next_ip, shift);
297
+ next_hash = Hash(next_ip, shift, min_match);
296
298
  candidate = ip - last_distance;
297
- if (IsMatch(ip, candidate)) {
299
+ if (IsMatch(ip, candidate, min_match)) {
298
300
  if (BROTLI_PREDICT_TRUE(candidate < ip)) {
299
301
  table[hash] = (int)(ip - base_ip);
300
302
  break;
301
303
  }
302
304
  }
303
305
  candidate = base_ip + table[hash];
304
- assert(candidate >= base_ip);
305
- assert(candidate < ip);
306
+ BROTLI_DCHECK(candidate >= base_ip);
307
+ BROTLI_DCHECK(candidate < ip);
306
308
 
307
309
  table[hash] = (int)(ip - base_ip);
308
- } while (BROTLI_PREDICT_TRUE(!IsMatch(ip, candidate)));
310
+ } while (BROTLI_PREDICT_TRUE(!IsMatch(ip, candidate, min_match)));
309
311
 
310
312
  /* Check copy distance. If candidate is not feasible, continue search.
311
313
  Checking is done outside of hot loop to reduce overhead. */
@@ -320,12 +322,13 @@ trawl:
320
322
  /* We have a 6-byte match at ip, and we need to emit bytes in
321
323
  [next_emit, ip). */
322
324
  const uint8_t* base = ip;
323
- size_t matched = 6 + FindMatchLengthWithLimit(
324
- candidate + 6, ip + 6, (size_t)(ip_end - ip) - 6);
325
+ size_t matched = min_match + FindMatchLengthWithLimit(
326
+ candidate + min_match, ip + min_match,
327
+ (size_t)(ip_end - ip) - min_match);
325
328
  int distance = (int)(base - candidate); /* > 0 */
326
329
  int insert = (int)(base - next_emit);
327
330
  ip += matched;
328
- assert(0 == memcmp(base, candidate, matched));
331
+ BROTLI_DCHECK(0 == memcmp(base, candidate, matched));
329
332
  EmitInsertLen((uint32_t)insert, commands);
330
333
  memcpy(*literals, next_emit, (size_t)insert);
331
334
  *literals += insert;
@@ -346,35 +349,50 @@ trawl:
346
349
  /* We could immediately start working at ip now, but to improve
347
350
  compression we first update "table" with the hashes of some
348
351
  positions within the last copy. */
349
- uint64_t input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 5);
350
- uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift);
352
+ uint64_t input_bytes;
351
353
  uint32_t cur_hash;
352
- table[prev_hash] = (int)(ip - base_ip - 5);
353
- prev_hash = HashBytesAtOffset(input_bytes, 1, shift);
354
- table[prev_hash] = (int)(ip - base_ip - 4);
355
- prev_hash = HashBytesAtOffset(input_bytes, 2, shift);
356
- table[prev_hash] = (int)(ip - base_ip - 3);
357
- input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 2);
358
- cur_hash = HashBytesAtOffset(input_bytes, 2, shift);
359
- prev_hash = HashBytesAtOffset(input_bytes, 0, shift);
360
- table[prev_hash] = (int)(ip - base_ip - 2);
361
- prev_hash = HashBytesAtOffset(input_bytes, 1, shift);
362
- table[prev_hash] = (int)(ip - base_ip - 1);
354
+ uint32_t prev_hash;
355
+ if (min_match == 4) {
356
+ input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 3);
357
+ cur_hash = HashBytesAtOffset(input_bytes, 3, shift, min_match);
358
+ prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
359
+ table[prev_hash] = (int)(ip - base_ip - 3);
360
+ prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
361
+ table[prev_hash] = (int)(ip - base_ip - 2);
362
+ prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
363
+ table[prev_hash] = (int)(ip - base_ip - 1);
364
+ } else {
365
+ input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 5);
366
+ prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
367
+ table[prev_hash] = (int)(ip - base_ip - 5);
368
+ prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
369
+ table[prev_hash] = (int)(ip - base_ip - 4);
370
+ prev_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
371
+ table[prev_hash] = (int)(ip - base_ip - 3);
372
+ input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 2);
373
+ cur_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
374
+ prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
375
+ table[prev_hash] = (int)(ip - base_ip - 2);
376
+ prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
377
+ table[prev_hash] = (int)(ip - base_ip - 1);
378
+ }
363
379
 
364
380
  candidate = base_ip + table[cur_hash];
365
381
  table[cur_hash] = (int)(ip - base_ip);
366
382
  }
367
383
  }
368
384
 
369
- while (ip - candidate <= MAX_DISTANCE && IsMatch(ip, candidate)) {
385
+ while (ip - candidate <= MAX_DISTANCE &&
386
+ IsMatch(ip, candidate, min_match)) {
370
387
  /* We have a 6-byte match at ip, and no need to emit any
371
388
  literal bytes prior to ip. */
372
389
  const uint8_t* base = ip;
373
- size_t matched = 6 + FindMatchLengthWithLimit(
374
- candidate + 6, ip + 6, (size_t)(ip_end - ip) - 6);
390
+ size_t matched = min_match + FindMatchLengthWithLimit(
391
+ candidate + min_match, ip + min_match,
392
+ (size_t)(ip_end - ip) - min_match);
375
393
  ip += matched;
376
394
  last_distance = (int)(base - candidate); /* > 0 */
377
- assert(0 == memcmp(base, candidate, matched));
395
+ BROTLI_DCHECK(0 == memcmp(base, candidate, matched));
378
396
  EmitCopyLen(matched, commands);
379
397
  EmitDistance((uint32_t)last_distance, commands);
380
398
 
@@ -386,32 +404,45 @@ trawl:
386
404
  /* We could immediately start working at ip now, but to improve
387
405
  compression we first update "table" with the hashes of some
388
406
  positions within the last copy. */
389
- uint64_t input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 5);
390
- uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift);
407
+ uint64_t input_bytes;
391
408
  uint32_t cur_hash;
392
- table[prev_hash] = (int)(ip - base_ip - 5);
393
- prev_hash = HashBytesAtOffset(input_bytes, 1, shift);
394
- table[prev_hash] = (int)(ip - base_ip - 4);
395
- prev_hash = HashBytesAtOffset(input_bytes, 2, shift);
396
- table[prev_hash] = (int)(ip - base_ip - 3);
397
- input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 2);
398
- cur_hash = HashBytesAtOffset(input_bytes, 2, shift);
399
- prev_hash = HashBytesAtOffset(input_bytes, 0, shift);
400
- table[prev_hash] = (int)(ip - base_ip - 2);
401
- prev_hash = HashBytesAtOffset(input_bytes, 1, shift);
402
- table[prev_hash] = (int)(ip - base_ip - 1);
409
+ uint32_t prev_hash;
410
+ if (min_match == 4) {
411
+ input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 3);
412
+ cur_hash = HashBytesAtOffset(input_bytes, 3, shift, min_match);
413
+ prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
414
+ table[prev_hash] = (int)(ip - base_ip - 3);
415
+ prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
416
+ table[prev_hash] = (int)(ip - base_ip - 2);
417
+ prev_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
418
+ table[prev_hash] = (int)(ip - base_ip - 1);
419
+ } else {
420
+ input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 5);
421
+ prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
422
+ table[prev_hash] = (int)(ip - base_ip - 5);
423
+ prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
424
+ table[prev_hash] = (int)(ip - base_ip - 4);
425
+ prev_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
426
+ table[prev_hash] = (int)(ip - base_ip - 3);
427
+ input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 2);
428
+ cur_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
429
+ prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
430
+ table[prev_hash] = (int)(ip - base_ip - 2);
431
+ prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
432
+ table[prev_hash] = (int)(ip - base_ip - 1);
433
+ }
403
434
 
404
435
  candidate = base_ip + table[cur_hash];
405
436
  table[cur_hash] = (int)(ip - base_ip);
406
437
  }
407
438
  }
408
439
 
409
- next_hash = Hash(++ip, shift);
440
+ next_hash = Hash(++ip, shift, min_match);
410
441
  }
411
442
  }
412
443
 
413
444
  emit_remainder:
414
- assert(next_emit <= ip_end);
445
+ BROTLI_DCHECK(next_emit <= ip_end);
415
446
  /* Emit the remaining bytes as literals. */
416
447
  if (next_emit < ip_end) {
417
448
  const uint32_t insert = (uint32_t)(ip_end - next_emit);
@@ -457,7 +488,7 @@ static void StoreCommands(MemoryManager* m,
457
488
 
458
489
  for (i = 0; i < num_commands; ++i) {
459
490
  const uint32_t code = commands[i] & 0xFF;
460
- assert(code < 128);
491
+ BROTLI_DCHECK(code < 128);
461
492
  ++cmd_histo[code];
462
493
  }
463
494
  cmd_histo[1] += 1;
@@ -471,7 +502,7 @@ static void StoreCommands(MemoryManager* m,
471
502
  const uint32_t cmd = commands[i];
472
503
  const uint32_t code = cmd & 0xFF;
473
504
  const uint32_t extra = cmd >> 8;
474
- assert(code < 128);
505
+ BROTLI_DCHECK(code < 128);
475
506
  BrotliWriteBits(cmd_depths[code], cmd_bits[code], storage_ix, storage);
476
507
  BrotliWriteBits(kNumExtraBits[code], extra, storage_ix, storage);
477
508
  if (code < 24) {
@@ -526,7 +557,8 @@ static void EmitUncompressedMetaBlock(const uint8_t* input, size_t input_size,
526
557
  static BROTLI_INLINE void BrotliCompressFragmentTwoPassImpl(
527
558
  MemoryManager* m, const uint8_t* input, size_t input_size,
528
559
  BROTLI_BOOL is_last, uint32_t* command_buf, uint8_t* literal_buf,
529
- int* table, size_t table_bits, size_t* storage_ix, uint8_t* storage) {
560
+ int* table, size_t table_bits, size_t min_match,
561
+ size_t* storage_ix, uint8_t* storage) {
530
562
  /* Save the start of the first block for position and distance computations.
531
563
  */
532
564
  const uint8_t* base_ip = input;
@@ -538,8 +570,8 @@ static BROTLI_INLINE void BrotliCompressFragmentTwoPassImpl(
538
570
  uint32_t* commands = command_buf;
539
571
  uint8_t* literals = literal_buf;
540
572
  size_t num_literals;
541
- CreateCommands(input, block_size, input_size, base_ip, table, table_bits,
542
- &literals, &commands);
573
+ CreateCommands(input, block_size, input_size, base_ip, table,
574
+ table_bits, min_match, &literals, &commands);
543
575
  num_literals = (size_t)(literals - literal_buf);
544
576
  if (ShouldCompress(input, block_size, num_literals)) {
545
577
  const size_t num_commands = (size_t)(commands - command_buf);
@@ -568,8 +600,9 @@ static BROTLI_NOINLINE void BrotliCompressFragmentTwoPassImpl ## B( \
568
600
  MemoryManager* m, const uint8_t* input, size_t input_size, \
569
601
  BROTLI_BOOL is_last, uint32_t* command_buf, uint8_t* literal_buf, \
570
602
  int* table, size_t* storage_ix, uint8_t* storage) { \
603
+ size_t min_match = (B <= 15) ? 4 : 6; \
571
604
  BrotliCompressFragmentTwoPassImpl(m, input, input_size, is_last, command_buf,\
572
- literal_buf, table, B, storage_ix, storage); \
605
+ literal_buf, table, B, min_match, storage_ix, storage); \
573
606
  }
574
607
  FOR_TABLE_BITS_(BAKE_METHOD_PARAM_)
575
608
  #undef BAKE_METHOD_PARAM_
@@ -589,7 +622,7 @@ void BrotliCompressFragmentTwoPass(
589
622
  break;
590
623
  FOR_TABLE_BITS_(CASE_)
591
624
  #undef CASE_
592
- default: assert(0); break;
625
+ default: BROTLI_DCHECK(0); break;
593
626
  }
594
627
 
595
628
  /* If output is larger than single uncompressed block, rewrite it. */