brotli 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +7 -3
  4. data/brotli.gemspec +1 -1
  5. data/ext/brotli/brotli.c +4 -4
  6. data/ext/brotli/brotli.h +2 -2
  7. data/ext/brotli/extconf.rb +9 -16
  8. data/lib/brotli/version.rb +1 -1
  9. data/vendor/brotli/{common → c/common}/constants.h +11 -1
  10. data/vendor/brotli/c/common/dictionary.bin +432 -0
  11. data/vendor/brotli/c/common/dictionary.c +5905 -0
  12. data/vendor/brotli/c/common/dictionary.h +64 -0
  13. data/vendor/brotli/c/common/version.h +19 -0
  14. data/vendor/brotli/{dec → c/dec}/bit_reader.c +2 -2
  15. data/vendor/brotli/{dec → c/dec}/bit_reader.h +11 -34
  16. data/vendor/brotli/{dec → c/dec}/context.h +1 -1
  17. data/vendor/brotli/{dec → c/dec}/decode.c +389 -356
  18. data/vendor/brotli/{dec → c/dec}/huffman.c +24 -23
  19. data/vendor/brotli/{dec → c/dec}/huffman.h +1 -1
  20. data/vendor/brotli/{dec → c/dec}/port.h +19 -10
  21. data/vendor/brotli/{dec → c/dec}/prefix.h +1 -1
  22. data/vendor/brotli/{dec → c/dec}/state.c +23 -19
  23. data/vendor/brotli/{dec → c/dec}/state.h +18 -17
  24. data/vendor/brotli/{dec → c/dec}/transform.h +2 -2
  25. data/vendor/brotli/c/enc/backward_references.c +134 -0
  26. data/vendor/brotli/c/enc/backward_references.h +39 -0
  27. data/vendor/brotli/{enc/backward_references.c → c/enc/backward_references_hq.c} +144 -232
  28. data/vendor/brotli/{enc/backward_references.h → c/enc/backward_references_hq.h} +28 -31
  29. data/vendor/brotli/{enc → c/enc}/backward_references_inc.h +37 -31
  30. data/vendor/brotli/{enc → c/enc}/bit_cost.c +1 -1
  31. data/vendor/brotli/{enc → c/enc}/bit_cost.h +1 -1
  32. data/vendor/brotli/{enc → c/enc}/bit_cost_inc.h +0 -0
  33. data/vendor/brotli/{enc → c/enc}/block_encoder_inc.h +0 -0
  34. data/vendor/brotli/{enc → c/enc}/block_splitter.c +2 -4
  35. data/vendor/brotli/{enc → c/enc}/block_splitter.h +1 -1
  36. data/vendor/brotli/{enc → c/enc}/block_splitter_inc.h +6 -7
  37. data/vendor/brotli/{enc → c/enc}/brotli_bit_stream.c +22 -26
  38. data/vendor/brotli/{enc → c/enc}/brotli_bit_stream.h +1 -5
  39. data/vendor/brotli/{enc → c/enc}/cluster.c +1 -1
  40. data/vendor/brotli/{enc → c/enc}/cluster.h +1 -1
  41. data/vendor/brotli/{enc → c/enc}/cluster_inc.h +2 -0
  42. data/vendor/brotli/{enc → c/enc}/command.h +34 -17
  43. data/vendor/brotli/{enc → c/enc}/compress_fragment.c +97 -53
  44. data/vendor/brotli/{enc → c/enc}/compress_fragment.h +5 -2
  45. data/vendor/brotli/{enc → c/enc}/compress_fragment_two_pass.c +106 -51
  46. data/vendor/brotli/{enc → c/enc}/compress_fragment_two_pass.h +5 -2
  47. data/vendor/brotli/{enc → c/enc}/context.h +3 -3
  48. data/vendor/brotli/c/enc/dictionary_hash.c +1120 -0
  49. data/vendor/brotli/c/enc/dictionary_hash.h +24 -0
  50. data/vendor/brotli/{enc → c/enc}/encode.c +442 -240
  51. data/vendor/brotli/{enc → c/enc}/entropy_encode.c +9 -9
  52. data/vendor/brotli/{enc → c/enc}/entropy_encode.h +4 -4
  53. data/vendor/brotli/{enc → c/enc}/entropy_encode_static.h +4 -4
  54. data/vendor/brotli/{enc → c/enc}/fast_log.h +3 -3
  55. data/vendor/brotli/{enc → c/enc}/find_match_length.h +8 -8
  56. data/vendor/brotli/c/enc/hash.h +446 -0
  57. data/vendor/brotli/{enc → c/enc}/hash_forgetful_chain_inc.h +72 -68
  58. data/vendor/brotli/c/enc/hash_longest_match64_inc.h +266 -0
  59. data/vendor/brotli/c/enc/hash_longest_match_inc.h +258 -0
  60. data/vendor/brotli/{enc → c/enc}/hash_longest_match_quickly_inc.h +81 -77
  61. data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +326 -0
  62. data/vendor/brotli/{enc → c/enc}/histogram.c +4 -2
  63. data/vendor/brotli/{enc → c/enc}/histogram.h +1 -1
  64. data/vendor/brotli/{enc → c/enc}/histogram_inc.h +0 -0
  65. data/vendor/brotli/{enc → c/enc}/literal_cost.c +4 -7
  66. data/vendor/brotli/{enc → c/enc}/literal_cost.h +2 -2
  67. data/vendor/brotli/{enc → c/enc}/memory.c +1 -1
  68. data/vendor/brotli/{enc → c/enc}/memory.h +3 -2
  69. data/vendor/brotli/{enc → c/enc}/metablock.c +136 -123
  70. data/vendor/brotli/{enc → c/enc}/metablock.h +2 -12
  71. data/vendor/brotli/{enc → c/enc}/metablock_inc.h +0 -0
  72. data/vendor/brotli/{enc → c/enc}/port.h +49 -33
  73. data/vendor/brotli/{enc → c/enc}/prefix.h +4 -2
  74. data/vendor/brotli/{enc → c/enc}/quality.h +47 -17
  75. data/vendor/brotli/{enc → c/enc}/ringbuffer.h +6 -6
  76. data/vendor/brotli/{enc → c/enc}/static_dict.c +26 -22
  77. data/vendor/brotli/{enc → c/enc}/static_dict.h +3 -1
  78. data/vendor/brotli/c/enc/static_dict_lut.h +5864 -0
  79. data/vendor/brotli/{enc → c/enc}/utf8_util.c +1 -1
  80. data/vendor/brotli/{enc → c/enc}/utf8_util.h +2 -2
  81. data/vendor/brotli/{enc → c/enc}/write_bits.h +3 -3
  82. data/vendor/brotli/c/include/brotli/decode.h +339 -0
  83. data/vendor/brotli/c/include/brotli/encode.h +402 -0
  84. data/vendor/brotli/c/include/brotli/port.h +146 -0
  85. data/vendor/brotli/c/include/brotli/types.h +90 -0
  86. metadata +80 -79
  87. data/vendor/brotli/common/dictionary.c +0 -9474
  88. data/vendor/brotli/common/dictionary.h +0 -29
  89. data/vendor/brotli/common/port.h +0 -107
  90. data/vendor/brotli/common/types.h +0 -58
  91. data/vendor/brotli/dec/decode.h +0 -188
  92. data/vendor/brotli/enc/compressor.cc +0 -139
  93. data/vendor/brotli/enc/compressor.h +0 -161
  94. data/vendor/brotli/enc/dictionary_hash.h +0 -4121
  95. data/vendor/brotli/enc/encode.h +0 -221
  96. data/vendor/brotli/enc/encode_parallel.cc +0 -289
  97. data/vendor/brotli/enc/encode_parallel.h +0 -27
  98. data/vendor/brotli/enc/hash.h +0 -717
  99. data/vendor/brotli/enc/hash_longest_match_inc.h +0 -241
  100. data/vendor/brotli/enc/static_dict_lut.h +0 -11241
  101. data/vendor/brotli/enc/streams.cc +0 -114
  102. data/vendor/brotli/enc/streams.h +0 -121
