brotli 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +8 -0
- data/ext/brotli/extconf.rb +6 -0
- data/lib/brotli/version.rb +1 -1
- data/test/brotli_test.rb +14 -1
- data/test/test_helper.rb +1 -0
- 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" */
|