brotli 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +6 -3
  3. data/.github/workflows/publish.yml +7 -17
  4. data/.gitmodules +1 -1
  5. data/README.md +2 -2
  6. data/ext/brotli/brotli.c +1 -0
  7. data/ext/brotli/extconf.rb +6 -0
  8. data/lib/brotli/version.rb +1 -1
  9. data/test/brotli_test.rb +4 -1
  10. data/vendor/brotli/c/common/constants.c +1 -1
  11. data/vendor/brotli/c/common/constants.h +2 -1
  12. data/vendor/brotli/c/common/context.c +1 -1
  13. data/vendor/brotli/c/common/dictionary.c +5 -3
  14. data/vendor/brotli/c/common/platform.c +2 -1
  15. data/vendor/brotli/c/common/platform.h +60 -113
  16. data/vendor/brotli/c/common/shared_dictionary.c +521 -0
  17. data/vendor/brotli/c/common/shared_dictionary_internal.h +75 -0
  18. data/vendor/brotli/c/common/transform.c +1 -1
  19. data/vendor/brotli/c/common/version.h +31 -6
  20. data/vendor/brotli/c/dec/bit_reader.c +10 -8
  21. data/vendor/brotli/c/dec/bit_reader.h +172 -100
  22. data/vendor/brotli/c/dec/decode.c +467 -200
  23. data/vendor/brotli/c/dec/huffman.c +7 -4
  24. data/vendor/brotli/c/dec/huffman.h +2 -1
  25. data/vendor/brotli/c/dec/prefix.h +2 -1
  26. data/vendor/brotli/c/dec/state.c +33 -9
  27. data/vendor/brotli/c/dec/state.h +70 -35
  28. data/vendor/brotli/c/enc/backward_references.c +81 -19
  29. data/vendor/brotli/c/enc/backward_references.h +5 -4
  30. data/vendor/brotli/c/enc/backward_references_hq.c +148 -52
  31. data/vendor/brotli/c/enc/backward_references_hq.h +6 -5
  32. data/vendor/brotli/c/enc/backward_references_inc.h +31 -5
  33. data/vendor/brotli/c/enc/bit_cost.c +8 -7
  34. data/vendor/brotli/c/enc/bit_cost.h +5 -4
  35. data/vendor/brotli/c/enc/block_splitter.c +37 -14
  36. data/vendor/brotli/c/enc/block_splitter.h +5 -4
  37. data/vendor/brotli/c/enc/block_splitter_inc.h +86 -45
  38. data/vendor/brotli/c/enc/brotli_bit_stream.c +132 -110
  39. data/vendor/brotli/c/enc/brotli_bit_stream.h +11 -6
  40. data/vendor/brotli/c/enc/cluster.c +10 -9
  41. data/vendor/brotli/c/enc/cluster.h +7 -6
  42. data/vendor/brotli/c/enc/cluster_inc.h +25 -20
  43. data/vendor/brotli/c/enc/command.c +1 -1
  44. data/vendor/brotli/c/enc/command.h +5 -4
  45. data/vendor/brotli/c/enc/compound_dictionary.c +207 -0
  46. data/vendor/brotli/c/enc/compound_dictionary.h +74 -0
  47. data/vendor/brotli/c/enc/compress_fragment.c +93 -83
  48. data/vendor/brotli/c/enc/compress_fragment.h +32 -7
  49. data/vendor/brotli/c/enc/compress_fragment_two_pass.c +99 -87
  50. data/vendor/brotli/c/enc/compress_fragment_two_pass.h +21 -3
  51. data/vendor/brotli/c/enc/dictionary_hash.c +3 -1
  52. data/vendor/brotli/c/enc/encode.c +473 -404
  53. data/vendor/brotli/c/enc/encoder_dict.c +611 -4
  54. data/vendor/brotli/c/enc/encoder_dict.h +117 -3
  55. data/vendor/brotli/c/enc/entropy_encode.c +3 -2
  56. data/vendor/brotli/c/enc/entropy_encode.h +2 -1
  57. data/vendor/brotli/c/enc/entropy_encode_static.h +5 -2
  58. data/vendor/brotli/c/enc/fast_log.c +1 -1
  59. data/vendor/brotli/c/enc/fast_log.h +2 -1
  60. data/vendor/brotli/c/enc/find_match_length.h +15 -22
  61. data/vendor/brotli/c/enc/hash.h +285 -45
  62. data/vendor/brotli/c/enc/hash_composite_inc.h +26 -11
  63. data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +20 -18
  64. data/vendor/brotli/c/enc/hash_longest_match64_inc.h +34 -39
  65. data/vendor/brotli/c/enc/hash_longest_match_inc.h +6 -10
  66. data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -4
  67. data/vendor/brotli/c/enc/hash_rolling_inc.h +4 -4
  68. data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +6 -5
  69. data/vendor/brotli/c/enc/histogram.c +4 -4
  70. data/vendor/brotli/c/enc/histogram.h +7 -6
  71. data/vendor/brotli/c/enc/literal_cost.c +20 -15
  72. data/vendor/brotli/c/enc/literal_cost.h +4 -2
  73. data/vendor/brotli/c/enc/memory.c +29 -5
  74. data/vendor/brotli/c/enc/memory.h +19 -2
  75. data/vendor/brotli/c/enc/metablock.c +72 -58
  76. data/vendor/brotli/c/enc/metablock.h +9 -8
  77. data/vendor/brotli/c/enc/metablock_inc.h +8 -6
  78. data/vendor/brotli/c/enc/params.h +4 -3
  79. data/vendor/brotli/c/enc/prefix.h +3 -2
  80. data/vendor/brotli/c/enc/quality.h +40 -3
  81. data/vendor/brotli/c/enc/ringbuffer.h +4 -3
  82. data/vendor/brotli/c/enc/state.h +104 -0
  83. data/vendor/brotli/c/enc/static_dict.c +60 -4
  84. data/vendor/brotli/c/enc/static_dict.h +3 -2
  85. data/vendor/brotli/c/enc/static_dict_lut.h +2 -0
  86. data/vendor/brotli/c/enc/utf8_util.c +1 -1
  87. data/vendor/brotli/c/enc/utf8_util.h +2 -1
  88. data/vendor/brotli/c/enc/write_bits.h +2 -1
  89. data/vendor/brotli/c/include/brotli/decode.h +67 -2
  90. data/vendor/brotli/c/include/brotli/encode.h +55 -2
  91. data/vendor/brotli/c/include/brotli/port.h +28 -11
  92. data/vendor/brotli/c/include/brotli/shared_dictionary.h +100 -0
  93. metadata +9 -3
