brotli 0.1.8 → 0.2.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/.gitignore +1 -0
- data/.travis.yml +7 -3
- data/brotli.gemspec +1 -1
- data/ext/brotli/brotli.c +4 -4
- data/ext/brotli/brotli.h +2 -2
- data/ext/brotli/extconf.rb +9 -16
- data/lib/brotli/version.rb +1 -1
- data/vendor/brotli/{common → c/common}/constants.h +11 -1
- data/vendor/brotli/c/common/dictionary.bin +432 -0
- data/vendor/brotli/c/common/dictionary.c +5905 -0
- data/vendor/brotli/c/common/dictionary.h +64 -0
- data/vendor/brotli/c/common/version.h +19 -0
- data/vendor/brotli/{dec → c/dec}/bit_reader.c +2 -2
- data/vendor/brotli/{dec → c/dec}/bit_reader.h +11 -34
- data/vendor/brotli/{dec → c/dec}/context.h +1 -1
- data/vendor/brotli/{dec → c/dec}/decode.c +389 -356
- data/vendor/brotli/{dec → c/dec}/huffman.c +24 -23
- data/vendor/brotli/{dec → c/dec}/huffman.h +1 -1
- data/vendor/brotli/{dec → c/dec}/port.h +19 -10
- data/vendor/brotli/{dec → c/dec}/prefix.h +1 -1
- data/vendor/brotli/{dec → c/dec}/state.c +23 -19
- data/vendor/brotli/{dec → c/dec}/state.h +18 -17
- data/vendor/brotli/{dec → c/dec}/transform.h +2 -2
- data/vendor/brotli/c/enc/backward_references.c +134 -0
- data/vendor/brotli/c/enc/backward_references.h +39 -0
- data/vendor/brotli/{enc/backward_references.c → c/enc/backward_references_hq.c} +144 -232
- data/vendor/brotli/{enc/backward_references.h → c/enc/backward_references_hq.h} +28 -31
- data/vendor/brotli/{enc → c/enc}/backward_references_inc.h +37 -31
- data/vendor/brotli/{enc → c/enc}/bit_cost.c +1 -1
- data/vendor/brotli/{enc → c/enc}/bit_cost.h +1 -1
- data/vendor/brotli/{enc → c/enc}/bit_cost_inc.h +0 -0
- data/vendor/brotli/{enc → c/enc}/block_encoder_inc.h +0 -0
- data/vendor/brotli/{enc → c/enc}/block_splitter.c +2 -4
- data/vendor/brotli/{enc → c/enc}/block_splitter.h +1 -1
- data/vendor/brotli/{enc → c/enc}/block_splitter_inc.h +6 -7
- data/vendor/brotli/{enc → c/enc}/brotli_bit_stream.c +22 -26
- data/vendor/brotli/{enc → c/enc}/brotli_bit_stream.h +1 -5
- data/vendor/brotli/{enc → c/enc}/cluster.c +1 -1
- data/vendor/brotli/{enc → c/enc}/cluster.h +1 -1
- data/vendor/brotli/{enc → c/enc}/cluster_inc.h +2 -0
- data/vendor/brotli/{enc → c/enc}/command.h +34 -17
- data/vendor/brotli/{enc → c/enc}/compress_fragment.c +97 -53
- data/vendor/brotli/{enc → c/enc}/compress_fragment.h +5 -2
- data/vendor/brotli/{enc → c/enc}/compress_fragment_two_pass.c +106 -51
- data/vendor/brotli/{enc → c/enc}/compress_fragment_two_pass.h +5 -2
- data/vendor/brotli/{enc → c/enc}/context.h +3 -3
- data/vendor/brotli/c/enc/dictionary_hash.c +1120 -0
- data/vendor/brotli/c/enc/dictionary_hash.h +24 -0
- data/vendor/brotli/{enc → c/enc}/encode.c +442 -240
- data/vendor/brotli/{enc → c/enc}/entropy_encode.c +9 -9
- data/vendor/brotli/{enc → c/enc}/entropy_encode.h +4 -4
- data/vendor/brotli/{enc → c/enc}/entropy_encode_static.h +4 -4
- data/vendor/brotli/{enc → c/enc}/fast_log.h +3 -3
- data/vendor/brotli/{enc → c/enc}/find_match_length.h +8 -8
- data/vendor/brotli/c/enc/hash.h +446 -0
- data/vendor/brotli/{enc → c/enc}/hash_forgetful_chain_inc.h +72 -68
- data/vendor/brotli/c/enc/hash_longest_match64_inc.h +266 -0
- data/vendor/brotli/c/enc/hash_longest_match_inc.h +258 -0
- data/vendor/brotli/{enc → c/enc}/hash_longest_match_quickly_inc.h +81 -77
- data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +326 -0
- data/vendor/brotli/{enc → c/enc}/histogram.c +4 -2
- data/vendor/brotli/{enc → c/enc}/histogram.h +1 -1
- data/vendor/brotli/{enc → c/enc}/histogram_inc.h +0 -0
- data/vendor/brotli/{enc → c/enc}/literal_cost.c +4 -7
- data/vendor/brotli/{enc → c/enc}/literal_cost.h +2 -2
- data/vendor/brotli/{enc → c/enc}/memory.c +1 -1
- data/vendor/brotli/{enc → c/enc}/memory.h +3 -2
- data/vendor/brotli/{enc → c/enc}/metablock.c +136 -123
- data/vendor/brotli/{enc → c/enc}/metablock.h +2 -12
- data/vendor/brotli/{enc → c/enc}/metablock_inc.h +0 -0
- data/vendor/brotli/{enc → c/enc}/port.h +49 -33
- data/vendor/brotli/{enc → c/enc}/prefix.h +4 -2
- data/vendor/brotli/{enc → c/enc}/quality.h +47 -17
- data/vendor/brotli/{enc → c/enc}/ringbuffer.h +6 -6
- data/vendor/brotli/{enc → c/enc}/static_dict.c +26 -22
- data/vendor/brotli/{enc → c/enc}/static_dict.h +3 -1
- data/vendor/brotli/c/enc/static_dict_lut.h +5864 -0
- data/vendor/brotli/{enc → c/enc}/utf8_util.c +1 -1
- data/vendor/brotli/{enc → c/enc}/utf8_util.h +2 -2
- data/vendor/brotli/{enc → c/enc}/write_bits.h +3 -3
- data/vendor/brotli/c/include/brotli/decode.h +339 -0
- data/vendor/brotli/c/include/brotli/encode.h +402 -0
- data/vendor/brotli/c/include/brotli/port.h +146 -0
- data/vendor/brotli/c/include/brotli/types.h +90 -0
- metadata +80 -79
- data/vendor/brotli/common/dictionary.c +0 -9474
- data/vendor/brotli/common/dictionary.h +0 -29
- data/vendor/brotli/common/port.h +0 -107
- data/vendor/brotli/common/types.h +0 -58
- data/vendor/brotli/dec/decode.h +0 -188
- data/vendor/brotli/enc/compressor.cc +0 -139
- data/vendor/brotli/enc/compressor.h +0 -161
- data/vendor/brotli/enc/dictionary_hash.h +0 -4121
- data/vendor/brotli/enc/encode.h +0 -221
- data/vendor/brotli/enc/encode_parallel.cc +0 -289
- data/vendor/brotli/enc/encode_parallel.h +0 -27
- data/vendor/brotli/enc/hash.h +0 -717
- data/vendor/brotli/enc/hash_longest_match_inc.h +0 -241
- data/vendor/brotli/enc/static_dict_lut.h +0 -11241
- data/vendor/brotli/enc/streams.cc +0 -114
- 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
|
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
|
@@ -9,8 +9,9 @@
|
|
9
9
|
#ifndef BROTLI_ENC_COMMAND_H_
|
10
10
|
#define BROTLI_ENC_COMMAND_H_
|
11
11
|
|
12
|
-
#include "../common/
|
13
|
-
#include
|
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
|
-
/*
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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,
|
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 | (
|
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,
|
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_ =
|
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
|
132
|
-
if (self->dist_prefix_ <
|
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
|
-
|
138
|
-
|
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
|
-
|
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/
|
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
|
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 = (
|
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
|
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 <<
|
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
|
-
|
333
|
-
|
334
|
-
|
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
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
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 =
|
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 -
|
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 (
|
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 (
|
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 (
|
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 (
|
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 (
|
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
|
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 (
|
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 (
|
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 =
|
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 (
|
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 =
|
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 (
|
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
|