brotli 0.2.3 → 0.5.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 +37 -0
- data/.github/workflows/publish.yml +24 -0
- data/.gitmodules +1 -1
- data/Gemfile +6 -3
- data/README.md +2 -2
- data/Rakefile +16 -9
- data/brotli.gemspec +7 -13
- data/ext/brotli/brotli.c +210 -31
- data/ext/brotli/buffer.c +1 -7
- data/ext/brotli/buffer.h +1 -1
- data/ext/brotli/extconf.rb +25 -17
- data/lib/brotli/version.rb +1 -1
- data/test/brotli_test.rb +107 -0
- data/test/brotli_writer_test.rb +36 -0
- data/test/test_helper.rb +8 -0
- data/vendor/brotli/c/common/constants.c +15 -0
- data/vendor/brotli/c/common/constants.h +137 -0
- data/vendor/brotli/c/common/context.c +156 -0
- data/vendor/brotli/c/common/context.h +4 -152
- data/vendor/brotli/c/common/dictionary.bin.br +0 -0
- data/vendor/brotli/c/common/dictionary.c +14 -3
- data/vendor/brotli/c/common/platform.c +23 -0
- data/vendor/brotli/c/common/platform.h +95 -122
- 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 +60 -4
- data/vendor/brotli/c/common/transform.h +5 -0
- data/vendor/brotli/c/common/version.h +31 -6
- data/vendor/brotli/c/dec/bit_reader.c +34 -4
- data/vendor/brotli/c/dec/bit_reader.h +221 -107
- data/vendor/brotli/c/dec/decode.c +772 -403
- data/vendor/brotli/c/dec/huffman.c +7 -4
- data/vendor/brotli/c/dec/huffman.h +8 -13
- data/vendor/brotli/c/dec/prefix.h +1 -18
- data/vendor/brotli/c/dec/state.c +40 -21
- data/vendor/brotli/c/dec/state.h +201 -59
- data/vendor/brotli/c/enc/backward_references.c +88 -25
- data/vendor/brotli/c/enc/backward_references.h +10 -8
- data/vendor/brotli/c/enc/backward_references_hq.c +194 -80
- data/vendor/brotli/c/enc/backward_references_hq.h +17 -13
- data/vendor/brotli/c/enc/backward_references_inc.h +52 -16
- 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 +40 -17
- data/vendor/brotli/c/enc/block_splitter.h +5 -4
- data/vendor/brotli/c/enc/block_splitter_inc.h +99 -49
- data/vendor/brotli/c/enc/brotli_bit_stream.c +142 -137
- 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 +30 -22
- data/vendor/brotli/c/enc/command.c +28 -0
- data/vendor/brotli/c/enc/command.h +17 -16
- 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 +100 -88
- data/vendor/brotli/c/enc/compress_fragment_two_pass.h +21 -3
- data/vendor/brotli/c/enc/dictionary_hash.c +1829 -1101
- data/vendor/brotli/c/enc/dictionary_hash.h +2 -1
- data/vendor/brotli/c/enc/encode.c +550 -416
- data/vendor/brotli/c/enc/encoder_dict.c +613 -5
- data/vendor/brotli/c/enc/encoder_dict.h +120 -4
- data/vendor/brotli/c/enc/entropy_encode.c +5 -2
- data/vendor/brotli/c/enc/entropy_encode.h +4 -3
- data/vendor/brotli/c/enc/entropy_encode_static.h +5 -2
- data/vendor/brotli/c/enc/fast_log.c +105 -0
- data/vendor/brotli/c/enc/fast_log.h +21 -101
- data/vendor/brotli/c/enc/find_match_length.h +17 -25
- data/vendor/brotli/c/enc/hash.h +350 -120
- data/vendor/brotli/c/enc/hash_composite_inc.h +71 -67
- data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +92 -51
- data/vendor/brotli/c/enc/hash_longest_match64_inc.h +79 -84
- data/vendor/brotli/c/enc/hash_longest_match_inc.h +53 -54
- data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +93 -62
- data/vendor/brotli/c/enc/hash_rolling_inc.h +25 -29
- data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +42 -40
- 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 +43 -14
- data/vendor/brotli/c/enc/metablock.c +95 -85
- data/vendor/brotli/c/enc/metablock.h +9 -8
- data/vendor/brotli/c/enc/metablock_inc.h +9 -7
- data/vendor/brotli/c/enc/params.h +7 -4
- 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 +8 -4
- 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 +2 -2
- data/vendor/brotli/c/enc/utf8_util.h +2 -1
- data/vendor/brotli/c/enc/write_bits.h +29 -26
- data/vendor/brotli/c/include/brotli/decode.h +67 -2
- data/vendor/brotli/c/include/brotli/encode.h +77 -3
- data/vendor/brotli/c/include/brotli/port.h +34 -3
- data/vendor/brotli/c/include/brotli/shared_dictionary.h +100 -0
- metadata +23 -97
- data/.travis.yml +0 -31
- data/docs/Brotli/Error.html +0 -124
- data/docs/Brotli.html +0 -485
- data/docs/_index.html +0 -122
- data/docs/class_list.html +0 -51
- data/docs/css/common.css +0 -1
- data/docs/css/full_list.css +0 -58
- data/docs/css/style.css +0 -496
- data/docs/file.README.html +0 -127
- data/docs/file_list.html +0 -56
- data/docs/frames.html +0 -17
- data/docs/index.html +0 -127
- data/docs/js/app.js +0 -292
- data/docs/js/full_list.js +0 -216
- data/docs/js/jquery.js +0 -4
- data/docs/method_list.html +0 -67
- data/docs/top-level-namespace.html +0 -110
- data/spec/brotli_spec.rb +0 -88
- data/spec/inflate_spec.rb +0 -75
- data/spec/spec_helper.rb +0 -4
@@ -37,6 +37,8 @@ enum BrotliWordTransformType {
|
|
37
37
|
BROTLI_TRANSFORM_OMIT_FIRST_7 = 18,
|
38
38
|
BROTLI_TRANSFORM_OMIT_FIRST_8 = 19,
|
39
39
|
BROTLI_TRANSFORM_OMIT_FIRST_9 = 20,
|
40
|
+
BROTLI_TRANSFORM_SHIFT_FIRST = 21,
|
41
|
+
BROTLI_TRANSFORM_SHIFT_ALL = 22,
|
40
42
|
BROTLI_NUM_TRANSFORM_TYPES /* Counts transforms, not a transform itself. */
|
41
43
|
};
|
42
44
|
|
@@ -50,6 +52,9 @@ typedef struct BrotliTransforms {
|
|
50
52
|
uint32_t num_transforms;
|
51
53
|
/* Each entry is a [prefix_id, transform, suffix_id] triplet. */
|
52
54
|
const uint8_t* transforms;
|
55
|
+
/* Shift for BROTLI_TRANSFORM_SHIFT_FIRST and BROTLI_TRANSFORM_SHIFT_ALL,
|
56
|
+
must be NULL if and only if no such transforms are present. */
|
57
|
+
const uint8_t* params;
|
53
58
|
/* Indices of transforms like ["", BROTLI_TRANSFORM_OMIT_LAST_#, ""].
|
54
59
|
0-th element corresponds to ["", BROTLI_TRANSFORM_IDENTITY, ""].
|
55
60
|
-1, if cut-off transform does not exist. */
|
@@ -9,18 +9,43 @@
|
|
9
9
|
#ifndef BROTLI_COMMON_VERSION_H_
|
10
10
|
#define BROTLI_COMMON_VERSION_H_
|
11
11
|
|
12
|
-
/*
|
13
|
-
|
12
|
+
/* Compose 3 components into a single number. In a hexadecimal representation
|
13
|
+
B and C components occupy exactly 3 digits. */
|
14
|
+
#define BROTLI_MAKE_HEX_VERSION(A, B, C) ((A << 24) | (B << 12) | C)
|
15
|
+
|
16
|
+
/* Those macros should only be used when library is compiled together with
|
17
|
+
the client. If library is dynamically linked, use BrotliDecoderVersion and
|
14
18
|
BrotliEncoderVersion methods. */
|
15
19
|
|
16
|
-
|
17
|
-
#define
|
20
|
+
#define BROTLI_VERSION_MAJOR 1
|
21
|
+
#define BROTLI_VERSION_MINOR 1
|
22
|
+
#define BROTLI_VERSION_PATCH 0
|
23
|
+
|
24
|
+
#define BROTLI_VERSION BROTLI_MAKE_HEX_VERSION( \
|
25
|
+
BROTLI_VERSION_MAJOR, BROTLI_VERSION_MINOR, BROTLI_VERSION_PATCH)
|
18
26
|
|
19
27
|
/* This macro is used by build system to produce Libtool-friendly soname. See
|
20
28
|
https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
|
29
|
+
Version evolution rules:
|
30
|
+
- interfaces added (or change is compatible) -> current+1:0:age+1
|
31
|
+
- interfaces removed (or changed is incompatible) -> current+1:0:0
|
32
|
+
- interfaces not changed -> current:revision+1:age
|
21
33
|
*/
|
22
34
|
|
23
|
-
|
24
|
-
#define
|
35
|
+
#define BROTLI_ABI_CURRENT 2
|
36
|
+
#define BROTLI_ABI_REVISION 0
|
37
|
+
#define BROTLI_ABI_AGE 1
|
38
|
+
|
39
|
+
#if BROTLI_VERSION_MAJOR != (BROTLI_ABI_CURRENT - BROTLI_ABI_AGE)
|
40
|
+
#error ABI/API version inconsistency
|
41
|
+
#endif
|
42
|
+
|
43
|
+
#if BROTLI_VERSION_MINOR != BROTLI_ABI_AGE
|
44
|
+
#error ABI/API version inconsistency
|
45
|
+
#endif
|
46
|
+
|
47
|
+
#if BROTLI_VERSION_PATCH != BROTLI_ABI_REVISION
|
48
|
+
#error ABI/API version inconsistency
|
49
|
+
#endif
|
25
50
|
|
26
51
|
#endif /* BROTLI_COMMON_VERSION_H_ */
|
@@ -6,18 +6,30 @@
|
|
6
6
|
|
7
7
|
/* Bit reading helpers */
|
8
8
|
|
9
|
-
#include "
|
9
|
+
#include "bit_reader.h"
|
10
10
|
|
11
|
-
#include "../common/platform.h"
|
12
11
|
#include <brotli/types.h>
|
13
12
|
|
13
|
+
#include "../common/platform.h"
|
14
|
+
|
14
15
|
#if defined(__cplusplus) || defined(c_plusplus)
|
15
16
|
extern "C" {
|
16
17
|
#endif
|
17
18
|
|
19
|
+
const brotli_reg_t kBrotliBitMask[33] = { 0x00000000,
|
20
|
+
0x00000001, 0x00000003, 0x00000007, 0x0000000F,
|
21
|
+
0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
|
22
|
+
0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
|
23
|
+
0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
|
24
|
+
0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
|
25
|
+
0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
|
26
|
+
0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
|
27
|
+
0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
|
28
|
+
};
|
29
|
+
|
18
30
|
void BrotliInitBitReader(BrotliBitReader* const br) {
|
19
31
|
br->val_ = 0;
|
20
|
-
br->bit_pos_ =
|
32
|
+
br->bit_pos_ = 0;
|
21
33
|
}
|
22
34
|
|
23
35
|
BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
|
@@ -25,10 +37,11 @@ BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
|
|
25
37
|
/* Fixing alignment after unaligned BrotliFillWindow would result accumulator
|
26
38
|
overflow. If unalignment is caused by BrotliSafeReadBits, then there is
|
27
39
|
enough space in accumulator to fix alignment. */
|
28
|
-
if (
|
40
|
+
if (BROTLI_UNALIGNED_READ_FAST) {
|
29
41
|
aligned_read_mask = 0;
|
30
42
|
}
|
31
43
|
if (BrotliGetAvailableBits(br) == 0) {
|
44
|
+
br->val_ = 0;
|
32
45
|
if (!BrotliPullByte(br)) {
|
33
46
|
return BROTLI_FALSE;
|
34
47
|
}
|
@@ -43,6 +56,23 @@ BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
|
|
43
56
|
return BROTLI_TRUE;
|
44
57
|
}
|
45
58
|
|
59
|
+
BROTLI_BOOL BrotliSafeReadBits32Slow(BrotliBitReader* const br,
|
60
|
+
brotli_reg_t n_bits, brotli_reg_t* val) {
|
61
|
+
brotli_reg_t low_val;
|
62
|
+
brotli_reg_t high_val;
|
63
|
+
BrotliBitReaderState memento;
|
64
|
+
BROTLI_DCHECK(n_bits <= 32);
|
65
|
+
BROTLI_DCHECK(n_bits > 24);
|
66
|
+
BrotliBitReaderSaveState(br, &memento);
|
67
|
+
if (!BrotliSafeReadBits(br, 16, &low_val) ||
|
68
|
+
!BrotliSafeReadBits(br, n_bits - 16, &high_val)) {
|
69
|
+
BrotliBitReaderRestoreState(br, &memento);
|
70
|
+
return BROTLI_FALSE;
|
71
|
+
}
|
72
|
+
*val = low_val | (high_val << 16);
|
73
|
+
return BROTLI_TRUE;
|
74
|
+
}
|
75
|
+
|
46
76
|
#if defined(__cplusplus) || defined(c_plusplus)
|
47
77
|
} /* extern "C" */
|
48
78
|
#endif
|
@@ -11,66 +11,85 @@
|
|
11
11
|
|
12
12
|
#include <string.h> /* memcpy */
|
13
13
|
|
14
|
-
#include "../common/platform.h"
|
15
14
|
#include <brotli/types.h>
|
16
15
|
|
16
|
+
#include "../common/constants.h"
|
17
|
+
#include "../common/platform.h"
|
18
|
+
|
17
19
|
#if defined(__cplusplus) || defined(c_plusplus)
|
18
20
|
extern "C" {
|
19
21
|
#endif
|
20
22
|
|
21
23
|
#define BROTLI_SHORT_FILL_BIT_WINDOW_READ (sizeof(brotli_reg_t) >> 1)
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
|
30
|
-
0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
|
31
|
-
0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
|
32
|
-
};
|
33
|
-
|
34
|
-
static BROTLI_INLINE uint32_t BitMask(uint32_t n) {
|
25
|
+
/* 162 bits + 7 bytes */
|
26
|
+
#define BROTLI_FAST_INPUT_SLACK 28
|
27
|
+
|
28
|
+
BROTLI_INTERNAL extern const brotli_reg_t kBrotliBitMask[33];
|
29
|
+
|
30
|
+
static BROTLI_INLINE brotli_reg_t BitMask(brotli_reg_t n) {
|
35
31
|
if (BROTLI_IS_CONSTANT(n) || BROTLI_HAS_UBFX) {
|
36
32
|
/* Masking with this expression turns to a single
|
37
33
|
"Unsigned Bit Field Extract" UBFX instruction on ARM. */
|
38
|
-
return ~((
|
34
|
+
return ~(~((brotli_reg_t)0) << n);
|
39
35
|
} else {
|
40
|
-
return
|
36
|
+
return kBrotliBitMask[n];
|
41
37
|
}
|
42
38
|
}
|
43
39
|
|
44
40
|
typedef struct {
|
45
41
|
brotli_reg_t val_; /* pre-fetched bits */
|
46
|
-
|
42
|
+
brotli_reg_t bit_pos_; /* current bit-reading position in val_ */
|
47
43
|
const uint8_t* next_in; /* the byte we're reading from */
|
48
|
-
|
44
|
+
const uint8_t* guard_in; /* position from which "fast-path" is prohibited */
|
45
|
+
const uint8_t* last_in; /* == next_in + avail_in */
|
49
46
|
} BrotliBitReader;
|
50
47
|
|
51
48
|
typedef struct {
|
52
49
|
brotli_reg_t val_;
|
53
|
-
|
50
|
+
brotli_reg_t bit_pos_;
|
54
51
|
const uint8_t* next_in;
|
55
52
|
size_t avail_in;
|
56
53
|
} BrotliBitReaderState;
|
57
54
|
|
58
55
|
/* Initializes the BrotliBitReader fields. */
|
59
|
-
BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader*
|
56
|
+
BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* br);
|
60
57
|
|
61
58
|
/* Ensures that accumulator is not empty.
|
62
59
|
May consume up to sizeof(brotli_reg_t) - 1 bytes of input.
|
63
60
|
Returns BROTLI_FALSE if data is required but there is no input available.
|
64
|
-
For
|
65
|
-
reading. */
|
66
|
-
BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader*
|
61
|
+
For !BROTLI_UNALIGNED_READ_FAST this function also prepares bit reader for
|
62
|
+
aligned reading. */
|
63
|
+
BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* br);
|
64
|
+
|
65
|
+
/* Fallback for BrotliSafeReadBits32. Extracted as noninlined method to unburden
|
66
|
+
the main code-path. Never called for RFC brotli streams, required only for
|
67
|
+
"large-window" mode and other extensions. */
|
68
|
+
BROTLI_INTERNAL BROTLI_NOINLINE BROTLI_BOOL BrotliSafeReadBits32Slow(
|
69
|
+
BrotliBitReader* br, brotli_reg_t n_bits, brotli_reg_t* val);
|
70
|
+
|
71
|
+
static BROTLI_INLINE size_t
|
72
|
+
BrotliBitReaderGetAvailIn(BrotliBitReader* const br) {
|
73
|
+
return (size_t)(br->last_in - br->next_in);
|
74
|
+
}
|
67
75
|
|
68
76
|
static BROTLI_INLINE void BrotliBitReaderSaveState(
|
69
77
|
BrotliBitReader* const from, BrotliBitReaderState* to) {
|
70
78
|
to->val_ = from->val_;
|
71
79
|
to->bit_pos_ = from->bit_pos_;
|
72
80
|
to->next_in = from->next_in;
|
73
|
-
to->avail_in = from
|
81
|
+
to->avail_in = BrotliBitReaderGetAvailIn(from);
|
82
|
+
}
|
83
|
+
|
84
|
+
static BROTLI_INLINE void BrotliBitReaderSetInput(
|
85
|
+
BrotliBitReader* const br, const uint8_t* next_in, size_t avail_in) {
|
86
|
+
br->next_in = next_in;
|
87
|
+
br->last_in = (avail_in == 0) ? next_in : (next_in + avail_in);
|
88
|
+
if (avail_in + 1 > BROTLI_FAST_INPUT_SLACK) {
|
89
|
+
br->guard_in = next_in + (avail_in + 1 - BROTLI_FAST_INPUT_SLACK);
|
90
|
+
} else {
|
91
|
+
br->guard_in = next_in;
|
92
|
+
}
|
74
93
|
}
|
75
94
|
|
76
95
|
static BROTLI_INLINE void BrotliBitReaderRestoreState(
|
@@ -78,25 +97,40 @@ static BROTLI_INLINE void BrotliBitReaderRestoreState(
|
|
78
97
|
to->val_ = from->val_;
|
79
98
|
to->bit_pos_ = from->bit_pos_;
|
80
99
|
to->next_in = from->next_in;
|
81
|
-
to->
|
100
|
+
BrotliBitReaderSetInput(to, from->next_in, from->avail_in);
|
82
101
|
}
|
83
102
|
|
84
|
-
static BROTLI_INLINE
|
103
|
+
static BROTLI_INLINE brotli_reg_t BrotliGetAvailableBits(
|
85
104
|
const BrotliBitReader* br) {
|
86
|
-
return
|
105
|
+
return br->bit_pos_;
|
87
106
|
}
|
88
107
|
|
89
108
|
/* Returns amount of unread bytes the bit reader still has buffered from the
|
90
|
-
BrotliInput, including whole bytes in br->val_.
|
109
|
+
BrotliInput, including whole bytes in br->val_. Result is capped with
|
110
|
+
maximal ring-buffer size (larger number won't be utilized anyway). */
|
91
111
|
static BROTLI_INLINE size_t BrotliGetRemainingBytes(BrotliBitReader* br) {
|
92
|
-
|
112
|
+
static const size_t kCap = (size_t)1 << BROTLI_LARGE_MAX_WBITS;
|
113
|
+
size_t avail_in = BrotliBitReaderGetAvailIn(br);
|
114
|
+
if (avail_in > kCap) return kCap;
|
115
|
+
return avail_in + (BrotliGetAvailableBits(br) >> 3);
|
93
116
|
}
|
94
117
|
|
95
118
|
/* Checks if there is at least |num| bytes left in the input ring-buffer
|
96
119
|
(excluding the bits remaining in br->val_). */
|
97
120
|
static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount(
|
98
|
-
BrotliBitReader* const br
|
99
|
-
return TO_BROTLI_BOOL(br->
|
121
|
+
BrotliBitReader* const br) {
|
122
|
+
return TO_BROTLI_BOOL(br->next_in < br->guard_in);
|
123
|
+
}
|
124
|
+
|
125
|
+
/* Load more bits into accumulator. */
|
126
|
+
static BROTLI_INLINE brotli_reg_t BrotliBitReaderLoadBits(brotli_reg_t val,
|
127
|
+
brotli_reg_t new_bits,
|
128
|
+
brotli_reg_t count,
|
129
|
+
brotli_reg_t offset) {
|
130
|
+
BROTLI_DCHECK(
|
131
|
+
!((val >> offset) & ~new_bits & ~(~((brotli_reg_t)0) << count)));
|
132
|
+
(void)count;
|
133
|
+
return val | (new_bits << offset);
|
100
134
|
}
|
101
135
|
|
102
136
|
/* Guarantees that there are at least |n_bits| + 1 bits in accumulator.
|
@@ -104,49 +138,51 @@ static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount(
|
|
104
138
|
|n_bits| should be in the range [1..24] for regular build. For portable
|
105
139
|
non-64-bit little-endian build only 16 bits are safe to request. */
|
106
140
|
static BROTLI_INLINE void BrotliFillBitWindow(
|
107
|
-
BrotliBitReader* const br,
|
141
|
+
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
108
142
|
#if (BROTLI_64_BITS)
|
109
|
-
if (
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
br->val_
|
114
|
-
|
143
|
+
if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
|
144
|
+
(n_bits <= 8)) {
|
145
|
+
brotli_reg_t bit_pos = br->bit_pos_;
|
146
|
+
if (bit_pos <= 8) {
|
147
|
+
br->val_ = BrotliBitReaderLoadBits(br->val_,
|
148
|
+
BROTLI_UNALIGNED_LOAD64LE(br->next_in), 56, bit_pos);
|
149
|
+
br->bit_pos_ = bit_pos + 56;
|
115
150
|
br->next_in += 7;
|
116
151
|
}
|
117
|
-
} else if (
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
br->
|
122
|
-
|
123
|
-
br->
|
152
|
+
} else if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
|
153
|
+
(n_bits <= 16)) {
|
154
|
+
brotli_reg_t bit_pos = br->bit_pos_;
|
155
|
+
if (bit_pos <= 16) {
|
156
|
+
br->val_ = BrotliBitReaderLoadBits(br->val_,
|
157
|
+
BROTLI_UNALIGNED_LOAD64LE(br->next_in), 48, bit_pos);
|
158
|
+
br->bit_pos_ = bit_pos + 48;
|
124
159
|
br->next_in += 6;
|
125
160
|
}
|
126
161
|
} else {
|
127
|
-
|
128
|
-
|
129
|
-
br->
|
130
|
-
|
131
|
-
br->
|
162
|
+
brotli_reg_t bit_pos = br->bit_pos_;
|
163
|
+
if (bit_pos <= 32) {
|
164
|
+
br->val_ = BrotliBitReaderLoadBits(br->val_,
|
165
|
+
(uint64_t)BROTLI_UNALIGNED_LOAD32LE(br->next_in), 32, bit_pos);
|
166
|
+
br->bit_pos_ = bit_pos + 32;
|
132
167
|
br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
|
133
168
|
}
|
134
169
|
}
|
135
170
|
#else
|
136
|
-
if (
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
br->val_
|
141
|
-
|
171
|
+
if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
|
172
|
+
(n_bits <= 8)) {
|
173
|
+
brotli_reg_t bit_pos = br->bit_pos_;
|
174
|
+
if (bit_pos <= 8) {
|
175
|
+
br->val_ = BrotliBitReaderLoadBits(br->val_,
|
176
|
+
BROTLI_UNALIGNED_LOAD32LE(br->next_in), 24, bit_pos);
|
177
|
+
br->bit_pos_ = bit_pos + 24;
|
142
178
|
br->next_in += 3;
|
143
179
|
}
|
144
180
|
} else {
|
145
|
-
|
146
|
-
|
147
|
-
br->
|
148
|
-
|
149
|
-
br->
|
181
|
+
brotli_reg_t bit_pos = br->bit_pos_;
|
182
|
+
if (bit_pos <= 16) {
|
183
|
+
br->val_ = BrotliBitReaderLoadBits(br->val_,
|
184
|
+
(uint32_t)BROTLI_UNALIGNED_LOAD16LE(br->next_in), 16, bit_pos);
|
185
|
+
br->bit_pos_ = bit_pos + 16;
|
150
186
|
br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
|
151
187
|
}
|
152
188
|
}
|
@@ -162,17 +198,12 @@ static BROTLI_INLINE void BrotliFillBitWindow16(BrotliBitReader* const br) {
|
|
162
198
|
/* Tries to pull one byte of input to accumulator.
|
163
199
|
Returns BROTLI_FALSE if there is no input available. */
|
164
200
|
static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) {
|
165
|
-
if (br->
|
201
|
+
if (br->next_in == br->last_in) {
|
166
202
|
return BROTLI_FALSE;
|
167
203
|
}
|
168
|
-
br->val_
|
169
|
-
|
170
|
-
br->
|
171
|
-
#else
|
172
|
-
br->val_ |= ((uint32_t)*br->next_in) << 24;
|
173
|
-
#endif
|
174
|
-
br->bit_pos_ -= 8;
|
175
|
-
--br->avail_in;
|
204
|
+
br->val_ = BrotliBitReaderLoadBits(br->val_,
|
205
|
+
(brotli_reg_t)*br->next_in, 8, br->bit_pos_);
|
206
|
+
br->bit_pos_ += 8;
|
176
207
|
++br->next_in;
|
177
208
|
return BROTLI_TRUE;
|
178
209
|
}
|
@@ -181,79 +212,90 @@ static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) {
|
|
181
212
|
The number of valid bits could be calculated by BrotliGetAvailableBits. */
|
182
213
|
static BROTLI_INLINE brotli_reg_t BrotliGetBitsUnmasked(
|
183
214
|
BrotliBitReader* const br) {
|
184
|
-
return br->val_
|
215
|
+
return br->val_;
|
185
216
|
}
|
186
217
|
|
187
218
|
/* Like BrotliGetBits, but does not mask the result.
|
188
219
|
The result contains at least 16 valid bits. */
|
189
|
-
static BROTLI_INLINE
|
220
|
+
static BROTLI_INLINE brotli_reg_t BrotliGet16BitsUnmasked(
|
190
221
|
BrotliBitReader* const br) {
|
191
222
|
BrotliFillBitWindow(br, 16);
|
192
|
-
return (
|
223
|
+
return (brotli_reg_t)BrotliGetBitsUnmasked(br);
|
193
224
|
}
|
194
225
|
|
195
226
|
/* Returns the specified number of bits from |br| without advancing bit
|
196
227
|
position. */
|
197
|
-
static BROTLI_INLINE
|
198
|
-
BrotliBitReader* const br,
|
228
|
+
static BROTLI_INLINE brotli_reg_t BrotliGetBits(
|
229
|
+
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
199
230
|
BrotliFillBitWindow(br, n_bits);
|
200
|
-
return
|
231
|
+
return BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
201
232
|
}
|
202
233
|
|
203
234
|
/* Tries to peek the specified amount of bits. Returns BROTLI_FALSE, if there
|
204
235
|
is not enough input. */
|
205
236
|
static BROTLI_INLINE BROTLI_BOOL BrotliSafeGetBits(
|
206
|
-
BrotliBitReader* const br,
|
237
|
+
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
207
238
|
while (BrotliGetAvailableBits(br) < n_bits) {
|
208
239
|
if (!BrotliPullByte(br)) {
|
209
240
|
return BROTLI_FALSE;
|
210
241
|
}
|
211
242
|
}
|
212
|
-
*val =
|
243
|
+
*val = BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
213
244
|
return BROTLI_TRUE;
|
214
245
|
}
|
215
246
|
|
216
247
|
/* Advances the bit pos by |n_bits|. */
|
217
248
|
static BROTLI_INLINE void BrotliDropBits(
|
218
|
-
BrotliBitReader* const br,
|
219
|
-
br->bit_pos_
|
249
|
+
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
250
|
+
br->bit_pos_ -= n_bits;
|
251
|
+
br->val_ >>= n_bits;
|
220
252
|
}
|
221
253
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
br->
|
227
|
-
if (
|
228
|
-
br->val_
|
229
|
-
} else {
|
230
|
-
br->val_ <<= unused_bits;
|
254
|
+
/* Make sure that there are no spectre bits in accumulator.
|
255
|
+
This is important for the cases when some bytes are skipped
|
256
|
+
(i.e. never placed into accumulator). */
|
257
|
+
static BROTLI_INLINE void BrotliBitReaderNormalize(BrotliBitReader* br) {
|
258
|
+
/* Actually, it is enough to normalize when br->bit_pos_ == 0 */
|
259
|
+
if (br->bit_pos_ < (sizeof(brotli_reg_t) << 3u)) {
|
260
|
+
br->val_ &= (((brotli_reg_t)1) << br->bit_pos_) - 1;
|
231
261
|
}
|
232
|
-
|
262
|
+
}
|
263
|
+
|
264
|
+
static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) {
|
265
|
+
brotli_reg_t unused_bytes = BrotliGetAvailableBits(br) >> 3;
|
266
|
+
brotli_reg_t unused_bits = unused_bytes << 3;
|
267
|
+
br->next_in =
|
268
|
+
(unused_bytes == 0) ? br->next_in : (br->next_in - unused_bytes);
|
269
|
+
br->bit_pos_ -= unused_bits;
|
270
|
+
BrotliBitReaderNormalize(br);
|
233
271
|
}
|
234
272
|
|
235
273
|
/* Reads the specified number of bits from |br| and advances the bit pos.
|
236
274
|
Precondition: accumulator MUST contain at least |n_bits|. */
|
237
|
-
static BROTLI_INLINE void BrotliTakeBits(
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
275
|
+
static BROTLI_INLINE void BrotliTakeBits(BrotliBitReader* const br,
|
276
|
+
brotli_reg_t n_bits,
|
277
|
+
brotli_reg_t* val) {
|
278
|
+
*val = BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
279
|
+
BROTLI_LOG(("[BrotliTakeBits] %d %d %d val: %6x\n",
|
280
|
+
(int)BrotliBitReaderGetAvailIn(br), (int)br->bit_pos_,
|
281
|
+
(int)n_bits, (int)*val));
|
242
282
|
BrotliDropBits(br, n_bits);
|
243
283
|
}
|
244
284
|
|
245
285
|
/* Reads the specified number of bits from |br| and advances the bit pos.
|
246
|
-
Assumes that there is enough input to perform BrotliFillBitWindow.
|
247
|
-
|
248
|
-
|
286
|
+
Assumes that there is enough input to perform BrotliFillBitWindow.
|
287
|
+
Up to 24 bits are allowed to be requested from this method. */
|
288
|
+
static BROTLI_INLINE brotli_reg_t BrotliReadBits24(
|
289
|
+
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
290
|
+
BROTLI_DCHECK(n_bits <= 24);
|
249
291
|
if (BROTLI_64_BITS || (n_bits <= 16)) {
|
250
|
-
|
292
|
+
brotli_reg_t val;
|
251
293
|
BrotliFillBitWindow(br, n_bits);
|
252
294
|
BrotliTakeBits(br, n_bits, &val);
|
253
295
|
return val;
|
254
296
|
} else {
|
255
|
-
|
256
|
-
|
297
|
+
brotli_reg_t low_val;
|
298
|
+
brotli_reg_t high_val;
|
257
299
|
BrotliFillBitWindow(br, 16);
|
258
300
|
BrotliTakeBits(br, 16, &low_val);
|
259
301
|
BrotliFillBitWindow(br, 8);
|
@@ -262,10 +304,32 @@ static BROTLI_INLINE uint32_t BrotliReadBits(
|
|
262
304
|
}
|
263
305
|
}
|
264
306
|
|
307
|
+
/* Same as BrotliReadBits24, but allows reading up to 32 bits. */
|
308
|
+
static BROTLI_INLINE brotli_reg_t BrotliReadBits32(
|
309
|
+
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
310
|
+
BROTLI_DCHECK(n_bits <= 32);
|
311
|
+
if (BROTLI_64_BITS || (n_bits <= 16)) {
|
312
|
+
brotli_reg_t val;
|
313
|
+
BrotliFillBitWindow(br, n_bits);
|
314
|
+
BrotliTakeBits(br, n_bits, &val);
|
315
|
+
return val;
|
316
|
+
} else {
|
317
|
+
brotli_reg_t low_val;
|
318
|
+
brotli_reg_t high_val;
|
319
|
+
BrotliFillBitWindow(br, 16);
|
320
|
+
BrotliTakeBits(br, 16, &low_val);
|
321
|
+
BrotliFillBitWindow(br, 16);
|
322
|
+
BrotliTakeBits(br, n_bits - 16, &high_val);
|
323
|
+
return low_val | (high_val << 16);
|
324
|
+
}
|
325
|
+
}
|
326
|
+
|
265
327
|
/* Tries to read the specified amount of bits. Returns BROTLI_FALSE, if there
|
266
|
-
is not enough input. |n_bits| MUST be positive.
|
328
|
+
is not enough input. |n_bits| MUST be positive.
|
329
|
+
Up to 24 bits are allowed to be requested from this method. */
|
267
330
|
static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
|
268
|
-
BrotliBitReader* const br,
|
331
|
+
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
332
|
+
BROTLI_DCHECK(n_bits <= 24);
|
269
333
|
while (BrotliGetAvailableBits(br) < n_bits) {
|
270
334
|
if (!BrotliPullByte(br)) {
|
271
335
|
return BROTLI_FALSE;
|
@@ -275,17 +339,42 @@ static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
|
|
275
339
|
return BROTLI_TRUE;
|
276
340
|
}
|
277
341
|
|
342
|
+
/* Same as BrotliSafeReadBits, but allows reading up to 32 bits. */
|
343
|
+
static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits32(
|
344
|
+
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
345
|
+
BROTLI_DCHECK(n_bits <= 32);
|
346
|
+
if (BROTLI_64_BITS || (n_bits <= 24)) {
|
347
|
+
while (BrotliGetAvailableBits(br) < n_bits) {
|
348
|
+
if (!BrotliPullByte(br)) {
|
349
|
+
return BROTLI_FALSE;
|
350
|
+
}
|
351
|
+
}
|
352
|
+
BrotliTakeBits(br, n_bits, val);
|
353
|
+
return BROTLI_TRUE;
|
354
|
+
} else {
|
355
|
+
return BrotliSafeReadBits32Slow(br, n_bits, val);
|
356
|
+
}
|
357
|
+
}
|
358
|
+
|
278
359
|
/* Advances the bit reader position to the next byte boundary and verifies
|
279
360
|
that any skipped bits are set to zero. */
|
280
361
|
static BROTLI_INLINE BROTLI_BOOL BrotliJumpToByteBoundary(BrotliBitReader* br) {
|
281
|
-
|
282
|
-
|
362
|
+
brotli_reg_t pad_bits_count = BrotliGetAvailableBits(br) & 0x7;
|
363
|
+
brotli_reg_t pad_bits = 0;
|
283
364
|
if (pad_bits_count != 0) {
|
284
365
|
BrotliTakeBits(br, pad_bits_count, &pad_bits);
|
285
366
|
}
|
367
|
+
BrotliBitReaderNormalize(br);
|
286
368
|
return TO_BROTLI_BOOL(pad_bits == 0);
|
287
369
|
}
|
288
370
|
|
371
|
+
static BROTLI_INLINE void BrotliDropBytes(BrotliBitReader* br, size_t num) {
|
372
|
+
/* Check detour is legal: accumulator must to be empty. */
|
373
|
+
BROTLI_DCHECK(br->bit_pos_ == 0);
|
374
|
+
BROTLI_DCHECK(br->val_ == 0);
|
375
|
+
br->next_in += num;
|
376
|
+
}
|
377
|
+
|
289
378
|
/* Copies remaining input bytes stored in the bit reader to the output. Value
|
290
379
|
|num| may not be larger than BrotliGetRemainingBytes. The bit reader must be
|
291
380
|
warmed up again after this. */
|
@@ -297,9 +386,34 @@ static BROTLI_INLINE void BrotliCopyBytes(uint8_t* dest,
|
|
297
386
|
++dest;
|
298
387
|
--num;
|
299
388
|
}
|
300
|
-
|
301
|
-
|
302
|
-
|
389
|
+
BrotliBitReaderNormalize(br);
|
390
|
+
if (num > 0) {
|
391
|
+
memcpy(dest, br->next_in, num);
|
392
|
+
BrotliDropBytes(br, num);
|
393
|
+
}
|
394
|
+
}
|
395
|
+
|
396
|
+
BROTLI_UNUSED_FUNCTION void BrotliBitReaderSuppressUnusedFunctions(void) {
|
397
|
+
BROTLI_UNUSED(&BrotliBitReaderSuppressUnusedFunctions);
|
398
|
+
|
399
|
+
BROTLI_UNUSED(&BrotliBitReaderGetAvailIn);
|
400
|
+
BROTLI_UNUSED(&BrotliBitReaderLoadBits);
|
401
|
+
BROTLI_UNUSED(&BrotliBitReaderRestoreState);
|
402
|
+
BROTLI_UNUSED(&BrotliBitReaderSaveState);
|
403
|
+
BROTLI_UNUSED(&BrotliBitReaderSetInput);
|
404
|
+
BROTLI_UNUSED(&BrotliBitReaderUnload);
|
405
|
+
BROTLI_UNUSED(&BrotliCheckInputAmount);
|
406
|
+
BROTLI_UNUSED(&BrotliCopyBytes);
|
407
|
+
BROTLI_UNUSED(&BrotliFillBitWindow16);
|
408
|
+
BROTLI_UNUSED(&BrotliGet16BitsUnmasked);
|
409
|
+
BROTLI_UNUSED(&BrotliGetBits);
|
410
|
+
BROTLI_UNUSED(&BrotliGetRemainingBytes);
|
411
|
+
BROTLI_UNUSED(&BrotliJumpToByteBoundary);
|
412
|
+
BROTLI_UNUSED(&BrotliReadBits24);
|
413
|
+
BROTLI_UNUSED(&BrotliReadBits32);
|
414
|
+
BROTLI_UNUSED(&BrotliSafeGetBits);
|
415
|
+
BROTLI_UNUSED(&BrotliSafeReadBits);
|
416
|
+
BROTLI_UNUSED(&BrotliSafeReadBits32);
|
303
417
|
}
|
304
418
|
|
305
419
|
#if defined(__cplusplus) || defined(c_plusplus)
|