@@ -12,19 +12,18 @@
12
12
  Adapted from the CompressFragment() function in
13
13
  https://github.com/google/snappy/blob/master/snappy.cc */
14
14
 
15
- #include "./compress_fragment.h"
15
+ #include "compress_fragment.h"
16
16
 
17
17
  #include <string.h> /* memcmp, memcpy, memset */
18
18
 
19
- #include "../common/constants.h"
20
- #include "../common/platform.h"
21
19
  #include <brotli/types.h>
22
- #include "./brotli_bit_stream.h"
23
- #include "./entropy_encode.h"
24
- #include "./fast_log.h"
25
- #include "./find_match_length.h"
26
- #include "./memory.h"
27
- #include "./write_bits.h"
20
+
21
+ #include "../common/platform.h"
22
+ #include "brotli_bit_stream.h"
23
+ #include "entropy_encode.h"
24
+ #include "fast_log.h"
25
+ #include "find_match_length.h"
26
+ #include "write_bits.h"
28
27
 
29
28
  #if defined(__cplusplus) || defined(c_plusplus)
30
29
  extern "C" {
@@ -69,16 +68,18 @@ static BROTLI_INLINE BROTLI_BOOL IsMatch(const uint8_t* p1, const uint8_t* p2) {
69
68
  and thus have to assign a non-zero depth for each literal.
70
69
  Returns estimated compression ratio millibytes/char for encoding given input
71
70
  with generated code. */
72
- static size_t BuildAndStoreLiteralPrefixCode(MemoryManager* m,
71
+ static size_t BuildAndStoreLiteralPrefixCode(BrotliOnePassArena* s,
73
72
  const uint8_t* input,
74
73
  const size_t input_size,
75
74
  uint8_t depths[256],
76
75
  uint16_t bits[256],
77
76
  size_t* storage_ix,
78
77
  uint8_t* storage) {
79
- uint32_t histogram[256] = { 0 };
78
+ uint32_t* BROTLI_RESTRICT const histogram = s->histogram;
80
79
  size_t histogram_total;
81
80
  size_t i;
81
+ memset(histogram, 0, sizeof(s->histogram));
82
+
82
83
  if (input_size < (1 << 15)) {
83
84
  for (i = 0; i < input_size; ++i) {
84
85
  ++histogram[input[i]];
@@ -108,10 +109,9 @@ static size_t BuildAndStoreLiteralPrefixCode(MemoryManager* m,
108
109
  histogram_total += adjust;
109
110
  }
110
111
  }
111
- BrotliBuildAndStoreHuffmanTreeFast(m, histogram, histogram_total,
112
+ BrotliBuildAndStoreHuffmanTreeFast(s->tree, histogram, histogram_total,
112
113
  /* max_bits = */ 8,
113
114
  depths, bits, storage_ix, storage);
114
- if (BROTLI_IS_OOM(m)) return 0;
115
115
  {
116
116
  size_t literal_ratio = 0;
117
117
  for (i = 0; i < 256; ++i) {
@@ -124,53 +124,56 @@ static size_t BuildAndStoreLiteralPrefixCode(MemoryManager* m,
124
124
 
125
125
  /* Builds a command and distance prefix code (each 64 symbols) into "depth" and
126
126
  "bits" based on "histogram" and stores it into the bit stream. */
127
- static void BuildAndStoreCommandPrefixCode(const uint32_t histogram[128],
128
- uint8_t depth[128], uint16_t bits[128], size_t* storage_ix,
129
- uint8_t* storage) {
130
- /* Tree size for building a tree over 64 symbols is 2 * 64 + 1. */
131
- HuffmanTree tree[129];
132
- uint8_t cmd_depth[BROTLI_NUM_COMMAND_SYMBOLS] = { 0 };
133
- uint16_t cmd_bits[64];
134
-
135
- BrotliCreateHuffmanTree(histogram, 64, 15, tree, depth);
136
- BrotliCreateHuffmanTree(&histogram[64], 64, 14, tree, &depth[64]);
127
+ static void BuildAndStoreCommandPrefixCode(BrotliOnePassArena* s,
128
+ size_t* storage_ix, uint8_t* storage) {
129
+ const uint32_t* const histogram = s->cmd_histo;
130
+ uint8_t* const depth = s->cmd_depth;
131
+ uint16_t* const bits = s->cmd_bits;
132
+ uint8_t* BROTLI_RESTRICT const tmp_depth = s->tmp_depth;
133
+ uint16_t* BROTLI_RESTRICT const tmp_bits = s->tmp_bits;
134
+ /* TODO(eustas): do only once on initialization. */
135
+ memset(tmp_depth, 0, BROTLI_NUM_COMMAND_SYMBOLS);
136
+
137
+ BrotliCreateHuffmanTree(histogram, 64, 15, s->tree, depth);
138
+ BrotliCreateHuffmanTree(&histogram[64], 64, 14, s->tree, &depth[64]);
137
139
  /* We have to jump through a few hoops here in order to compute
138
140
  the command bits because the symbols are in a different order than in
139
141
  the full alphabet. This looks complicated, but having the symbols
140
142
  in this order in the command bits saves a few branches in the Emit*
141
143
  functions. */
142
- memcpy(cmd_depth, depth, 24);
143
- memcpy(cmd_depth + 24, depth + 40, 8);
144
- memcpy(cmd_depth + 32, depth + 24, 8);
145
- memcpy(cmd_depth + 40, depth + 48, 8);
146
- memcpy(cmd_depth + 48, depth + 32, 8);
147
- memcpy(cmd_depth + 56, depth + 56, 8);
148
- BrotliConvertBitDepthsToSymbols(cmd_depth, 64, cmd_bits);
149
- memcpy(bits, cmd_bits, 48);
150
- memcpy(bits + 24, cmd_bits + 32, 16);
151
- memcpy(bits + 32, cmd_bits + 48, 16);
152
- memcpy(bits + 40, cmd_bits + 24, 16);
153
- memcpy(bits + 48, cmd_bits + 40, 16);
154
- memcpy(bits + 56, cmd_bits + 56, 16);
144
+ memcpy(tmp_depth, depth, 24);
145
+ memcpy(tmp_depth + 24, depth + 40, 8);
146
+ memcpy(tmp_depth + 32, depth + 24, 8);
147
+ memcpy(tmp_depth + 40, depth + 48, 8);
148
+ memcpy(tmp_depth + 48, depth + 32, 8);
149
+ memcpy(tmp_depth + 56, depth + 56, 8);
150
+ BrotliConvertBitDepthsToSymbols(tmp_depth, 64, tmp_bits);
151
+ memcpy(bits, tmp_bits, 48);
152
+ memcpy(bits + 24, tmp_bits + 32, 16);
153
+ memcpy(bits + 32, tmp_bits + 48, 16);
154
+ memcpy(bits + 40, tmp_bits + 24, 16);
155
+ memcpy(bits + 48, tmp_bits + 40, 16);
156
+ memcpy(bits + 56, tmp_bits + 56, 16);
155
157
  BrotliConvertBitDepthsToSymbols(&depth[64], 64, &bits[64]);
156
158
  {
157
159
  /* Create the bit length array for the full command alphabet. */
158
160
  size_t i;
159
- memset(cmd_depth, 0, 64); /* only 64 first values were used */
160
- memcpy(cmd_depth, depth, 8);
161
- memcpy(cmd_depth + 64, depth + 8, 8);
162
- memcpy(cmd_depth + 128, depth + 16, 8);
163
- memcpy(cmd_depth + 192, depth + 24, 8);
164
- memcpy(cmd_depth + 384, depth + 32, 8);
161
+ memset(tmp_depth, 0, 64); /* only 64 first values were used */
162
+ memcpy(tmp_depth, depth, 8);
163
+ memcpy(tmp_depth + 64, depth + 8, 8);
164
+ memcpy(tmp_depth + 128, depth + 16, 8);
165
+ memcpy(tmp_depth + 192, depth + 24, 8);
166
+ memcpy(tmp_depth + 384, depth + 32, 8);
165
167
  for (i = 0; i < 8; ++i) {
166
- cmd_depth[128 + 8 * i] = depth[40 + i];
167
- cmd_depth[256 + 8 * i] = depth[48 + i];
168
- cmd_depth[448 + 8 * i] = depth[56 + i];
168
+ tmp_depth[128 + 8 * i] = depth[40 + i];
169
+ tmp_depth[256 + 8 * i] = depth[48 + i];
170
+ tmp_depth[448 + 8 * i] = depth[56 + i];
169
171
  }
172
+ /* TODO(eustas): could/should full-length machinery be avoided? */
170
173
  BrotliStoreHuffmanTree(
171
- cmd_depth, BROTLI_NUM_COMMAND_SYMBOLS, tree, storage_ix, storage);
174
+ tmp_depth, BROTLI_NUM_COMMAND_SYMBOLS, s->tree, storage_ix, storage);
172
175
  }
173
- BrotliStoreHuffmanTree(&depth[64], 64, tree, storage_ix, storage);
176
+ BrotliStoreHuffmanTree(&depth[64], 64, s->tree, storage_ix, storage);
174
177
  }
175
178
 
176
179
  /* REQUIRES: insertlen < 6210 */
@@ -369,11 +372,12 @@ static void RewindBitPosition(const size_t new_storage_ix,
369
372
  *storage_ix = new_storage_ix;
370
373
  }
371
374
 
372
- static BROTLI_BOOL ShouldMergeBlock(
375
+ static BROTLI_BOOL ShouldMergeBlock(BrotliOnePassArena* s,
373
376
  const uint8_t* data, size_t len, const uint8_t* depths) {
374
- size_t histo[256] = { 0 };
377
+ uint32_t* BROTLI_RESTRICT const histo = s->histogram;
375
378
  static const size_t kSampleRate = 43;
376
379
  size_t i;
380
+ memset(histo, 0, sizeof(s->histogram));
377
381
  for (i = 0; i < len; i += kSampleRate) {
378
382
  ++histo[data[i]];
379
383
  }
@@ -423,11 +427,14 @@ static uint32_t kCmdHistoSeed[128] = {
423
427
  };
424
428
 
425
429
  static BROTLI_INLINE void BrotliCompressFragmentFastImpl(
426
- MemoryManager* m, const uint8_t* input, size_t input_size,
427
- BROTLI_BOOL is_last, int* table, size_t table_bits, uint8_t cmd_depth[128],
428
- uint16_t cmd_bits[128], size_t* cmd_code_numbits, uint8_t* cmd_code,
430
+ BrotliOnePassArena* s, const uint8_t* input, size_t input_size,
431
+ BROTLI_BOOL is_last, int* table, size_t table_bits,
429
432
  size_t* storage_ix, uint8_t* storage) {
430
- uint32_t cmd_histo[128];
433
+ uint8_t* BROTLI_RESTRICT const cmd_depth = s->cmd_depth;
434
+ uint16_t* BROTLI_RESTRICT const cmd_bits = s->cmd_bits;
435
+ uint32_t* BROTLI_RESTRICT const cmd_histo = s->cmd_histo;
436
+ uint8_t* BROTLI_RESTRICT const lit_depth = s->lit_depth;
437
+ uint16_t* BROTLI_RESTRICT const lit_bits = s->lit_bits;
431
438
  const uint8_t* ip_end;
432
439
 
433
440
  /* "next_emit" is a pointer to the first byte that is not covered by a
@@ -451,9 +458,6 @@ static BROTLI_INLINE void BrotliCompressFragmentFastImpl(
451
458
  we can update it later if we decide to extend this meta-block. */
452
459
  size_t mlen_storage_ix = *storage_ix + 3;
453
460
 
454
- uint8_t lit_depth[256];
455
- uint16_t lit_bits[256];
456
-
457
461
  size_t literal_ratio;
458
462
 
459
463
  const uint8_t* ip;
@@ -466,25 +470,24 @@ static BROTLI_INLINE void BrotliCompressFragmentFastImpl(
466
470
  BrotliWriteBits(13, 0, storage_ix, storage);
467
471
 
468
472
  literal_ratio = BuildAndStoreLiteralPrefixCode(
469
- m, input, block_size, lit_depth, lit_bits, storage_ix, storage);
470
- if (BROTLI_IS_OOM(m)) return;
473
+ s, input, block_size, s->lit_depth, s->lit_bits, storage_ix, storage);
471
474
 
472
475
  {
473
476
  /* Store the pre-compressed command and distance prefix codes. */
474
477
  size_t i;
475
- for (i = 0; i + 7 < *cmd_code_numbits; i += 8) {
476
- BrotliWriteBits(8, cmd_code[i >> 3], storage_ix, storage);
478
+ for (i = 0; i + 7 < s->cmd_code_numbits; i += 8) {
479
+ BrotliWriteBits(8, s->cmd_code[i >> 3], storage_ix, storage);
477
480
  }
478
481
  }
479
- BrotliWriteBits(*cmd_code_numbits & 7, cmd_code[*cmd_code_numbits >> 3],
480
- storage_ix, storage);
482
+ BrotliWriteBits(s->cmd_code_numbits & 7,
483
+ s->cmd_code[s->cmd_code_numbits >> 3], storage_ix, storage);
481
484
 
482
485
  emit_commands:
483
486
  /* Initialize the command and distance histograms. We will gather
484
487
  statistics of command and distance codes during the processing
485
488
  of this block and use it to update the command and distance
486
489
  prefix codes for the next block. */
487
- memcpy(cmd_histo, kCmdHistoSeed, sizeof(kCmdHistoSeed));
490
+ memcpy(s->cmd_histo, kCmdHistoSeed, sizeof(kCmdHistoSeed));
488
491
 
489
492
  /* "ip" is the input pointer. */
490
493
  ip = input;
@@ -565,6 +568,8 @@ trawl:
565
568
  int distance = (int)(base - candidate); /* > 0 */
566
569
  size_t insert = (size_t)(base - next_emit);
567
570
  ip += matched;
571
+ BROTLI_LOG(("[CompressFragment] pos = %d insert = %lu copy = %d\n",
572
+ (int)(next_emit - base_ip), (unsigned long)insert, 2));
568
573
  BROTLI_DCHECK(0 == memcmp(base, candidate, matched));
569
574
  if (BROTLI_PREDICT_TRUE(insert < 6210)) {
570
575
  EmitInsertLen(insert, cmd_depth, cmd_bits, cmd_histo,
@@ -593,6 +598,12 @@ trawl:
593
598
  }
594
599
  EmitCopyLenLastDistance(matched, cmd_depth, cmd_bits, cmd_histo,
595
600
  storage_ix, storage);
601
+ BROTLI_LOG(("[CompressFragment] pos = %d distance = %d\n"
602
+ "[CompressFragment] pos = %d insert = %d copy = %d\n"
603
+ "[CompressFragment] pos = %d distance = %d\n",
604
+ (int)(base - base_ip), (int)distance,
605
+ (int)(base - base_ip) + 2, 0, (int)matched - 2,
606
+ (int)(base - base_ip) + 2, (int)distance));
596
607
 
597
608
  next_emit = ip;
598
609
  if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) {
@@ -630,6 +641,10 @@ trawl:
630
641
  storage_ix, storage);
631
642
  EmitDistance((size_t)last_distance, cmd_depth, cmd_bits,
632
643
  cmd_histo, storage_ix, storage);
644
+ BROTLI_LOG(("[CompressFragment] pos = %d insert = %d copy = %d\n"
645
+ "[CompressFragment] pos = %d distance = %d\n",
646
+ (int)(base - base_ip), 0, (int)matched,
647
+ (int)(base - base_ip), (int)last_distance));
633
648
 
634
649
  next_emit = ip;
635
650
  if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) {
@@ -667,7 +682,7 @@ trawl:
667
682
  last insert-only command. */
668
683
  if (input_size > 0 &&
669
684
  total_block_size + block_size <= (1 << 20) &&
670
- ShouldMergeBlock(input, block_size, lit_depth)) {
685
+ ShouldMergeBlock(s, input, block_size, lit_depth)) {
671
686
  BROTLI_DCHECK(total_block_size > (1 << 16));
672
687
  /* Update the size of the current meta-block and continue emitting commands.
673
688
  We can do this because the current size and the new size both have 5
@@ -680,6 +695,8 @@ trawl:
680
695
  /* Emit the remaining bytes as literals. */
681
696
  if (next_emit < ip_end) {
682
697
  const size_t insert = (size_t)(ip_end - next_emit);
698
+ BROTLI_LOG(("[CompressFragment] pos = %d insert = %lu copy = %d\n",
699
+ (int)(next_emit - base_ip), (unsigned long)insert, 2));
683
700
  if (BROTLI_PREDICT_TRUE(insert < 6210)) {
684
701
  EmitInsertLen(insert, cmd_depth, cmd_bits, cmd_histo,
685
702
  storage_ix, storage);
@@ -711,20 +728,17 @@ next_block:
711
728
  /* No block splits, no contexts. */
712
729
  BrotliWriteBits(13, 0, storage_ix, storage);
713
730
  literal_ratio = BuildAndStoreLiteralPrefixCode(
714
- m, input, block_size, lit_depth, lit_bits, storage_ix, storage);
715
- if (BROTLI_IS_OOM(m)) return;
716
- BuildAndStoreCommandPrefixCode(cmd_histo, cmd_depth, cmd_bits,
717
- storage_ix, storage);
731
+ s, input, block_size, lit_depth, lit_bits, storage_ix, storage);
732
+ BuildAndStoreCommandPrefixCode(s, storage_ix, storage);
718
733
  goto emit_commands;
719
734
  }
720
735
 
721
736
  if (!is_last) {
722
737
  /* If this is not the last block, update the command and distance prefix
723
738
  codes for the next block and store the compressed forms. */
724
- cmd_code[0] = 0;
725
- *cmd_code_numbits = 0;
726
- BuildAndStoreCommandPrefixCode(cmd_histo, cmd_depth, cmd_bits,
727
- cmd_code_numbits, cmd_code);
739
+ s->cmd_code[0] = 0;
740
+ s->cmd_code_numbits = 0;
741
+ BuildAndStoreCommandPrefixCode(s, &s->cmd_code_numbits, s->cmd_code);
728
742
  }
729
743
  }
730
744
 
@@ -732,20 +746,17 @@ next_block:
732
746
 
733
747
  #define BAKE_METHOD_PARAM_(B) \
734
748
  static BROTLI_NOINLINE void BrotliCompressFragmentFastImpl ## B( \
735
- MemoryManager* m, const uint8_t* input, size_t input_size, \
736
- BROTLI_BOOL is_last, int* table, uint8_t cmd_depth[128], \
737
- uint16_t cmd_bits[128], size_t* cmd_code_numbits, uint8_t* cmd_code, \
738
- size_t* storage_ix, uint8_t* storage) { \
739
- BrotliCompressFragmentFastImpl(m, input, input_size, is_last, table, B, \
740
- cmd_depth, cmd_bits, cmd_code_numbits, cmd_code, storage_ix, storage); \
749
+ BrotliOnePassArena* s, const uint8_t* input, size_t input_size, \
750
+ BROTLI_BOOL is_last, int* table, size_t* storage_ix, uint8_t* storage) { \
751
+ BrotliCompressFragmentFastImpl(s, input, input_size, is_last, table, B, \
752
+ storage_ix, storage); \
741
753
  }
742
754
  FOR_TABLE_BITS_(BAKE_METHOD_PARAM_)
743
755
  #undef BAKE_METHOD_PARAM_
744
756
 
745
757
  void BrotliCompressFragmentFast(
746
- MemoryManager* m, const uint8_t* input, size_t input_size,
747
- BROTLI_BOOL is_last, int* table, size_t table_size, uint8_t cmd_depth[128],
748
- uint16_t cmd_bits[128], size_t* cmd_code_numbits, uint8_t* cmd_code,
758
+ BrotliOnePassArena* s, const uint8_t* input, size_t input_size,
759
+ BROTLI_BOOL is_last, int* table, size_t table_size,
749
760
  size_t* storage_ix, uint8_t* storage) {
750
761
  const size_t initial_storage_ix = *storage_ix;
751
762
  const size_t table_bits = Log2FloorNonZero(table_size);
@@ -762,8 +773,7 @@ void BrotliCompressFragmentFast(
762
773
  #define CASE_(B) \
763
774
  case B: \
764
775
  BrotliCompressFragmentFastImpl ## B( \
765
- m, input, input_size, is_last, table, cmd_depth, cmd_bits, \
766
- cmd_code_numbits, cmd_code, storage_ix, storage); \
776
+ s, input, input_size, is_last, table, storage_ix, storage);\
767
777
  break;
768
778
  FOR_TABLE_BITS_(CASE_)
769
779
  #undef CASE_
@@ -12,14 +12,43 @@
12
12
  #ifndef BROTLI_ENC_COMPRESS_FRAGMENT_H_
13
13
  #define BROTLI_ENC_COMPRESS_FRAGMENT_H_
14
14
 
15
- #include "../common/platform.h"
16
15
  #include <brotli/types.h>
17
- #include "./memory.h"
16
+
17
+ #include "../common/constants.h"
18
+ #include "../common/platform.h"
19
+ #include "entropy_encode.h"
18
20
 
19
21
  #if defined(__cplusplus) || defined(c_plusplus)
20
22
  extern "C" {
21
23
  #endif
22
24
 
25
+ typedef struct BrotliOnePassArena {
26
+ uint8_t lit_depth[256];
27
+ uint16_t lit_bits[256];
28
+
29
+ /* Command and distance prefix codes (each 64 symbols, stored back-to-back)
30
+ used for the next block. The command prefix code is over a smaller alphabet
31
+ with the following 64 symbols:
32
+ 0 - 15: insert length code 0, copy length code 0 - 15, same distance
33
+ 16 - 39: insert length code 0, copy length code 0 - 23
34
+ 40 - 63: insert length code 0 - 23, copy length code 0
35
+ Note that symbols 16 and 40 represent the same code in the full alphabet,
36
+ but we do not use either of them. */
37
+ uint8_t cmd_depth[128];
38
+ uint16_t cmd_bits[128];
39
+ uint32_t cmd_histo[128];
40
+
41
+ /* The compressed form of the command and distance prefix codes for the next
42
+ block. */
43
+ uint8_t cmd_code[512];
44
+ size_t cmd_code_numbits;
45
+
46
+ HuffmanTree tree[2 * BROTLI_NUM_LITERAL_SYMBOLS + 1];
47
+ uint32_t histogram[256];
48
+ uint8_t tmp_depth[BROTLI_NUM_COMMAND_SYMBOLS];
49
+ uint16_t tmp_bits[64];
50
+ } BrotliOnePassArena;
51
+
23
52
  /* Compresses "input" string to the "*storage" buffer as one or more complete
24
53
  meta-blocks, and updates the "*storage_ix" bit position.
25
54
 
@@ -42,15 +71,11 @@ extern "C" {
42
71
  REQUIRES: "table_size" is an odd (9, 11, 13, 15) power of two
43
72
  OUTPUT: maximal copy distance <= |input_size|
44
73
  OUTPUT: maximal copy distance <= BROTLI_MAX_BACKWARD_LIMIT(18) */
45
- BROTLI_INTERNAL void BrotliCompressFragmentFast(MemoryManager* m,
74
+ BROTLI_INTERNAL void BrotliCompressFragmentFast(BrotliOnePassArena* s,
46
75
  const uint8_t* input,
47
76
  size_t input_size,
48
77
  BROTLI_BOOL is_last,
49
78
  int* table, size_t table_size,
50
- uint8_t cmd_depth[128],
51
- uint16_t cmd_bits[128],
52
- size_t* cmd_code_numbits,
53
- uint8_t* cmd_code,
54
79
  size_t* storage_ix,
55
80
  uint8_t* storage);
56
81