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
@@ -10,20 +10,20 @@
|
|
10
10
|
second pass we emit them into the bit stream using prefix codes built based
|
11
11
|
on the actual command and literal byte histograms. */
|
12
12
|
|
13
|
-
#include "
|
13
|
+
#include "compress_fragment_two_pass.h"
|
14
14
|
|
15
15
|
#include <string.h> /* memcmp, memcpy, memset */
|
16
16
|
|
17
|
+
#include <brotli/types.h>
|
18
|
+
|
17
19
|
#include "../common/constants.h"
|
18
20
|
#include "../common/platform.h"
|
19
|
-
#include
|
20
|
-
#include "
|
21
|
-
#include "
|
22
|
-
#include "
|
23
|
-
#include "
|
24
|
-
#include "
|
25
|
-
#include "./memory.h"
|
26
|
-
#include "./write_bits.h"
|
21
|
+
#include "bit_cost.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"
|
27
27
|
|
28
28
|
#if defined(__cplusplus) || defined(c_plusplus)
|
29
29
|
extern "C" {
|
@@ -66,53 +66,53 @@ static BROTLI_INLINE BROTLI_BOOL IsMatch(const uint8_t* p1, const uint8_t* p2,
|
|
66
66
|
|
67
67
|
/* Builds a command and distance prefix code (each 64 symbols) into "depth" and
|
68
68
|
"bits" based on "histogram" and stores it into the bit stream. */
|
69
|
-
static void BuildAndStoreCommandPrefixCode(
|
70
|
-
|
71
|
-
|
72
|
-
size_t* storage_ix, uint8_t* storage) {
|
69
|
+
static void BuildAndStoreCommandPrefixCode(BrotliTwoPassArena* s,
|
70
|
+
size_t* storage_ix,
|
71
|
+
uint8_t* storage) {
|
73
72
|
/* Tree size for building a tree over 64 symbols is 2 * 64 + 1. */
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
BrotliCreateHuffmanTree(
|
78
|
-
|
73
|
+
/* TODO(eustas): initialize once. */
|
74
|
+
memset(s->tmp_depth, 0, sizeof(s->tmp_depth));
|
75
|
+
BrotliCreateHuffmanTree(s->cmd_histo, 64, 15, s->tmp_tree, s->cmd_depth);
|
76
|
+
BrotliCreateHuffmanTree(&s->cmd_histo[64], 64, 14, s->tmp_tree,
|
77
|
+
&s->cmd_depth[64]);
|
79
78
|
/* We have to jump through a few hoops here in order to compute
|
80
79
|
the command bits because the symbols are in a different order than in
|
81
80
|
the full alphabet. This looks complicated, but having the symbols
|
82
81
|
in this order in the command bits saves a few branches in the Emit*
|
83
82
|
functions. */
|
84
|
-
memcpy(
|
85
|
-
memcpy(
|
86
|
-
memcpy(
|
87
|
-
memcpy(
|
88
|
-
memcpy(
|
89
|
-
memcpy(
|
90
|
-
BrotliConvertBitDepthsToSymbols(
|
91
|
-
memcpy(
|
92
|
-
memcpy(
|
93
|
-
memcpy(
|
94
|
-
memcpy(
|
95
|
-
memcpy(
|
96
|
-
memcpy(
|
97
|
-
BrotliConvertBitDepthsToSymbols(&
|
83
|
+
memcpy(s->tmp_depth, s->cmd_depth + 24, 24);
|
84
|
+
memcpy(s->tmp_depth + 24, s->cmd_depth, 8);
|
85
|
+
memcpy(s->tmp_depth + 32, s->cmd_depth + 48, 8);
|
86
|
+
memcpy(s->tmp_depth + 40, s->cmd_depth + 8, 8);
|
87
|
+
memcpy(s->tmp_depth + 48, s->cmd_depth + 56, 8);
|
88
|
+
memcpy(s->tmp_depth + 56, s->cmd_depth + 16, 8);
|
89
|
+
BrotliConvertBitDepthsToSymbols(s->tmp_depth, 64, s->tmp_bits);
|
90
|
+
memcpy(s->cmd_bits, s->tmp_bits + 24, 16);
|
91
|
+
memcpy(s->cmd_bits + 8, s->tmp_bits + 40, 16);
|
92
|
+
memcpy(s->cmd_bits + 16, s->tmp_bits + 56, 16);
|
93
|
+
memcpy(s->cmd_bits + 24, s->tmp_bits, 48);
|
94
|
+
memcpy(s->cmd_bits + 48, s->tmp_bits + 32, 16);
|
95
|
+
memcpy(s->cmd_bits + 56, s->tmp_bits + 48, 16);
|
96
|
+
BrotliConvertBitDepthsToSymbols(&s->cmd_depth[64], 64, &s->cmd_bits[64]);
|
98
97
|
{
|
99
98
|
/* Create the bit length array for the full command alphabet. */
|
100
99
|
size_t i;
|
101
|
-
memset(
|
102
|
-
memcpy(
|
103
|
-
memcpy(
|
104
|
-
memcpy(
|
105
|
-
memcpy(
|
106
|
-
memcpy(
|
100
|
+
memset(s->tmp_depth, 0, 64); /* only 64 first values were used */
|
101
|
+
memcpy(s->tmp_depth, s->cmd_depth + 24, 8);
|
102
|
+
memcpy(s->tmp_depth + 64, s->cmd_depth + 32, 8);
|
103
|
+
memcpy(s->tmp_depth + 128, s->cmd_depth + 40, 8);
|
104
|
+
memcpy(s->tmp_depth + 192, s->cmd_depth + 48, 8);
|
105
|
+
memcpy(s->tmp_depth + 384, s->cmd_depth + 56, 8);
|
107
106
|
for (i = 0; i < 8; ++i) {
|
108
|
-
|
109
|
-
|
110
|
-
|
107
|
+
s->tmp_depth[128 + 8 * i] = s->cmd_depth[i];
|
108
|
+
s->tmp_depth[256 + 8 * i] = s->cmd_depth[8 + i];
|
109
|
+
s->tmp_depth[448 + 8 * i] = s->cmd_depth[16 + i];
|
111
110
|
}
|
112
|
-
BrotliStoreHuffmanTree(
|
113
|
-
|
111
|
+
BrotliStoreHuffmanTree(s->tmp_depth, BROTLI_NUM_COMMAND_SYMBOLS,
|
112
|
+
s->tmp_tree, storage_ix, storage);
|
114
113
|
}
|
115
|
-
BrotliStoreHuffmanTree(&
|
114
|
+
BrotliStoreHuffmanTree(&s->cmd_depth[64], 64, s->tmp_tree, storage_ix,
|
115
|
+
storage);
|
116
116
|
}
|
117
117
|
|
118
118
|
static BROTLI_INLINE void EmitInsertLen(
|
@@ -330,6 +330,8 @@ trawl:
|
|
330
330
|
ip += matched;
|
331
331
|
BROTLI_DCHECK(0 == memcmp(base, candidate, matched));
|
332
332
|
EmitInsertLen((uint32_t)insert, commands);
|
333
|
+
BROTLI_LOG(("[CompressFragment] pos = %d insert = %d copy = %d\n",
|
334
|
+
(int)(next_emit - base_ip), insert, 2));
|
333
335
|
memcpy(*literals, next_emit, (size_t)insert);
|
334
336
|
*literals += insert;
|
335
337
|
if (distance == last_distance) {
|
@@ -340,6 +342,12 @@ trawl:
|
|
340
342
|
last_distance = distance;
|
341
343
|
}
|
342
344
|
EmitCopyLenLastDistance(matched, commands);
|
345
|
+
BROTLI_LOG(("[CompressFragment] pos = %d distance = %d\n"
|
346
|
+
"[CompressFragment] pos = %d insert = %d copy = %d\n"
|
347
|
+
"[CompressFragment] pos = %d distance = %d\n",
|
348
|
+
(int)(base - base_ip), (int)distance,
|
349
|
+
(int)(base - base_ip) + 2, 0, (int)matched - 2,
|
350
|
+
(int)(base - base_ip) + 2, (int)distance));
|
343
351
|
|
344
352
|
next_emit = ip;
|
345
353
|
if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) {
|
@@ -395,6 +403,10 @@ trawl:
|
|
395
403
|
BROTLI_DCHECK(0 == memcmp(base, candidate, matched));
|
396
404
|
EmitCopyLen(matched, commands);
|
397
405
|
EmitDistance((uint32_t)last_distance, commands);
|
406
|
+
BROTLI_LOG(("[CompressFragment] pos = %d insert = %d copy = %d\n"
|
407
|
+
"[CompressFragment] pos = %d distance = %d\n",
|
408
|
+
(int)(base - base_ip), 0, (int)matched,
|
409
|
+
(int)(base - base_ip), (int)last_distance));
|
398
410
|
|
399
411
|
next_emit = ip;
|
400
412
|
if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) {
|
@@ -447,70 +459,71 @@ emit_remainder:
|
|
447
459
|
if (next_emit < ip_end) {
|
448
460
|
const uint32_t insert = (uint32_t)(ip_end - next_emit);
|
449
461
|
EmitInsertLen(insert, commands);
|
462
|
+
BROTLI_LOG(("[CompressFragment] pos = %d insert = %d copy = %d\n",
|
463
|
+
(int)(next_emit - base_ip), insert, 2));
|
450
464
|
memcpy(*literals, next_emit, insert);
|
451
465
|
*literals += insert;
|
452
466
|
}
|
453
467
|
}
|
454
468
|
|
455
|
-
static void StoreCommands(
|
469
|
+
static void StoreCommands(BrotliTwoPassArena* s,
|
456
470
|
const uint8_t* literals, const size_t num_literals,
|
457
471
|
const uint32_t* commands, const size_t num_commands,
|
458
472
|
size_t* storage_ix, uint8_t* storage) {
|
459
473
|
static const uint32_t kNumExtraBits[128] = {
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
474
|
+
0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5,
|
475
|
+
6, 7, 8, 9, 10, 12, 14, 24, 0, 0, 0, 0, 0, 0, 0, 0,
|
476
|
+
1, 1, 2, 2, 3, 3, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0,
|
477
|
+
1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 24,
|
478
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
479
|
+
1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
|
480
|
+
9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
|
481
|
+
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24,
|
467
482
|
};
|
468
483
|
static const uint32_t kInsertOffset[24] = {
|
469
|
-
|
470
|
-
|
484
|
+
0, 1, 2, 3, 4, 5, 6, 8, 10, 14, 18, 26,
|
485
|
+
34, 50, 66, 98, 130, 194, 322, 578, 1090, 2114, 6210, 22594,
|
471
486
|
};
|
472
487
|
|
473
|
-
uint8_t lit_depths[256];
|
474
|
-
uint16_t lit_bits[256];
|
475
|
-
uint32_t lit_histo[256] = { 0 };
|
476
|
-
uint8_t cmd_depths[128] = { 0 };
|
477
|
-
uint16_t cmd_bits[128] = { 0 };
|
478
|
-
uint32_t cmd_histo[128] = { 0 };
|
479
488
|
size_t i;
|
489
|
+
memset(s->lit_histo, 0, sizeof(s->lit_histo));
|
490
|
+
/* TODO(eustas): is that necessary? */
|
491
|
+
memset(s->cmd_depth, 0, sizeof(s->cmd_depth));
|
492
|
+
/* TODO(eustas): is that necessary? */
|
493
|
+
memset(s->cmd_bits, 0, sizeof(s->cmd_bits));
|
494
|
+
memset(s->cmd_histo, 0, sizeof(s->cmd_histo));
|
480
495
|
for (i = 0; i < num_literals; ++i) {
|
481
|
-
++lit_histo[literals[i]];
|
496
|
+
++s->lit_histo[literals[i]];
|
482
497
|
}
|
483
|
-
BrotliBuildAndStoreHuffmanTreeFast(
|
484
|
-
/* max_bits = */ 8,
|
485
|
-
|
486
|
-
storage_ix, storage);
|
487
|
-
if (BROTLI_IS_OOM(m)) return;
|
498
|
+
BrotliBuildAndStoreHuffmanTreeFast(s->tmp_tree, s->lit_histo, num_literals,
|
499
|
+
/* max_bits = */ 8, s->lit_depth,
|
500
|
+
s->lit_bits, storage_ix, storage);
|
488
501
|
|
489
502
|
for (i = 0; i < num_commands; ++i) {
|
490
503
|
const uint32_t code = commands[i] & 0xFF;
|
491
504
|
BROTLI_DCHECK(code < 128);
|
492
|
-
++cmd_histo[code];
|
505
|
+
++s->cmd_histo[code];
|
493
506
|
}
|
494
|
-
cmd_histo[1] += 1;
|
495
|
-
cmd_histo[2] += 1;
|
496
|
-
cmd_histo[64] += 1;
|
497
|
-
cmd_histo[84] += 1;
|
498
|
-
BuildAndStoreCommandPrefixCode(
|
499
|
-
storage_ix, storage);
|
507
|
+
s->cmd_histo[1] += 1;
|
508
|
+
s->cmd_histo[2] += 1;
|
509
|
+
s->cmd_histo[64] += 1;
|
510
|
+
s->cmd_histo[84] += 1;
|
511
|
+
BuildAndStoreCommandPrefixCode(s, storage_ix, storage);
|
500
512
|
|
501
513
|
for (i = 0; i < num_commands; ++i) {
|
502
514
|
const uint32_t cmd = commands[i];
|
503
515
|
const uint32_t code = cmd & 0xFF;
|
504
516
|
const uint32_t extra = cmd >> 8;
|
505
517
|
BROTLI_DCHECK(code < 128);
|
506
|
-
BrotliWriteBits(
|
518
|
+
BrotliWriteBits(s->cmd_depth[code], s->cmd_bits[code], storage_ix, storage);
|
507
519
|
BrotliWriteBits(kNumExtraBits[code], extra, storage_ix, storage);
|
508
520
|
if (code < 24) {
|
509
521
|
const uint32_t insert = kInsertOffset[code] + extra;
|
510
522
|
uint32_t j;
|
511
523
|
for (j = 0; j < insert; ++j) {
|
512
524
|
const uint8_t lit = *literals;
|
513
|
-
BrotliWriteBits(
|
525
|
+
BrotliWriteBits(s->lit_depth[lit], s->lit_bits[lit], storage_ix,
|
526
|
+
storage);
|
514
527
|
++literals;
|
515
528
|
}
|
516
529
|
}
|
@@ -521,19 +534,19 @@ static void StoreCommands(MemoryManager* m,
|
|
521
534
|
#define MIN_RATIO 0.98
|
522
535
|
#define SAMPLE_RATE 43
|
523
536
|
|
524
|
-
static BROTLI_BOOL ShouldCompress(
|
537
|
+
static BROTLI_BOOL ShouldCompress(BrotliTwoPassArena* s,
|
525
538
|
const uint8_t* input, size_t input_size, size_t num_literals) {
|
526
539
|
double corpus_size = (double)input_size;
|
527
540
|
if ((double)num_literals < MIN_RATIO * corpus_size) {
|
528
541
|
return BROTLI_TRUE;
|
529
542
|
} else {
|
530
|
-
uint32_t literal_histo[256] = { 0 };
|
531
543
|
const double max_total_bit_cost = corpus_size * 8 * MIN_RATIO / SAMPLE_RATE;
|
532
544
|
size_t i;
|
545
|
+
memset(s->lit_histo, 0, sizeof(s->lit_histo));
|
533
546
|
for (i = 0; i < input_size; i += SAMPLE_RATE) {
|
534
|
-
++
|
547
|
+
++s->lit_histo[input[i]];
|
535
548
|
}
|
536
|
-
return TO_BROTLI_BOOL(BitsEntropy(
|
549
|
+
return TO_BROTLI_BOOL(BitsEntropy(s->lit_histo, 256) < max_total_bit_cost);
|
537
550
|
}
|
538
551
|
}
|
539
552
|
|
@@ -555,7 +568,7 @@ static void EmitUncompressedMetaBlock(const uint8_t* input, size_t input_size,
|
|
555
568
|
}
|
556
569
|
|
557
570
|
static BROTLI_INLINE void BrotliCompressFragmentTwoPassImpl(
|
558
|
-
|
571
|
+
BrotliTwoPassArena* s, const uint8_t* input, size_t input_size,
|
559
572
|
BROTLI_BOOL is_last, uint32_t* command_buf, uint8_t* literal_buf,
|
560
573
|
int* table, size_t table_bits, size_t min_match,
|
561
574
|
size_t* storage_ix, uint8_t* storage) {
|
@@ -573,14 +586,13 @@ static BROTLI_INLINE void BrotliCompressFragmentTwoPassImpl(
|
|
573
586
|
CreateCommands(input, block_size, input_size, base_ip, table,
|
574
587
|
table_bits, min_match, &literals, &commands);
|
575
588
|
num_literals = (size_t)(literals - literal_buf);
|
576
|
-
if (ShouldCompress(input, block_size, num_literals)) {
|
589
|
+
if (ShouldCompress(s, input, block_size, num_literals)) {
|
577
590
|
const size_t num_commands = (size_t)(commands - command_buf);
|
578
591
|
BrotliStoreMetaBlockHeader(block_size, 0, storage_ix, storage);
|
579
592
|
/* No block splits, no contexts. */
|
580
593
|
BrotliWriteBits(13, 0, storage_ix, storage);
|
581
|
-
StoreCommands(
|
594
|
+
StoreCommands(s, literal_buf, num_literals, command_buf, num_commands,
|
582
595
|
storage_ix, storage);
|
583
|
-
if (BROTLI_IS_OOM(m)) return;
|
584
596
|
} else {
|
585
597
|
/* Since we did not find many backward references and the entropy of
|
586
598
|
the data is close to 8 bits, we can simply emit an uncompressed block.
|
@@ -597,18 +609,18 @@ static BROTLI_INLINE void BrotliCompressFragmentTwoPassImpl(
|
|
597
609
|
|
598
610
|
#define BAKE_METHOD_PARAM_(B) \
|
599
611
|
static BROTLI_NOINLINE void BrotliCompressFragmentTwoPassImpl ## B( \
|
600
|
-
|
612
|
+
BrotliTwoPassArena* s, const uint8_t* input, size_t input_size, \
|
601
613
|
BROTLI_BOOL is_last, uint32_t* command_buf, uint8_t* literal_buf, \
|
602
614
|
int* table, size_t* storage_ix, uint8_t* storage) { \
|
603
615
|
size_t min_match = (B <= 15) ? 4 : 6; \
|
604
|
-
BrotliCompressFragmentTwoPassImpl(
|
616
|
+
BrotliCompressFragmentTwoPassImpl(s, input, input_size, is_last, command_buf,\
|
605
617
|
literal_buf, table, B, min_match, storage_ix, storage); \
|
606
618
|
}
|
607
619
|
FOR_TABLE_BITS_(BAKE_METHOD_PARAM_)
|
608
620
|
#undef BAKE_METHOD_PARAM_
|
609
621
|
|
610
622
|
void BrotliCompressFragmentTwoPass(
|
611
|
-
|
623
|
+
BrotliTwoPassArena* s, const uint8_t* input, size_t input_size,
|
612
624
|
BROTLI_BOOL is_last, uint32_t* command_buf, uint8_t* literal_buf,
|
613
625
|
int* table, size_t table_size, size_t* storage_ix, uint8_t* storage) {
|
614
626
|
const size_t initial_storage_ix = *storage_ix;
|
@@ -617,7 +629,7 @@ void BrotliCompressFragmentTwoPass(
|
|
617
629
|
#define CASE_(B) \
|
618
630
|
case B: \
|
619
631
|
BrotliCompressFragmentTwoPassImpl ## B( \
|
620
|
-
|
632
|
+
s, input, input_size, is_last, command_buf, \
|
621
633
|
literal_buf, table, storage_ix, storage); \
|
622
634
|
break;
|
623
635
|
FOR_TABLE_BITS_(CASE_)
|
@@ -13,16 +13,34 @@
|
|
13
13
|
#ifndef BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_
|
14
14
|
#define BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_
|
15
15
|
|
16
|
-
#include "../common/platform.h"
|
17
16
|
#include <brotli/types.h>
|
18
|
-
|
17
|
+
|
18
|
+
#include "../common/constants.h"
|
19
|
+
#include "../common/platform.h"
|
20
|
+
#include "entropy_encode.h"
|
19
21
|
|
20
22
|
#if defined(__cplusplus) || defined(c_plusplus)
|
21
23
|
extern "C" {
|
22
24
|
#endif
|
23
25
|
|
26
|
+
/* TODO(eustas): turn to macro. */
|
24
27
|
static const size_t kCompressFragmentTwoPassBlockSize = 1 << 17;
|
25
28
|
|
29
|
+
typedef struct BrotliTwoPassArena {
|
30
|
+
uint32_t lit_histo[256];
|
31
|
+
uint8_t lit_depth[256];
|
32
|
+
uint16_t lit_bits[256];
|
33
|
+
|
34
|
+
uint32_t cmd_histo[128];
|
35
|
+
uint8_t cmd_depth[128];
|
36
|
+
uint16_t cmd_bits[128];
|
37
|
+
|
38
|
+
/* BuildAndStoreCommandPrefixCode */
|
39
|
+
HuffmanTree tmp_tree[2 * BROTLI_NUM_LITERAL_SYMBOLS + 1];
|
40
|
+
uint8_t tmp_depth[BROTLI_NUM_COMMAND_SYMBOLS];
|
41
|
+
uint16_t tmp_bits[64];
|
42
|
+
} BrotliTwoPassArena;
|
43
|
+
|
26
44
|
/* Compresses "input" string to the "*storage" buffer as one or more complete
|
27
45
|
meta-blocks, and updates the "*storage_ix" bit position.
|
28
46
|
|
@@ -36,7 +54,7 @@ static const size_t kCompressFragmentTwoPassBlockSize = 1 << 17;
|
|
36
54
|
REQUIRES: "table_size" is a power of two
|
37
55
|
OUTPUT: maximal copy distance <= |input_size|
|
38
56
|
OUTPUT: maximal copy distance <= BROTLI_MAX_BACKWARD_LIMIT(18) */
|
39
|
-
BROTLI_INTERNAL void BrotliCompressFragmentTwoPass(
|
57
|
+
BROTLI_INTERNAL void BrotliCompressFragmentTwoPass(BrotliTwoPassArena* s,
|
40
58
|
const uint8_t* input,
|
41
59
|
size_t input_size,
|
42
60
|
BROTLI_BOOL is_last,
|
@@ -7,12 +7,13 @@
|
|
7
7
|
/* Hash table on the 4-byte prefixes of static dictionary words. */
|
8
8
|
|
9
9
|
#include "../common/platform.h"
|
10
|
-
#include "
|
10
|
+
#include "dictionary_hash.h"
|
11
11
|
|
12
12
|
#if defined(__cplusplus) || defined(c_plusplus)
|
13
13
|
extern "C" {
|
14
14
|
#endif
|
15
15
|
|
16
|
+
/* GENERATED CODE START */
|
16
17
|
BROTLI_INTERNAL const uint16_t kStaticDictionaryHashWords[32768] = {
|
17
18
|
1002,0,0,0,0,0,0,0,0,683,0,0,0,0,0,0,0,1265,0,0,0,0,0,1431,0,0,0,0,0,0,40,0,0,0,
|
18
19
|
0,155,8,741,0,624,0,0,0,0,0,0,0,0,0,0,0,0,66,503,0,0,0,451,0,0,0,0,0,0,0,835,70,
|
@@ -1840,6 +1841,7 @@ BROTLI_INTERNAL const uint8_t kStaticDictionaryHashLengths[32768] = {
|
|
1840
1841
|
0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,
|
1841
1842
|
10,7,0,0,0,0,0,0,0,0,9,0,0,0,0,4,0,0,0,0,0,0,0,0,0,5,11,0,0,0,0,0,0,0,8,6,0,0,9,
|
1842
1843
|
7,0,0,12,4,0,0,0,0,0,0,12,6,0,6,0,7,0,0,8,5,0,0,0,0};
|
1844
|
+
/* GENERATED CODE END */
|
1843
1845
|
|
1844
1846
|
#if defined(__cplusplus) || defined(c_plusplus)
|
1845
1847
|
} /* extern "C" */
|