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.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +37 -0
  3. data/.github/workflows/publish.yml +24 -0
  4. data/.gitmodules +1 -1
  5. data/Gemfile +6 -3
  6. data/README.md +2 -2
  7. data/Rakefile +16 -9
  8. data/brotli.gemspec +7 -13
  9. data/ext/brotli/brotli.c +210 -31
  10. data/ext/brotli/buffer.c +1 -7
  11. data/ext/brotli/buffer.h +1 -1
  12. data/ext/brotli/extconf.rb +25 -17
  13. data/lib/brotli/version.rb +1 -1
  14. data/test/brotli_test.rb +107 -0
  15. data/test/brotli_writer_test.rb +36 -0
  16. data/test/test_helper.rb +8 -0
  17. data/vendor/brotli/c/common/constants.c +15 -0
  18. data/vendor/brotli/c/common/constants.h +137 -0
  19. data/vendor/brotli/c/common/context.c +156 -0
  20. data/vendor/brotli/c/common/context.h +4 -152
  21. data/vendor/brotli/c/common/dictionary.bin.br +0 -0
  22. data/vendor/brotli/c/common/dictionary.c +14 -3
  23. data/vendor/brotli/c/common/platform.c +23 -0
  24. data/vendor/brotli/c/common/platform.h +95 -122
  25. data/vendor/brotli/c/common/shared_dictionary.c +521 -0
  26. data/vendor/brotli/c/common/shared_dictionary_internal.h +75 -0
  27. data/vendor/brotli/c/common/transform.c +60 -4
  28. data/vendor/brotli/c/common/transform.h +5 -0
  29. data/vendor/brotli/c/common/version.h +31 -6
  30. data/vendor/brotli/c/dec/bit_reader.c +34 -4
  31. data/vendor/brotli/c/dec/bit_reader.h +221 -107
  32. data/vendor/brotli/c/dec/decode.c +772 -403
  33. data/vendor/brotli/c/dec/huffman.c +7 -4
  34. data/vendor/brotli/c/dec/huffman.h +8 -13
  35. data/vendor/brotli/c/dec/prefix.h +1 -18
  36. data/vendor/brotli/c/dec/state.c +40 -21
  37. data/vendor/brotli/c/dec/state.h +201 -59
  38. data/vendor/brotli/c/enc/backward_references.c +88 -25
  39. data/vendor/brotli/c/enc/backward_references.h +10 -8
  40. data/vendor/brotli/c/enc/backward_references_hq.c +194 -80
  41. data/vendor/brotli/c/enc/backward_references_hq.h +17 -13
  42. data/vendor/brotli/c/enc/backward_references_inc.h +52 -16
  43. data/vendor/brotli/c/enc/bit_cost.c +8 -7
  44. data/vendor/brotli/c/enc/bit_cost.h +5 -4
  45. data/vendor/brotli/c/enc/block_splitter.c +40 -17
  46. data/vendor/brotli/c/enc/block_splitter.h +5 -4
  47. data/vendor/brotli/c/enc/block_splitter_inc.h +99 -49
  48. data/vendor/brotli/c/enc/brotli_bit_stream.c +142 -137
  49. data/vendor/brotli/c/enc/brotli_bit_stream.h +11 -6
  50. data/vendor/brotli/c/enc/cluster.c +10 -9
  51. data/vendor/brotli/c/enc/cluster.h +7 -6
  52. data/vendor/brotli/c/enc/cluster_inc.h +30 -22
  53. data/vendor/brotli/c/enc/command.c +28 -0
  54. data/vendor/brotli/c/enc/command.h +17 -16
  55. data/vendor/brotli/c/enc/compound_dictionary.c +207 -0
  56. data/vendor/brotli/c/enc/compound_dictionary.h +74 -0
  57. data/vendor/brotli/c/enc/compress_fragment.c +93 -83
  58. data/vendor/brotli/c/enc/compress_fragment.h +32 -7
  59. data/vendor/brotli/c/enc/compress_fragment_two_pass.c +100 -88
  60. data/vendor/brotli/c/enc/compress_fragment_two_pass.h +21 -3
  61. data/vendor/brotli/c/enc/dictionary_hash.c +1829 -1101
  62. data/vendor/brotli/c/enc/dictionary_hash.h +2 -1
  63. data/vendor/brotli/c/enc/encode.c +550 -416
  64. data/vendor/brotli/c/enc/encoder_dict.c +613 -5
  65. data/vendor/brotli/c/enc/encoder_dict.h +120 -4
  66. data/vendor/brotli/c/enc/entropy_encode.c +5 -2
  67. data/vendor/brotli/c/enc/entropy_encode.h +4 -3
  68. data/vendor/brotli/c/enc/entropy_encode_static.h +5 -2
  69. data/vendor/brotli/c/enc/fast_log.c +105 -0
  70. data/vendor/brotli/c/enc/fast_log.h +21 -101
  71. data/vendor/brotli/c/enc/find_match_length.h +17 -25
  72. data/vendor/brotli/c/enc/hash.h +350 -120
  73. data/vendor/brotli/c/enc/hash_composite_inc.h +71 -67
  74. data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +92 -51
  75. data/vendor/brotli/c/enc/hash_longest_match64_inc.h +79 -84
  76. data/vendor/brotli/c/enc/hash_longest_match_inc.h +53 -54
  77. data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +93 -62
  78. data/vendor/brotli/c/enc/hash_rolling_inc.h +25 -29
  79. data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +42 -40
  80. data/vendor/brotli/c/enc/histogram.c +4 -4
  81. data/vendor/brotli/c/enc/histogram.h +7 -6
  82. data/vendor/brotli/c/enc/literal_cost.c +20 -15
  83. data/vendor/brotli/c/enc/literal_cost.h +4 -2
  84. data/vendor/brotli/c/enc/memory.c +29 -5
  85. data/vendor/brotli/c/enc/memory.h +43 -14
  86. data/vendor/brotli/c/enc/metablock.c +95 -85
  87. data/vendor/brotli/c/enc/metablock.h +9 -8
  88. data/vendor/brotli/c/enc/metablock_inc.h +9 -7
  89. data/vendor/brotli/c/enc/params.h +7 -4
  90. data/vendor/brotli/c/enc/prefix.h +3 -2
  91. data/vendor/brotli/c/enc/quality.h +40 -3
  92. data/vendor/brotli/c/enc/ringbuffer.h +8 -4
  93. data/vendor/brotli/c/enc/state.h +104 -0
  94. data/vendor/brotli/c/enc/static_dict.c +60 -4
  95. data/vendor/brotli/c/enc/static_dict.h +3 -2
  96. data/vendor/brotli/c/enc/static_dict_lut.h +2 -0
  97. data/vendor/brotli/c/enc/utf8_util.c +2 -2
  98. data/vendor/brotli/c/enc/utf8_util.h +2 -1
  99. data/vendor/brotli/c/enc/write_bits.h +29 -26
  100. data/vendor/brotli/c/include/brotli/decode.h +67 -2
  101. data/vendor/brotli/c/include/brotli/encode.h +77 -3
  102. data/vendor/brotli/c/include/brotli/port.h +34 -3
  103. data/vendor/brotli/c/include/brotli/shared_dictionary.h +100 -0
  104. metadata +23 -97
  105. data/.travis.yml +0 -31
  106. data/docs/Brotli/Error.html +0 -124
  107. data/docs/Brotli.html +0 -485
  108. data/docs/_index.html +0 -122
  109. data/docs/class_list.html +0 -51
  110. data/docs/css/common.css +0 -1
  111. data/docs/css/full_list.css +0 -58
  112. data/docs/css/style.css +0 -496
  113. data/docs/file.README.html +0 -127
  114. data/docs/file_list.html +0 -56
  115. data/docs/frames.html +0 -17
  116. data/docs/index.html +0 -127
  117. data/docs/js/app.js +0 -292
  118. data/docs/js/full_list.js +0 -216
  119. data/docs/js/jquery.js +0 -4
  120. data/docs/method_list.html +0 -67
  121. data/docs/top-level-namespace.html +0 -110
  122. data/spec/brotli_spec.rb +0 -88
  123. data/spec/inflate_spec.rb +0 -75
  124. 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