@@ -16,7 +16,7 @@
16
16
  #ifndef BROTLI_ENC_BROTLI_BIT_STREAM_H_
17
17
  #define BROTLI_ENC_BROTLI_BIT_STREAM_H_
18
18
 
19
- #include "../common/types.h"
19
+ #include <brotli/types.h>
20
20
  #include "./command.h"
21
21
  #include "./context.h"
22
22
  #include "./entropy_encode.h"
@@ -96,10 +96,6 @@ BROTLI_INTERNAL void BrotliStoreUncompressedMetaBlock(
96
96
  BROTLI_BOOL is_final_block, const uint8_t* input, size_t position,
97
97
  size_t mask, size_t len, size_t* storage_ix, uint8_t* storage);
98
98
 
99
- /* Stores an empty metadata meta-block and syncs to a byte boundary. */
100
- BROTLI_INTERNAL void BrotliStoreSyncMetaBlock(size_t* storage_ix,
101
- uint8_t* storage);
102
-
103
99
  #if defined(__cplusplus) || defined(c_plusplus)
104
100
  } /* extern "C" */
105
101
  #endif
@@ -8,7 +8,7 @@
8
8
 
9
9
  #include "./cluster.h"
10
10
 
11
- #include "../common/types.h"
11
+ #include <brotli/types.h>
12
12
  #include "./bit_cost.h" /* BrotliPopulationCost */
