brotli 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +6 -3
- data/.github/workflows/publish.yml +7 -17
- data/.gitmodules +1 -1
- data/README.md +2 -2
- data/ext/brotli/brotli.c +1 -0
- data/ext/brotli/extconf.rb +6 -0
- data/lib/brotli/version.rb +1 -1
- data/test/brotli_test.rb +4 -1
- data/vendor/brotli/c/common/constants.c +1 -1
- data/vendor/brotli/c/common/constants.h +2 -1
- data/vendor/brotli/c/common/context.c +1 -1
- data/vendor/brotli/c/common/dictionary.c +5 -3
- data/vendor/brotli/c/common/platform.c +2 -1
- data/vendor/brotli/c/common/platform.h +60 -113
- data/vendor/brotli/c/common/shared_dictionary.c +521 -0
- data/vendor/brotli/c/common/shared_dictionary_internal.h +75 -0
- data/vendor/brotli/c/common/transform.c +1 -1
- data/vendor/brotli/c/common/version.h +31 -6
- data/vendor/brotli/c/dec/bit_reader.c +10 -8
- data/vendor/brotli/c/dec/bit_reader.h +172 -100
- data/vendor/brotli/c/dec/decode.c +467 -200
- data/vendor/brotli/c/dec/huffman.c +7 -4
- data/vendor/brotli/c/dec/huffman.h +2 -1
- data/vendor/brotli/c/dec/prefix.h +2 -1
- data/vendor/brotli/c/dec/state.c +33 -9
- data/vendor/brotli/c/dec/state.h +70 -35
- data/vendor/brotli/c/enc/backward_references.c +81 -19
- data/vendor/brotli/c/enc/backward_references.h +5 -4
- data/vendor/brotli/c/enc/backward_references_hq.c +148 -52
- data/vendor/brotli/c/enc/backward_references_hq.h +6 -5
- data/vendor/brotli/c/enc/backward_references_inc.h +31 -5
- data/vendor/brotli/c/enc/bit_cost.c +8 -7
- data/vendor/brotli/c/enc/bit_cost.h +5 -4
- data/vendor/brotli/c/enc/block_splitter.c +37 -14
- data/vendor/brotli/c/enc/block_splitter.h +5 -4
- data/vendor/brotli/c/enc/block_splitter_inc.h +86 -45
- data/vendor/brotli/c/enc/brotli_bit_stream.c +132 -110
- data/vendor/brotli/c/enc/brotli_bit_stream.h +11 -6
- data/vendor/brotli/c/enc/cluster.c +10 -9
- data/vendor/brotli/c/enc/cluster.h +7 -6
- data/vendor/brotli/c/enc/cluster_inc.h +25 -20
- data/vendor/brotli/c/enc/command.c +1 -1
- data/vendor/brotli/c/enc/command.h +5 -4
- data/vendor/brotli/c/enc/compound_dictionary.c +207 -0
- data/vendor/brotli/c/enc/compound_dictionary.h +74 -0
- data/vendor/brotli/c/enc/compress_fragment.c +93 -83
- data/vendor/brotli/c/enc/compress_fragment.h +32 -7
- data/vendor/brotli/c/enc/compress_fragment_two_pass.c +99 -87
- data/vendor/brotli/c/enc/compress_fragment_two_pass.h +21 -3
- data/vendor/brotli/c/enc/dictionary_hash.c +3 -1
- data/vendor/brotli/c/enc/encode.c +473 -404
- data/vendor/brotli/c/enc/encoder_dict.c +611 -4
- data/vendor/brotli/c/enc/encoder_dict.h +117 -3
- data/vendor/brotli/c/enc/entropy_encode.c +3 -2
- data/vendor/brotli/c/enc/entropy_encode.h +2 -1
- data/vendor/brotli/c/enc/entropy_encode_static.h +5 -2
- data/vendor/brotli/c/enc/fast_log.c +1 -1
- data/vendor/brotli/c/enc/fast_log.h +2 -1
- data/vendor/brotli/c/enc/find_match_length.h +15 -22
- data/vendor/brotli/c/enc/hash.h +285 -45
- data/vendor/brotli/c/enc/hash_composite_inc.h +26 -11
- data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +20 -18
- data/vendor/brotli/c/enc/hash_longest_match64_inc.h +34 -39
- data/vendor/brotli/c/enc/hash_longest_match_inc.h +6 -10
- data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -4
- data/vendor/brotli/c/enc/hash_rolling_inc.h +4 -4
- data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +6 -5
- data/vendor/brotli/c/enc/histogram.c +4 -4
- data/vendor/brotli/c/enc/histogram.h +7 -6
- data/vendor/brotli/c/enc/literal_cost.c +20 -15
- data/vendor/brotli/c/enc/literal_cost.h +4 -2
- data/vendor/brotli/c/enc/memory.c +29 -5
- data/vendor/brotli/c/enc/memory.h +19 -2
- data/vendor/brotli/c/enc/metablock.c +72 -58
- data/vendor/brotli/c/enc/metablock.h +9 -8
- data/vendor/brotli/c/enc/metablock_inc.h +8 -6
- data/vendor/brotli/c/enc/params.h +4 -3
- data/vendor/brotli/c/enc/prefix.h +3 -2
- data/vendor/brotli/c/enc/quality.h +40 -3
- data/vendor/brotli/c/enc/ringbuffer.h +4 -3
- data/vendor/brotli/c/enc/state.h +104 -0
- data/vendor/brotli/c/enc/static_dict.c +60 -4
- data/vendor/brotli/c/enc/static_dict.h +3 -2
- data/vendor/brotli/c/enc/static_dict_lut.h +2 -0
- data/vendor/brotli/c/enc/utf8_util.c +1 -1
- data/vendor/brotli/c/enc/utf8_util.h +2 -1
- data/vendor/brotli/c/enc/write_bits.h +2 -1
- data/vendor/brotli/c/include/brotli/decode.h +67 -2
- data/vendor/brotli/c/include/brotli/encode.h +55 -2
- data/vendor/brotli/c/include/brotli/port.h +28 -11
- data/vendor/brotli/c/include/brotli/shared_dictionary.h +100 -0
- 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 "
|
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
|
-
|
23
|
-
#include "
|
24
|
-
#include "
|
25
|
-
#include "
|
26
|
-
#include "
|
27
|
-
#include "
|
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(
|
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
|
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(
|
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(
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
uint8_t
|
133
|
-
uint16_t
|
134
|
-
|
135
|
-
|
136
|
-
|
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(
|
143
|
-
memcpy(
|
144
|
-
memcpy(
|
145
|
-
memcpy(
|
146
|
-
memcpy(
|
147
|
-
memcpy(
|
148
|
-
BrotliConvertBitDepthsToSymbols(
|
149
|
-
memcpy(bits,
|
150
|
-
memcpy(bits + 24,
|
151
|
-
memcpy(bits + 32,
|
152
|
-
memcpy(bits + 40,
|
153
|
-
memcpy(bits + 48,
|
154
|
-
memcpy(bits + 56,
|
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(
|
160
|
-
memcpy(
|
161
|
-
memcpy(
|
162
|
-
memcpy(
|
163
|
-
memcpy(
|
164
|
-
memcpy(
|
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
|
-
|
167
|
-
|
168
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
427
|
-
BROTLI_BOOL is_last, int* table, size_t table_bits,
|
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
|
-
|
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
|
-
|
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 <
|
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(
|
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
|
-
|
715
|
-
|
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
|
-
|
726
|
-
BuildAndStoreCommandPrefixCode(
|
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
|
-
|
736
|
-
BROTLI_BOOL is_last, int* table, uint8_t
|
737
|
-
|
738
|
-
|
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
|
-
|
747
|
-
BROTLI_BOOL is_last, int* table, size_t table_size,
|
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
|
-
|
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
|
-
|
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(
|
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
|
|