- /* This macro should only be used when library is compiled together with client.
13
- If library is dynamically linked, use BrotliDecoderVersion and
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
- /* Semantic version, calculated as (MAJOR << 24) | (MINOR << 12) | PATCH */
17
- #define BROTLI_VERSION 0x1000007
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
- /* ABI version, calculated as (CURRENT << 24) | (REVISION << 12) | AGE */
24
- #define BROTLI_ABI_VERSION 0x1007000
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 "./bit_reader.h"
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_ = sizeof(br->val_) << 3;
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 (!BROTLI_ALIGNED_READ) {
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
- static const uint32_t kBitMask[33] = { 0x00000000,
24
- 0x00000001, 0x00000003, 0x00000007, 0x0000000F,
25
- 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
26
- 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
27
- 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
28
- 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
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 ~((0xFFFFFFFFu) << n);
34
+ return ~(~((brotli_reg_t)0) << n);
39
35
  } else {
40
- return kBitMask[n];
36
+ return kBrotliBitMask[n];
41
37
  }
42
38
  }
43
39
 
44
40
  typedef struct {
45
41
  brotli_reg_t val_; /* pre-fetched bits */
46
- uint32_t bit_pos_; /* current bit-reading position in val_ */
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
- size_t avail_in;
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
- uint32_t bit_pos_;
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* const br);
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 BROTLI_ALIGNED_READ this function also prepares bit reader for aligned
65
- reading. */
66
- BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br);
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->avail_in;
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->avail_in = from->avail_in;
100
+ BrotliBitReaderSetInput(to, from->next_in, from->avail_in);
82
101
  }