13
13
  #include "./fast_log.h"
14
14
  #include "./histogram.h"
@@ -9,7 +9,7 @@
9
9
  #ifndef BROTLI_ENC_CLUSTER_H_
10
10
  #define BROTLI_ENC_CLUSTER_H_
11
11
 
12
- #include "../common/types.h"
12
+ #include <brotli/types.h>
13
13
  #include "./histogram.h"
14
14
  #include "./memory.h"
15
15
  #include "./port.h"
@@ -17,6 +17,8 @@ BROTLI_INTERNAL void FN(BrotliCompareAndPushToQueue)(
17
17
  size_t* num_pairs) CODE({
18
18
  BROTLI_BOOL is_good_pair = BROTLI_FALSE;
19
19
  HistogramPair p;
20
+ p.idx1 = p.idx2 = 0;
21
+ p.cost_diff = p.cost_combo = 0;
20
22
  if (idx1 == idx2) {
21
23
  return;
22
24
  }
@@ -9,8 +9,9 @@
9
9
  #ifndef BROTLI_ENC_COMMAND_H_
10
10
  #define BROTLI_ENC_COMMAND_H_
11
11
 
12
- #include "../common/types.h"
13
- #include "../common/port.h"
12
+ #include "../common/constants.h"
13
+ #include <brotli/port.h>
14
+ #include <brotli/types.h>
14
15
  #include "./fast_log.h"
15
16
  #include "./prefix.h"
16
17
 
@@ -64,11 +65,17 @@ static BROTLI_INLINE uint16_t CombineLengthCodes(
64
65
  if (use_last_distance && inscode < 8 && copycode < 16) {
65
66
  return (copycode < 8) ? bits64 : (bits64 | 64);
66
67
  } else {
67
- /* "To convert an insert-and-copy length code to an insert length code and
68
- a copy length code, the following table can be used" */
69
- static const uint16_t cells[9] = { 128u, 192u, 384u, 256u, 320u, 512u,
70
- 448u, 576u, 640u };
71
- return cells[(copycode >> 3) + 3 * (inscode >> 3)] | bits64;
68
+ /* Specification: 5 Encoding of ... (last table) */
69
+ /* offset = 2 * index, where index is in range [0..8] */
70
+ int offset = 2 * ((copycode >> 3) + 3 * (inscode >> 3));
71
+ /* All values in specification are K * 64,
72
+ where K = [2, 3, 6, 4, 5, 8, 7, 9, 10],
73
+ i + 1 = [1, 2, 3, 4, 5, 6, 7, 8, 9],
74
+ K - i - 1 = [1, 1, 3, 0, 0, 2, 0, 1, 2] = D.
75
+ All values in D require only 2 bits to encode.
76
+ 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;
72
79
  }
73
80
  }
74
81
 
@@ -107,35 +114,44 @@ typedef struct Command {
107
114
 
108
115
  /* distance_code is e.g. 0 for same-as-last short code, or 16 for offset 1. */
109
116
  static BROTLI_INLINE void InitCommand(Command* self, size_t insertlen,
110
- size_t copylen, size_t copylen_code, size_t distance_code) {
117
+ size_t copylen, int copylen_code_delta, size_t distance_code) {
118
+ /* Don't rely on signed int representation, use honest casts. */
119
+ uint32_t delta = (uint8_t)((int8_t)copylen_code_delta);
111
120
  self->insert_len_ = (uint32_t)insertlen;
112
- self->copy_len_ = (uint32_t)(copylen | ((copylen_code ^ copylen) << 24));
121
+ self->copy_len_ = (uint32_t)(copylen | (delta << 24));
113
122
  /* The distance prefix and extra bits are stored in this Command as if
114
123
  npostfix and ndirect were 0, they are only recomputed later after the
115
124
  clustering if needed. */
116
125
  PrefixEncodeCopyDistance(
117
126
  distance_code, 0, 0, &self->dist_prefix_, &self->dist_extra_);
118
127
  GetLengthCode(
119
- insertlen, copylen_code, TO_BROTLI_BOOL(self->dist_prefix_ == 0),
120
- &self->cmd_prefix_);
128
+ insertlen, (size_t)((int)copylen + copylen_code_delta),
129
+ TO_BROTLI_BOOL(self->dist_prefix_ == 0), &self->cmd_prefix_);
121
130
  }
122
131
 
123
132
  static BROTLI_INLINE void InitInsertCommand(Command* self, size_t insertlen) {
124
133
  self->insert_len_ = (uint32_t)insertlen;
125
134
  self->copy_len_ = 4 << 24;
126
135
  self->dist_extra_ = 0;
127
- self->dist_prefix_ = 16;
136
+ self->dist_prefix_ = BROTLI_NUM_DISTANCE_SHORT_CODES;
128
137
  GetLengthCode(insertlen, 4, BROTLI_FALSE, &self->cmd_prefix_);
129
138
  }
130
139
 
131
- static BROTLI_INLINE uint32_t CommandDistanceCode(const Command* self) {
132
- if (self->dist_prefix_ < 16) {
140
+ static BROTLI_INLINE uint32_t CommandRestoreDistanceCode(const Command* self) {
141
+ if (self->dist_prefix_ < BROTLI_NUM_DISTANCE_SHORT_CODES) {
133
142
  return self->dist_prefix_;
134
143
  } else {
135
144
  uint32_t nbits = self->dist_extra_ >> 24;
136
145
  uint32_t extra = self->dist_extra_ & 0xffffff;
137
- uint32_t prefix = self->dist_prefix_ - 12u - 2u * nbits;
138
- return (prefix << nbits) + extra + 12;
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;
139
155
  }
140
156
  }
141
157
 
@@ -153,7 +169,8 @@ static BROTLI_INLINE uint32_t CommandCopyLen(const Command* self) {
153
169
  }
154
170
 
155
171
  static BROTLI_INLINE uint32_t CommandCopyLenCode(const Command* self) {
156
- return (self->copy_len_ & 0xFFFFFF) ^ (self->copy_len_ >> 24);
172
+ int32_t delta = (int8_t)((uint8_t)(self->copy_len_ >> 24));
173
+ return (uint32_t)((int32_t)(self->copy_len_ & 0xFFFFFF) + delta);
157
174
  }
158
175
 
159
176
  #if defined(__cplusplus) || defined(c_plusplus)
@@ -16,7 +16,8 @@
16
16
 
17
17
  #include <string.h> /* memcmp, memcpy, memset */
18
18
 
19
- #include "../common/types.h"
19
+ #include "../common/constants.h"
20
+ #include <brotli/types.h>
20
21
  #include "./brotli_bit_stream.h"
21
22
  #include "./entropy_encode.h"
22
23
  #include "./fast_log.h"
@@ -30,16 +31,18 @@
30
31
  extern "C" {
31
32
  #endif
32
33
 
34
+ #define MAX_DISTANCE (long)BROTLI_MAX_BACKWARD_LIMIT(18)
35
+
33
36
  /* kHashMul32 multiplier has these properties:
34
37
  * The multiplier must be odd. Otherwise we may lose the highest bit.
35
- * No long streaks of 1s or 0s.
38
+ * No long streaks of ones or zeros.
36
39
  * There is no effort to ensure that it is a prime, the oddity is enough
37
40
  for this use.
38
41
  * The number has been tuned heuristically against compression benchmarks. */
39
42
  static const uint32_t kHashMul32 = 0x1e35a7bd;
40
43
 
41
44
  static BROTLI_INLINE uint32_t Hash(const uint8_t* p, size_t shift) {
42
- const uint64_t h = (BROTLI_UNALIGNED_LOAD64(p) << 24) * kHashMul32;
45
+ const uint64_t h = (BROTLI_UNALIGNED_LOAD64LE(p) << 24) * kHashMul32;
43
46
  return (uint32_t)(h >> shift);
44
47
  }
45
48
 
@@ -132,7 +135,7 @@ static void BuildAndStoreCommandPrefixCode(const uint32_t histogram[128],
132
135
 
133
136
  BrotliCreateHuffmanTree(histogram, 64, 15, tree, depth);
134
137
  BrotliCreateHuffmanTree(&histogram[64], 64, 14, tree, &depth[64]);
135
- /* We have to jump through a few hoopes here in order to compute
138
+ /* We have to jump through a few hoops here in order to compute
136
139
  the command bits because the symbols are in a different order than in
137
140
  the full alphabet. This looks complicated, but having the symbols
138
141
  in this order in the command bits saves a few branches in the Emit*
@@ -322,21 +325,20 @@ static BROTLI_INLINE void EmitLiterals(const uint8_t* input, const size_t len,
322
325
  }
323
326
  }
324
327
 
325
- /* REQUIRES: len <= 1 << 20. */
328
+ /* REQUIRES: len <= 1 << 24. */
326
329
  static void BrotliStoreMetaBlockHeader(
327
330
  size_t len, BROTLI_BOOL is_uncompressed, size_t* storage_ix,
328
331
  uint8_t* storage) {
332
+ size_t nibbles = 6;
329
333
  /* ISLAST */
330
334
  BrotliWriteBits(1, 0, storage_ix, storage);
331
335
  if (len <= (1U << 16)) {
332
- /* MNIBBLES is 4 */
333
- BrotliWriteBits(2, 0, storage_ix, storage);
334
- BrotliWriteBits(16, len - 1, storage_ix, storage);
335
- } else {
336
- /* MNIBBLES is 5 */
337
- BrotliWriteBits(2, 1, storage_ix, storage);
338
- BrotliWriteBits(20, len - 1, storage_ix, storage);
336
+ nibbles = 4;
337
+ } else if (len <= (1U << 20)) {
338
+ nibbles = 5;
339
339
  }
340
+ BrotliWriteBits(2, nibbles - 4, storage_ix, storage);
341
+ BrotliWriteBits(nibbles * 4, len - 1, storage_ix, storage);
340
342
  /* ISUNCOMPRESSED */
341
343
  BrotliWriteBits(1, (uint64_t)is_uncompressed, storage_ix, storage);
342
344
  }
@@ -421,13 +423,11 @@ static uint32_t kCmdHistoSeed[128] = {
421
423
  1, 1, 1, 1, 0, 0, 0, 0,
422
424
  };
423
425
 
424
- void BrotliCompressFragmentFast(MemoryManager* m,
425
- const uint8_t* input, size_t input_size,
426
- BROTLI_BOOL is_last,
427
- int* table, size_t table_size,
428
- uint8_t cmd_depth[128], uint16_t cmd_bits[128],
429
- size_t* cmd_code_numbits, uint8_t* cmd_code,
430
- size_t* storage_ix, uint8_t* storage) {
426
+ static BROTLI_INLINE void BrotliCompressFragmentFastImpl(
427
+ MemoryManager* m, const uint8_t* input, size_t input_size,
428
+ BROTLI_BOOL is_last, int* table, size_t table_bits, uint8_t cmd_depth[128],
429
+ uint16_t cmd_bits[128], size_t* cmd_code_numbits, uint8_t* cmd_code,
430
+ size_t* storage_ix, uint8_t* storage) {
431
431
  uint32_t cmd_histo[128];
432
432
  const uint8_t* ip_end;
433
433
 
@@ -442,7 +442,7 @@ void BrotliCompressFragmentFast(MemoryManager* m,
442
442
  static const size_t kFirstBlockSize = 3 << 15;
443
443
  static const size_t kMergeBlockSize = 1 << 16;
444
444
 
445
- const size_t kInputMarginBytes = 16;
445
+ const size_t kInputMarginBytes = BROTLI_WINDOW_GAP;
446
446
  const size_t kMinMatchLen = 5;
447
447
 
448
448
  const uint8_t* metablock_start = input;
@@ -460,21 +460,7 @@ void BrotliCompressFragmentFast(MemoryManager* m,
460
460
  const uint8_t* ip;
461
461
  int last_distance;
462
462
 
463
- const size_t shift = 64u - Log2FloorNonZero(table_size);
464
- assert(table_size);
465
- assert(table_size <= (1u << 31));
466
- /* table must be power of two */
467
- assert((table_size & (table_size - 1)) == 0);
468
- assert(table_size - 1 ==
469
- (size_t)(MAKE_UINT64_T(0xFFFFFFFF, 0xFFFFFF) >> shift));
470
-
471
- if (input_size == 0) {
472
- assert(is_last);
473
- BrotliWriteBits(1, 1, storage_ix, storage); /* islast */
474
- BrotliWriteBits(1, 1, storage_ix, storage); /* isempty */
475
- *storage_ix = (*storage_ix + 7u) & ~7u;
476
- return;
477
- }
463
+ const size_t shift = 64u - table_bits;
478
464
 
479
465
  BrotliStoreMetaBlockHeader(block_size, 0, storage_ix, storage);
480
466
  /* No block splits, no contexts. */
@@ -506,7 +492,7 @@ void BrotliCompressFragmentFast(MemoryManager* m,
506
492
  last_distance = -1;
507
493
  ip_end = input + block_size;
508
494
 
509
- if (PREDICT_TRUE(block_size >= kInputMarginBytes)) {
495
+ if (BROTLI_PREDICT_TRUE(block_size >= kInputMarginBytes)) {
510
496
  /* For the last block, we need to keep a 16 bytes margin so that we can be
511
497
  sure that all distances are at most window size - 16.
512
498
  For all other blocks, we only need to keep a margin of 5 bytes so that
@@ -530,27 +516,27 @@ void BrotliCompressFragmentFast(MemoryManager* m,
530
516
  and doesn't bother looking for matches everywhere.
531
517
 
532
518
  The "skip" variable keeps track of how many bytes there are since the
533
- last match; dividing it by 32 (ie. right-shifting by five) gives the
519
+ last match; dividing it by 32 (i.e. right-shifting by five) gives the
534
520
  number of bytes to move ahead for each iteration. */
535
521
  uint32_t skip = 32;
536
522
 
537
523
  const uint8_t* next_ip = ip;
538
524
  const uint8_t* candidate;
539
525
  assert(next_emit < ip);
540
-
526
+ trawl:
541
527
  do {
542
528
  uint32_t hash = next_hash;
543
529
  uint32_t bytes_between_hash_lookups = skip++ >> 5;
544
530
  assert(hash == Hash(next_ip, shift));
545
531
  ip = next_ip;
546
532
  next_ip = ip + bytes_between_hash_lookups;
547
- if (PREDICT_FALSE(next_ip > ip_limit)) {
533
+ if (BROTLI_PREDICT_FALSE(next_ip > ip_limit)) {
548
534
  goto emit_remainder;
549
535
  }
550
536
  next_hash = Hash(next_ip, shift);
551
537
  candidate = ip - last_distance;
552
538
  if (IsMatch(ip, candidate)) {
553
- if (PREDICT_TRUE(candidate < ip)) {
539
+ if (BROTLI_PREDICT_TRUE(candidate < ip)) {
554
540
  table[hash] = (int)(ip - base_ip);
555
541
  break;
556
542
  }
@@ -560,10 +546,14 @@ void BrotliCompressFragmentFast(MemoryManager* m,
560
546
  assert(candidate < ip);
561
547
 
562
548
  table[hash] = (int)(ip - base_ip);
563
- } while (PREDICT_TRUE(!IsMatch(ip, candidate)));
549
+ } while (BROTLI_PREDICT_TRUE(!IsMatch(ip, candidate)));
550
+
551
+ /* Check copy distance. If candidate is not feasible, continue search.
552
+ Checking is done outside of hot loop to reduce overhead. */
553
+ if (ip - candidate > MAX_DISTANCE) goto trawl;
564
554
 
565
555
  /* Step 2: Emit the found match together with the literal bytes from
566
- "next_emit" to the bit stream, and then see if we can find a next macth
556
+ "next_emit" to the bit stream, and then see if we can find a next match
567
557
  immediately afterwards. Repeat until we find no match for the input
568
558
  without emitting some literal bytes. */
569
559
 
@@ -577,7 +567,7 @@ void BrotliCompressFragmentFast(MemoryManager* m,
577
567
  size_t insert = (size_t)(base - next_emit);
578
568
  ip += matched;
579
569
  assert(0 == memcmp(base, candidate, matched));
580
- if (PREDICT_TRUE(insert < 6210)) {
570
+ if (BROTLI_PREDICT_TRUE(insert < 6210)) {
581
571
  EmitInsertLen(insert, cmd_depth, cmd_bits, cmd_histo,
582
572
  storage_ix, storage);
583
573
  } else if (ShouldUseUncompressedMode(metablock_start, next_emit, insert,
@@ -606,14 +596,14 @@ void BrotliCompressFragmentFast(MemoryManager* m,
606
596
  storage_ix, storage);
607
597
 
608
598
  next_emit = ip;
609
- if (PREDICT_FALSE(ip >= ip_limit)) {
599
+ if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) {
610
600
  goto emit_remainder;
611
601
  }
612
602
  /* We could immediately start working at ip now, but to improve
613
603
  compression we first update "table" with the hashes of some positions
614
604
  within the last copy. */
615
605
  {
616
- uint64_t input_bytes = BROTLI_UNALIGNED_LOAD64(ip - 3);
606
+ uint64_t input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 3);
617
607
  uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift);
618
608
  uint32_t cur_hash = HashBytesAtOffset(input_bytes, 3, shift);
619
609
  table[prev_hash] = (int)(ip - base_ip - 3);
@@ -633,6 +623,7 @@ void BrotliCompressFragmentFast(MemoryManager* m,
633
623
  const uint8_t* base = ip;
634
624
  size_t matched = 5 + FindMatchLengthWithLimit(
635
625
  candidate + 5, ip + 5, (size_t)(ip_end - ip) - 5);
626
+ if (ip - candidate > MAX_DISTANCE) break;
636
627
  ip += matched;
637
628
  last_distance = (int)(base - candidate); /* > 0 */
638
629
  assert(0 == memcmp(base, candidate, matched));
@@ -642,14 +633,14 @@ void BrotliCompressFragmentFast(MemoryManager* m,
642
633
  cmd_histo, storage_ix, storage);
643
634
 
644
635
  next_emit = ip;
645
- if (PREDICT_FALSE(ip >= ip_limit)) {
636
+ if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) {
646
637
  goto emit_remainder;
647
638
  }
648
639
  /* We could immediately start working at ip now, but to improve
649
640
  compression we first update "table" with the hashes of some positions
650
641
  within the last copy. */
651
642
  {
652
- uint64_t input_bytes = BROTLI_UNALIGNED_LOAD64(ip - 3);
643
+ uint64_t input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 3);
653
644
  uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift);
654
645
  uint32_t cur_hash = HashBytesAtOffset(input_bytes, 3, shift);
655
646
  table[prev_hash] = (int)(ip - base_ip - 3);
@@ -690,7 +681,7 @@ void BrotliCompressFragmentFast(MemoryManager* m,
690
681
  /* Emit the remaining bytes as literals. */
691
682
  if (next_emit < ip_end) {
692
683
  const size_t insert = (size_t)(ip_end - next_emit);
693
- if (PREDICT_TRUE(insert < 6210)) {
684
+ if (BROTLI_PREDICT_TRUE(insert < 6210)) {
694
685
  EmitInsertLen(insert, cmd_depth, cmd_bits, cmd_histo,
695
686
  storage_ix, storage);
696
687
  EmitLiterals(next_emit, insert, lit_depth, lit_bits, storage_ix, storage);
@@ -728,11 +719,7 @@ next_block:
728
719
  goto emit_commands;
729
720
  }
730
721
 
731
- if (is_last) {
732
- BrotliWriteBits(1, 1, storage_ix, storage); /* islast */
733
- BrotliWriteBits(1, 1, storage_ix, storage); /* isempty */
734
- *storage_ix = (*storage_ix + 7u) & ~7u;
735
- } else {
722
+ if (!is_last) {
736
723
  /* If this is not the last block, update the command and distance prefix
737
724
  codes for the next block and store the compressed forms. */
738
725
  cmd_code[0] = 0;
@@ -742,6 +729,63 @@ next_block:
742
729
  }
743
730
  }
744
731
 
732
+ #define FOR_TABLE_BITS_(X) X(9) X(11) X(13) X(15)
733
+
734
+ #define BAKE_METHOD_PARAM_(B) \
735
+ static BROTLI_NOINLINE void BrotliCompressFragmentFastImpl ## B( \
736
+ MemoryManager* m, const uint8_t* input, size_t input_size, \
737
+ BROTLI_BOOL is_last, int* table, uint8_t cmd_depth[128], \
738
+ uint16_t cmd_bits[128], size_t* cmd_code_numbits, uint8_t* cmd_code, \
739
+ size_t* storage_ix, uint8_t* storage) { \
740
+ BrotliCompressFragmentFastImpl(m, input, input_size, is_last, table, B, \
741
+ cmd_depth, cmd_bits, cmd_code_numbits, cmd_code, storage_ix, storage); \
742
+ }
743
+ FOR_TABLE_BITS_(BAKE_METHOD_PARAM_)
744
+ #undef BAKE_METHOD_PARAM_
745
+
746
+ void BrotliCompressFragmentFast(
747
+ MemoryManager* m, const uint8_t* input, size_t input_size,
748
+ BROTLI_BOOL is_last, int* table, size_t table_size, uint8_t cmd_depth[128],
749
+ uint16_t cmd_bits[128], size_t* cmd_code_numbits, uint8_t* cmd_code,
750
+ size_t* storage_ix, uint8_t* storage) {
751
+ const size_t initial_storage_ix = *storage_ix;
752
+ const size_t table_bits = Log2FloorNonZero(table_size);
753
+
754
+ if (input_size == 0) {
755
+ assert(is_last);
756
+ BrotliWriteBits(1, 1, storage_ix, storage); /* islast */
757
+ BrotliWriteBits(1, 1, storage_ix, storage); /* isempty */
758
+ *storage_ix = (*storage_ix + 7u) & ~7u;
759
+ return;
760
+ }
761
+
762
+ switch (table_bits) {
763
+ #define CASE_(B) \
764
+ case B: \
765
+ BrotliCompressFragmentFastImpl ## B( \
766
+ m, input, input_size, is_last, table, cmd_depth, cmd_bits, \
767
+ cmd_code_numbits, cmd_code, storage_ix, storage); \
768
+ break;
769
+ FOR_TABLE_BITS_(CASE_)
770
+ #undef CASE_
771
+ default: assert(0); break;
772
+ }
773
+
774
+ /* If output is larger than single uncompressed block, rewrite it. */
775
+ if (*storage_ix - initial_storage_ix > 31 + (input_size << 3)) {
776
+ EmitUncompressedMetaBlock(input, input + input_size, initial_storage_ix,
777
+ storage_ix, storage);
778
+ }
779
+
780
+ if (is_last) {
781
+ BrotliWriteBits(1, 1, storage_ix, storage); /* islast */
782
+ BrotliWriteBits(1, 1, storage_ix, storage); /* isempty */
783
+ *storage_ix = (*storage_ix + 7u) & ~7u;
784
+ }
785
+ }
786
+
787
+ #undef FOR_TABLE_BITS_
788
+
745
789
  #if defined(__cplusplus) || defined(c_plusplus)
746
790
  } /* extern "C" */
747
791
  #endif