83
102
 
84
- static BROTLI_INLINE uint32_t BrotliGetAvailableBits(
103
+ static BROTLI_INLINE brotli_reg_t BrotliGetAvailableBits(
85
104
  const BrotliBitReader* br) {
86
- return (BROTLI_64_BITS ? 64 : 32) - br->bit_pos_;
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
- return br->avail_in + (BrotliGetAvailableBits(br) >> 3);
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, size_t num) {
99
- return TO_BROTLI_BOOL(br->avail_in >= num);
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, uint32_t n_bits) {
141
+ BrotliBitReader* const br, brotli_reg_t n_bits) {
108
142
  #if (BROTLI_64_BITS)
109
- if (!BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 8)) {
110
- if (br->bit_pos_ >= 56) {
111
- br->val_ >>= 56;
112
- br->bit_pos_ ^= 56; /* here same as -= 56 because of the if condition */
113
- br->val_ |= BROTLI_UNALIGNED_LOAD64LE(br->next_in) << 8;
114
- br->avail_in -= 7;
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
- !BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 16)) {
119
- if (br->bit_pos_ >= 48) {
120
- br->val_ >>= 48;
121
- br->bit_pos_ ^= 48; /* here same as -= 48 because of the if condition */
122
- br->val_ |= BROTLI_UNALIGNED_LOAD64LE(br->next_in) << 16;
123
- br->avail_in -= 6;
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
- if (br->bit_pos_ >= 32) {
128
- br->val_ >>= 32;
129
- br->bit_pos_ ^= 32; /* here same as -= 32 because of the if condition */
130
- br->val_ |= ((uint64_t)BROTLI_UNALIGNED_LOAD32LE(br->next_in)) << 32;
131
- br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
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 (!BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 8)) {
137
- if (br->bit_pos_ >= 24) {
138
- br->val_ >>= 24;
139
- br->bit_pos_ ^= 24; /* here same as -= 24 because of the if condition */
140
- br->val_ |= BROTLI_UNALIGNED_LOAD32LE(br->next_in) << 8;
141
- br->avail_in -= 3;
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
- if (br->bit_pos_ >= 16) {
146
- br->val_ >>= 16;
147
- br->bit_pos_ ^= 16; /* here same as -= 16 because of the if condition */
148
- br->val_ |= ((uint32_t)BROTLI_UNALIGNED_LOAD16LE(br->next_in)) << 16;
149
- br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
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->avail_in == 0) {
201
+ if (br->next_in == br->last_in) {
166
202
  return BROTLI_FALSE;
167
203
  }
168
- br->val_ >>= 8;
169
- #if (BROTLI_64_BITS)
170
- br->val_ |= ((uint64_t)*br->next_in) << 56;
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_ >> br->bit_pos_;
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 uint32_t BrotliGet16BitsUnmasked(
220
+ static BROTLI_INLINE brotli_reg_t BrotliGet16BitsUnmasked(
190
221
  BrotliBitReader* const br) {
191
222
  BrotliFillBitWindow(br, 16);
192
- return (uint32_t)BrotliGetBitsUnmasked(br);
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 uint32_t BrotliGetBits(
198
- BrotliBitReader* const br, uint32_t n_bits) {
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 (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
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, uint32_t n_bits, uint32_t* val) {
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 = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
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, uint32_t n_bits) {
219
- br->bit_pos_ += n_bits;
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
- static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) {
223
- uint32_t unused_bytes = BrotliGetAvailableBits(br) >> 3;
224
- uint32_t unused_bits = unused_bytes << 3;
225
- br->avail_in += unused_bytes;
226
- br->next_in -= unused_bytes;
227
- if (unused_bits == sizeof(br->val_) << 3) {
228
- br->val_ = 0;
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
- br->bit_pos_ += unused_bits;
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
- BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
239
- *val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
240
- BROTLI_LOG(("[BrotliReadBits] %d %d %d val: %6x\n",
241
- (int)br->avail_in, (int)br->bit_pos_, (int)n_bits, (int)*val));
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
- static BROTLI_INLINE uint32_t BrotliReadBits(
248
- BrotliBitReader* const br, uint32_t n_bits) {
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
- uint32_t val;
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
- uint32_t low_val;
256
- uint32_t high_val;
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, uint32_t n_bits, uint32_t* val) {
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
- uint32_t pad_bits_count = BrotliGetAvailableBits(br) & 0x7;
282
- uint32_t pad_bits = 0;
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
- memcpy(dest, br->next_in, num);
301
- br->avail_in -= num;
302
- br->next_in += num;
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)