brotli 0.2.1 → 0.2.2
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/.travis.yml +1 -4
- data/lib/brotli/version.rb +1 -1
- data/vendor/brotli/c/common/platform.h +70 -11
- data/vendor/brotli/c/common/transform.c +4 -4
- data/vendor/brotli/c/common/version.h +2 -2
- data/vendor/brotli/c/dec/decode.c +50 -41
- data/vendor/brotli/c/dec/huffman.c +30 -47
- data/vendor/brotli/c/dec/huffman.h +55 -0
- data/vendor/brotli/c/enc/backward_references_hq.c +50 -55
- data/vendor/brotli/c/enc/backward_references_hq.h +6 -7
- data/vendor/brotli/c/enc/backward_references_inc.h +9 -9
- data/vendor/brotli/c/enc/encode.c +16 -18
- data/vendor/brotli/c/enc/hash.h +5 -4
- data/vendor/brotli/c/enc/hash_composite_inc.h +7 -4
- data/vendor/brotli/c/enc/hash_longest_match64_inc.h +3 -2
- data/vendor/brotli/c/enc/hash_longest_match_inc.h +3 -2
- data/vendor/brotli/c/enc/hash_rolling_inc.h +3 -2
- data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +3 -2
- data/vendor/brotli/c/enc/metablock.c +2 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81b3e01265c409832de742771d83abbfa21c0445a0ad3fa44d8ae646998786d5
|
4
|
+
data.tar.gz: 79d4545e4c507a0ef774412c005fe8ac999a31457347fbea31e21533c194b0ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9380345b150e5d8e2de3d9c58e4a1b5e6e4ac293f247c9a86caf5b9d1e9026b9b3a89d91254d91edf12212e553fe979894c1a01d6e0d1bfbf5cb1fd37571a7af
|
7
|
+
data.tar.gz: 64bb2538e6d712929a8fdfb2511f612b638c0f33d47eb38b973c9a26876e8ed44642ab1198dcc9f92614716e2b2d5b519705287897dca3ecd66e102d21a41b4e
|
data/.travis.yml
CHANGED
@@ -9,7 +9,7 @@ rvm:
|
|
9
9
|
- 2.2.8
|
10
10
|
- 2.3.5
|
11
11
|
- 2.4.2
|
12
|
-
- 2.5.
|
12
|
+
- 2.5.3
|
13
13
|
env:
|
14
14
|
global:
|
15
15
|
- RANTLY_COUNT=10000
|
@@ -25,6 +25,3 @@ deploy:
|
|
25
25
|
tags: true
|
26
26
|
repo: miyucy/brotli
|
27
27
|
script: bundle exec rake && ./smoke.sh
|
28
|
-
matrix:
|
29
|
-
allow_failures:
|
30
|
-
- rvm: 2.5.0-preview1
|
data/lib/brotli/version.rb
CHANGED
@@ -71,7 +71,7 @@ OR:
|
|
71
71
|
*/
|
72
72
|
#if BROTLI_GNUC_HAS_BUILTIN(__builtin_expect, 3, 0, 0) || \
|
73
73
|
BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \
|
74
|
-
BROTLI_SUNPRO_VERSION_CHECK(5,
|
74
|
+
BROTLI_SUNPRO_VERSION_CHECK(5, 15, 0) || \
|
75
75
|
BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \
|
76
76
|
BROTLI_IBM_VERSION_CHECK(10, 1, 0) || \
|
77
77
|
BROTLI_TI_VERSION_CHECK(7, 3, 0) || \
|
@@ -180,6 +180,12 @@ OR:
|
|
180
180
|
#define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE
|
181
181
|
#endif
|
182
182
|
|
183
|
+
#if BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0)
|
184
|
+
#define BROTLI_ALIGNED(N) __attribute__((aligned(N)))
|
185
|
+
#else
|
186
|
+
#define BROTLI_ALIGNED(N)
|
187
|
+
#endif
|
188
|
+
|
183
189
|
#if (defined(__ARM_ARCH) && (__ARM_ARCH == 7)) || \
|
184
190
|
(defined(M_ARM) && (M_ARM == 7))
|
185
191
|
#define BROTLI_TARGET_ARMV7
|
@@ -187,9 +193,20 @@ OR:
|
|
187
193
|
|
188
194
|
#if (defined(__ARM_ARCH) && (__ARM_ARCH == 8)) || \
|
189
195
|
defined(__aarch64__) || defined(__ARM64_ARCH_8__)
|
190
|
-
#define
|
196
|
+
#define BROTLI_TARGET_ARMV8_ANY
|
197
|
+
|
198
|
+
#if defined(__ARM_32BIT_STATE)
|
199
|
+
#define BROTLI_TARGET_ARMV8_32
|
200
|
+
#elif defined(__ARM_64BIT_STATE)
|
201
|
+
#define BROTLI_TARGET_ARMV8_64
|
202
|
+
#endif
|
203
|
+
|
191
204
|
#endif /* ARMv8 */
|
192
205
|
|
206
|
+
#if defined(__ARM_NEON__) || defined(__ARM_NEON)
|
207
|
+
#define BROTLI_TARGET_NEON
|
208
|
+
#endif
|
209
|
+
|
193
210
|
#if defined(__i386) || defined(_M_IX86)
|
194
211
|
#define BROTLI_TARGET_X86
|
195
212
|
#endif
|
@@ -210,7 +227,7 @@ OR:
|
|
210
227
|
#define BROTLI_64_BITS 1
|
211
228
|
#elif defined(BROTLI_BUILD_32_BIT)
|
212
229
|
#define BROTLI_64_BITS 0
|
213
|
-
#elif defined(BROTLI_TARGET_X64) || defined(
|
230
|
+
#elif defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \
|
214
231
|
defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64)
|
215
232
|
#define BROTLI_64_BITS 1
|
216
233
|
#else
|
@@ -261,7 +278,7 @@ OR:
|
|
261
278
|
#if defined(BROTLI_BUILD_PORTABLE)
|
262
279
|
#define BROTLI_ALIGNED_READ (!!1)
|
263
280
|
#elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
|
264
|
-
defined(BROTLI_TARGET_ARMV7) || defined(
|
281
|
+
defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) || \
|
265
282
|
defined(BROTLI_TARGET_RISCV64)
|
266
283
|
/* Allow unaligned read only for white-listed CPUs. */
|
267
284
|
#define BROTLI_ALIGNED_READ (!!0)
|
@@ -291,6 +308,33 @@ static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
|
|
291
308
|
}
|
292
309
|
#else /* BROTLI_ALIGNED_READ */
|
293
310
|
/* Unaligned memory access is allowed: just cast pointer to requested type. */
|
311
|
+
#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
|
312
|
+
defined(MEMORY_SANITIZER)
|
313
|
+
/* Consider we have an unaligned load/store of 4 bytes from address 0x...05.
|
314
|
+
AddressSanitizer will treat it as a 3-byte access to the range 05:07 and
|
315
|
+
will miss a bug if 08 is the first unaddressable byte.
|
316
|
+
ThreadSanitizer will also treat this as a 3-byte access to 05:07 and will
|
317
|
+
miss a race between this access and some other accesses to 08.
|
318
|
+
MemorySanitizer will correctly propagate the shadow on unaligned stores
|
319
|
+
and correctly report bugs on unaligned loads, but it may not properly
|
320
|
+
update and report the origin of the uninitialized memory.
|
321
|
+
For all three tools, replacing an unaligned access with a tool-specific
|
322
|
+
callback solves the problem. */
|
323
|
+
#if defined(__cplusplus)
|
324
|
+
extern "C" {
|
325
|
+
#endif /* __cplusplus */
|
326
|
+
uint16_t __sanitizer_unaligned_load16(const void* p);
|
327
|
+
uint32_t __sanitizer_unaligned_load32(const void* p);
|
328
|
+
uint64_t __sanitizer_unaligned_load64(const void* p);
|
329
|
+
void __sanitizer_unaligned_store64(void* p, uint64_t v);
|
330
|
+
#if defined(__cplusplus)
|
331
|
+
} /* extern "C" */
|
332
|
+
#endif /* __cplusplus */
|
333
|
+
#define BrotliUnalignedRead16 __sanitizer_unaligned_load16
|
334
|
+
#define BrotliUnalignedRead32 __sanitizer_unaligned_load32
|
335
|
+
#define BrotliUnalignedRead64 __sanitizer_unaligned_load64
|
336
|
+
#define BrotliUnalignedWrite64 __sanitizer_unaligned_store64
|
337
|
+
#else
|
294
338
|
static BROTLI_INLINE uint16_t BrotliUnalignedRead16(const void* p) {
|
295
339
|
return *(const uint16_t*)p;
|
296
340
|
}
|
@@ -306,16 +350,31 @@ static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
|
|
306
350
|
}
|
307
351
|
#else /* BROTLI_64_BITS */
|
308
352
|
/* Avoid emitting LDRD / STRD, which require properly aligned address. */
|
353
|
+
/* If __attribute__(aligned) is available, use that. Otherwise, memcpy. */
|
354
|
+
|
355
|
+
#if BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0)
|
356
|
+
typedef BROTLI_ALIGNED(1) uint64_t brotli_unaligned_uint64_t;
|
357
|
+
|
358
|
+
static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) {
|
359
|
+
return (uint64_t) ((brotli_unaligned_uint64_t*) p)[0];
|
360
|
+
}
|
361
|
+
static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
|
362
|
+
brotli_unaligned_uint64_t* dwords = (brotli_unaligned_uint64_t*) p;
|
363
|
+
dwords[0] = (brotli_unaligned_uint64_t) v;
|
364
|
+
}
|
365
|
+
#else /* BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0) */
|
309
366
|
static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) {
|
310
|
-
|
311
|
-
|
367
|
+
uint64_t v;
|
368
|
+
memcpy(&v, p, sizeof(uint64_t));
|
369
|
+
return v;
|
312
370
|
}
|
371
|
+
|
313
372
|
static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
|
314
|
-
|
315
|
-
dwords[0] = (uint32_t)v;
|
316
|
-
dwords[1] = (uint32_t)(v >> 32);
|
373
|
+
memcpy(p, &v, sizeof(uint64_t));
|
317
374
|
}
|
375
|
+
#endif /* BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0) */
|
318
376
|
#endif /* BROTLI_64_BITS */
|
377
|
+
#endif /* ASAN / TSAN / MSAN */
|
319
378
|
#endif /* BROTLI_ALIGNED_READ */
|
320
379
|
|
321
380
|
#if BROTLI_LITTLE_ENDIAN
|
@@ -400,7 +459,7 @@ static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) {
|
|
400
459
|
#define BROTLI_IS_CONSTANT(x) (!!0)
|
401
460
|
#endif
|
402
461
|
|
403
|
-
#if defined(BROTLI_TARGET_ARMV7) || defined(
|
462
|
+
#if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY)
|
404
463
|
#define BROTLI_HAS_UBFX (!!1)
|
405
464
|
#else
|
406
465
|
#define BROTLI_HAS_UBFX (!!0)
|
@@ -427,7 +486,7 @@ static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) {
|
|
427
486
|
/* TODO: add appropriate icc/sunpro/arm/ibm/ti checks. */
|
428
487
|
#if (BROTLI_GNUC_VERSION_CHECK(3, 0, 0) || defined(__llvm__)) && \
|
429
488
|
!defined(BROTLI_BUILD_NO_RBIT)
|
430
|
-
#if defined(BROTLI_TARGET_ARMV7) || defined(
|
489
|
+
#if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY)
|
431
490
|
/* TODO: detect ARMv6T2 and enable this code for it. */
|
432
491
|
static BROTLI_INLINE brotli_reg_t BrotliRBit(brotli_reg_t input) {
|
433
492
|
brotli_reg_t output;
|
@@ -191,11 +191,11 @@ static int ToUpperCase(uint8_t* p) {
|
|
191
191
|
}
|
192
192
|
|
193
193
|
int BrotliTransformDictionaryWord(uint8_t* dst, const uint8_t* word, int len,
|
194
|
-
const BrotliTransforms* transforms, int
|
194
|
+
const BrotliTransforms* transforms, int transform_idx) {
|
195
195
|
int idx = 0;
|
196
|
-
const uint8_t* prefix = BROTLI_TRANSFORM_PREFIX(transforms,
|
197
|
-
uint8_t type = BROTLI_TRANSFORM_TYPE(transforms,
|
198
|
-
const uint8_t* suffix = BROTLI_TRANSFORM_SUFFIX(transforms,
|
196
|
+
const uint8_t* prefix = BROTLI_TRANSFORM_PREFIX(transforms, transform_idx);
|
197
|
+
uint8_t type = BROTLI_TRANSFORM_TYPE(transforms, transform_idx);
|
198
|
+
const uint8_t* suffix = BROTLI_TRANSFORM_SUFFIX(transforms, transform_idx);
|
199
199
|
{
|
200
200
|
int prefix_len = *prefix++;
|
201
201
|
while (prefix_len--) { dst[idx++] = *prefix++; }
|
@@ -14,13 +14,13 @@
|
|
14
14
|
BrotliEncoderVersion methods. */
|
15
15
|
|
16
16
|
/* Semantic version, calculated as (MAJOR << 24) | (MINOR << 12) | PATCH */
|
17
|
-
#define BROTLI_VERSION
|
17
|
+
#define BROTLI_VERSION 0x1000007
|
18
18
|
|
19
19
|
/* This macro is used by build system to produce Libtool-friendly soname. See
|
20
20
|
https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
|
21
21
|
*/
|
22
22
|
|
23
23
|
/* ABI version, calculated as (CURRENT << 24) | (REVISION << 12) | AGE */
|
24
|
-
#define BROTLI_ABI_VERSION
|
24
|
+
#define BROTLI_ABI_VERSION 0x1007000
|
25
25
|
|
26
26
|
#endif /* BROTLI_COMMON_VERSION_H_ */
|
@@ -6,10 +6,6 @@
|
|
6
6
|
|
7
7
|
#include <brotli/decode.h>
|
8
8
|
|
9
|
-
#if defined(__ARM_NEON__)
|
10
|
-
#include <arm_neon.h>
|
11
|
-
#endif
|
12
|
-
|
13
9
|
#include <stdlib.h> /* free, malloc */
|
14
10
|
#include <string.h> /* memcpy, memset */
|
15
11
|
|
@@ -24,6 +20,10 @@
|
|
24
20
|
#include "./prefix.h"
|
25
21
|
#include "./state.h"
|
26
22
|
|
23
|
+
#if defined(BROTLI_TARGET_NEON)
|
24
|
+
#include <arm_neon.h>
|
25
|
+
#endif
|
26
|
+
|
27
27
|
#if defined(__cplusplus) || defined(c_plusplus)
|
28
28
|
extern "C" {
|
29
29
|
#endif
|
@@ -167,7 +167,7 @@ static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s,
|
|
167
167
|
}
|
168
168
|
|
169
169
|
static BROTLI_INLINE void memmove16(uint8_t* dst, uint8_t* src) {
|
170
|
-
#if defined(
|
170
|
+
#if defined(BROTLI_TARGET_NEON)
|
171
171
|
vst1q_u8(dst, vld1q_u8(src));
|
172
172
|
#else
|
173
173
|
uint32_t buffer[4];
|
@@ -347,15 +347,17 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
|
347
347
|
static BROTLI_INLINE uint32_t DecodeSymbol(uint32_t bits,
|
348
348
|
const HuffmanCode* table,
|
349
349
|
BrotliBitReader* br) {
|
350
|
-
table
|
351
|
-
|
352
|
-
|
350
|
+
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
|
351
|
+
BROTLI_HC_ADJUST_TABLE_INDEX(table, bits & HUFFMAN_TABLE_MASK);
|
352
|
+
if (BROTLI_HC_FAST_LOAD_BITS(table) > HUFFMAN_TABLE_BITS) {
|
353
|
+
uint32_t nbits = BROTLI_HC_FAST_LOAD_BITS(table) - HUFFMAN_TABLE_BITS;
|
353
354
|
BrotliDropBits(br, HUFFMAN_TABLE_BITS);
|
354
|
-
table
|
355
|
-
|
355
|
+
BROTLI_HC_ADJUST_TABLE_INDEX(table,
|
356
|
+
BROTLI_HC_FAST_LOAD_VALUE(table) +
|
357
|
+
((bits >> HUFFMAN_TABLE_BITS) & BitMask(nbits)));
|
356
358
|
}
|
357
|
-
BrotliDropBits(br, table
|
358
|
-
return table
|
359
|
+
BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(table));
|
360
|
+
return BROTLI_HC_FAST_LOAD_VALUE(table);
|
359
361
|
}
|
360
362
|
|
361
363
|
/* Reads and decodes the next Huffman code from bit-stream.
|
@@ -371,19 +373,20 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
|
|
371
373
|
const HuffmanCode* table, BrotliBitReader* br, uint32_t* result) {
|
372
374
|
uint32_t val;
|
373
375
|
uint32_t available_bits = BrotliGetAvailableBits(br);
|
376
|
+
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
|
374
377
|
if (available_bits == 0) {
|
375
|
-
if (table
|
376
|
-
*result = table
|
378
|
+
if (BROTLI_HC_FAST_LOAD_BITS(table) == 0) {
|
379
|
+
*result = BROTLI_HC_FAST_LOAD_VALUE(table);
|
377
380
|
return BROTLI_TRUE;
|
378
381
|
}
|
379
382
|
return BROTLI_FALSE; /* No valid bits at all. */
|
380
383
|
}
|
381
384
|
val = (uint32_t)BrotliGetBitsUnmasked(br);
|
382
|
-
table
|
383
|
-
if (table
|
384
|
-
if (table
|
385
|
-
BrotliDropBits(br, table
|
386
|
-
*result = table
|
385
|
+
BROTLI_HC_ADJUST_TABLE_INDEX(table, val & HUFFMAN_TABLE_MASK);
|
386
|
+
if (BROTLI_HC_FAST_LOAD_BITS(table) <= HUFFMAN_TABLE_BITS) {
|
387
|
+
if (BROTLI_HC_FAST_LOAD_BITS(table) <= available_bits) {
|
388
|
+
BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(table));
|
389
|
+
*result = BROTLI_HC_FAST_LOAD_VALUE(table);
|
387
390
|
return BROTLI_TRUE;
|
388
391
|
} else {
|
389
392
|
return BROTLI_FALSE; /* Not enough bits for the first level. */
|
@@ -394,15 +397,15 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
|
|
394
397
|
}
|
395
398
|
|
396
399
|
/* Speculatively drop HUFFMAN_TABLE_BITS. */
|
397
|
-
val = (val & BitMask(table
|
400
|
+
val = (val & BitMask(BROTLI_HC_FAST_LOAD_BITS(table))) >> HUFFMAN_TABLE_BITS;
|
398
401
|
available_bits -= HUFFMAN_TABLE_BITS;
|
399
|
-
table
|
400
|
-
if (available_bits < table
|
402
|
+
BROTLI_HC_ADJUST_TABLE_INDEX(table, BROTLI_HC_FAST_LOAD_VALUE(table) + val);
|
403
|
+
if (available_bits < BROTLI_HC_FAST_LOAD_BITS(table)) {
|
401
404
|
return BROTLI_FALSE; /* Not enough bits for the second level. */
|
402
405
|
}
|
403
406
|
|
404
|
-
BrotliDropBits(br, HUFFMAN_TABLE_BITS + table
|
405
|
-
*result = table
|
407
|
+
BrotliDropBits(br, HUFFMAN_TABLE_BITS + BROTLI_HC_FAST_LOAD_BITS(table));
|
408
|
+
*result = BROTLI_HC_FAST_LOAD_VALUE(table);
|
406
409
|
return BROTLI_TRUE;
|
407
410
|
}
|
408
411
|
|
@@ -425,9 +428,10 @@ static BROTLI_INLINE void PreloadSymbol(int safe,
|
|
425
428
|
if (safe) {
|
426
429
|
return;
|
427
430
|
}
|
428
|
-
table
|
429
|
-
|
430
|
-
*
|
431
|
+
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
|
432
|
+
BROTLI_HC_ADJUST_TABLE_INDEX(table, BrotliGetBits(br, HUFFMAN_TABLE_BITS));
|
433
|
+
*bits = BROTLI_HC_FAST_LOAD_BITS(table);
|
434
|
+
*value = BROTLI_HC_FAST_LOAD_VALUE(table);
|
431
435
|
}
|
432
436
|
|
433
437
|
/* Decodes the next Huffman code using data prepared by PreloadSymbol.
|
@@ -441,10 +445,11 @@ static BROTLI_INLINE uint32_t ReadPreloadedSymbol(const HuffmanCode* table,
|
|
441
445
|
uint32_t val = BrotliGet16BitsUnmasked(br);
|
442
446
|
const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value;
|
443
447
|
uint32_t mask = BitMask((*bits - HUFFMAN_TABLE_BITS));
|
448
|
+
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(ext);
|
444
449
|
BrotliDropBits(br, HUFFMAN_TABLE_BITS);
|
445
|
-
ext
|
446
|
-
BrotliDropBits(br, ext
|
447
|
-
result = ext
|
450
|
+
BROTLI_HC_ADJUST_TABLE_INDEX(ext, (val >> HUFFMAN_TABLE_BITS) & mask);
|
451
|
+
BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(ext));
|
452
|
+
result = BROTLI_HC_FAST_LOAD_VALUE(ext);
|
448
453
|
} else {
|
449
454
|
BrotliDropBits(br, *bits);
|
450
455
|
}
|
@@ -597,6 +602,7 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
|
597
602
|
while (symbol < alphabet_size && space > 0) {
|
598
603
|
const HuffmanCode* p = s->table;
|
599
604
|
uint32_t code_len;
|
605
|
+
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
|
600
606
|
if (!BrotliCheckInputAmount(br, BROTLI_SHORT_FILL_BIT_WINDOW_READ)) {
|
601
607
|
s->symbol = symbol;
|
602
608
|
s->repeat = repeat;
|
@@ -606,10 +612,10 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
|
606
612
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
607
613
|
}
|
608
614
|
BrotliFillBitWindow16(br);
|
609
|
-
p
|
610
|
-
BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
|
611
|
-
BrotliDropBits(br, p
|
612
|
-
code_len = p
|
615
|
+
BROTLI_HC_ADJUST_TABLE_INDEX(p, BrotliGetBitsUnmasked(br) &
|
616
|
+
BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH));
|
617
|
+
BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p)); /* Use 1..5 bits. */
|
618
|
+
code_len = BROTLI_HC_FAST_LOAD_VALUE(p); /* code_len == 0..17 */
|
613
619
|
if (code_len < BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) {
|
614
620
|
ProcessSingleCodeLength(code_len, &symbol, &repeat, &space,
|
615
621
|
&prev_code_len, symbol_lists, code_length_histo, next_symbol);
|
@@ -637,31 +643,34 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
|
637
643
|
uint32_t code_len;
|
638
644
|
uint32_t available_bits;
|
639
645
|
uint32_t bits = 0;
|
646
|
+
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
|
640
647
|
if (get_byte && !BrotliPullByte(br)) return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
641
648
|
get_byte = BROTLI_FALSE;
|
642
649
|
available_bits = BrotliGetAvailableBits(br);
|
643
650
|
if (available_bits != 0) {
|
644
651
|
bits = (uint32_t)BrotliGetBitsUnmasked(br);
|
645
652
|
}
|
646
|
-
p
|
647
|
-
|
653
|
+
BROTLI_HC_ADJUST_TABLE_INDEX(p,
|
654
|
+
bits & BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH));
|
655
|
+
if (BROTLI_HC_FAST_LOAD_BITS(p) > available_bits) {
|
648
656
|
get_byte = BROTLI_TRUE;
|
649
657
|
continue;
|
650
658
|
}
|
651
|
-
code_len = p
|
659
|
+
code_len = BROTLI_HC_FAST_LOAD_VALUE(p); /* code_len == 0..17 */
|
652
660
|
if (code_len < BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) {
|
653
|
-
BrotliDropBits(br, p
|
661
|
+
BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p));
|
654
662
|
ProcessSingleCodeLength(code_len, &s->symbol, &s->repeat, &s->space,
|
655
663
|
&s->prev_code_len, s->symbol_lists, s->code_length_histo,
|
656
664
|
s->next_symbol);
|
657
665
|
} else { /* code_len == 16..17, extra_bits == 2..3 */
|
658
666
|
uint32_t extra_bits = code_len - 14U;
|
659
|
-
uint32_t repeat_delta = (bits >> p
|
660
|
-
|
667
|
+
uint32_t repeat_delta = (bits >> BROTLI_HC_FAST_LOAD_BITS(p)) &
|
668
|
+
BitMask(extra_bits);
|
669
|
+
if (available_bits < BROTLI_HC_FAST_LOAD_BITS(p) + extra_bits) {
|
661
670
|
get_byte = BROTLI_TRUE;
|
662
671
|
continue;
|
663
672
|
}
|
664
|
-
BrotliDropBits(br, p
|
673
|
+
BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p) + extra_bits);
|
665
674
|
ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
|
666
675
|
&s->symbol, &s->repeat, &s->space, &s->prev_code_len,
|
667
676
|
&s->repeat_code_len, s->symbol_lists, s->code_length_histo,
|
@@ -142,8 +142,7 @@ void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
|
|
142
142
|
|
143
143
|
/* Special case: all symbols but one have 0 code length. */
|
144
144
|
if (offset[0] == 0) {
|
145
|
-
code
|
146
|
-
code.value = (uint16_t)sorted[0];
|
145
|
+
code = ConstructHuffmanCode(0, (uint16_t)sorted[0]);
|
147
146
|
for (key = 0; key < (brotli_reg_t)table_size; ++key) {
|
148
147
|
table[key] = code;
|
149
148
|
}
|
@@ -157,9 +156,8 @@ void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
|
|
157
156
|
bits = 1;
|
158
157
|
step = 2;
|
159
158
|
do {
|
160
|
-
code.bits = (uint8_t)bits;
|
161
159
|
for (bits_count = count[bits]; bits_count != 0; --bits_count) {
|
162
|
-
code
|
160
|
+
code = ConstructHuffmanCode((uint8_t)bits, (uint16_t)sorted[symbol++]);
|
163
161
|
ReplicateValue(&table[BrotliReverseBits(key)], step, table_size, code);
|
164
162
|
key += key_step;
|
165
163
|
}
|
@@ -211,11 +209,10 @@ uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
|
211
209
|
bits = 1;
|
212
210
|
step = 2;
|
213
211
|
do {
|
214
|
-
code.bits = (uint8_t)bits;
|
215
212
|
symbol = bits - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1);
|
216
213
|
for (bits_count = count[bits]; bits_count != 0; --bits_count) {
|
217
214
|
symbol = symbol_lists[symbol];
|
218
|
-
code
|
215
|
+
code = ConstructHuffmanCode((uint8_t)bits, (uint16_t)symbol);
|
219
216
|
ReplicateValue(&table[BrotliReverseBits(key)], step, table_size, code);
|
220
217
|
key += key_step;
|
221
218
|
}
|
@@ -244,14 +241,13 @@ uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
|
244
241
|
total_size += table_size;
|
245
242
|
sub_key = BrotliReverseBits(key);
|
246
243
|
key += key_step;
|
247
|
-
root_table[sub_key]
|
248
|
-
|
249
|
-
(uint16_t)(((size_t)(table - root_table)) - sub_key);
|
244
|
+
root_table[sub_key] = ConstructHuffmanCode(
|
245
|
+
(uint8_t)(table_bits + root_bits),
|
246
|
+
(uint16_t)(((size_t)(table - root_table)) - sub_key));
|
250
247
|
sub_key = 0;
|
251
248
|
}
|
252
|
-
code.bits = (uint8_t)(len - root_bits);
|
253
249
|
symbol = symbol_lists[symbol];
|
254
|
-
code
|
250
|
+
code = ConstructHuffmanCode((uint8_t)(len - root_bits), (uint16_t)symbol);
|
255
251
|
ReplicateValue(
|
256
252
|
&table[BrotliReverseBits(sub_key)], step, table_size, code);
|
257
253
|
sub_key += sub_key_step;
|
@@ -270,35 +266,28 @@ uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
|
|
270
266
|
const uint32_t goal_size = 1U << root_bits;
|
271
267
|
switch (num_symbols) {
|
272
268
|
case 0:
|
273
|
-
table[0]
|
274
|
-
table[0].value = val[0];
|
269
|
+
table[0] = ConstructHuffmanCode(0, val[0]);
|
275
270
|
break;
|
276
271
|
case 1:
|
277
|
-
table[0].bits = 1;
|
278
|
-
table[1].bits = 1;
|
279
272
|
if (val[1] > val[0]) {
|
280
|
-
table[0]
|
281
|
-
table[1]
|
273
|
+
table[0] = ConstructHuffmanCode(1, val[0]);
|
274
|
+
table[1] = ConstructHuffmanCode(1, val[1]);
|
282
275
|
} else {
|
283
|
-
table[0]
|
284
|
-
table[1]
|
276
|
+
table[0] = ConstructHuffmanCode(1, val[1]);
|
277
|
+
table[1] = ConstructHuffmanCode(1, val[0]);
|
285
278
|
}
|
286
279
|
table_size = 2;
|
287
280
|
break;
|
288
281
|
case 2:
|
289
|
-
table[0]
|
290
|
-
table[
|
291
|
-
table[2].bits = 1;
|
292
|
-
table[2].value = val[0];
|
282
|
+
table[0] = ConstructHuffmanCode(1, val[0]);
|
283
|
+
table[2] = ConstructHuffmanCode(1, val[0]);
|
293
284
|
if (val[2] > val[1]) {
|
294
|
-
table[1]
|
295
|
-
table[3]
|
285
|
+
table[1] = ConstructHuffmanCode(2, val[1]);
|
286
|
+
table[3] = ConstructHuffmanCode(2, val[2]);
|
296
287
|
} else {
|
297
|
-
table[1]
|
298
|
-
table[3]
|
288
|
+
table[1] = ConstructHuffmanCode(2, val[2]);
|
289
|
+
table[3] = ConstructHuffmanCode(2, val[1]);
|
299
290
|
}
|
300
|
-
table[1].bits = 2;
|
301
|
-
table[3].bits = 2;
|
302
291
|
table_size = 4;
|
303
292
|
break;
|
304
293
|
case 3: {
|
@@ -312,33 +301,27 @@ uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
|
|
312
301
|
}
|
313
302
|
}
|
314
303
|
}
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
table[
|
319
|
-
table[2].value = val[1];
|
320
|
-
table[1].value = val[2];
|
321
|
-
table[3].value = val[3];
|
304
|
+
table[0] = ConstructHuffmanCode(2, val[0]);
|
305
|
+
table[2] = ConstructHuffmanCode(2, val[1]);
|
306
|
+
table[1] = ConstructHuffmanCode(2, val[2]);
|
307
|
+
table[3] = ConstructHuffmanCode(2, val[3]);
|
322
308
|
table_size = 4;
|
323
309
|
break;
|
324
310
|
}
|
325
311
|
case 4: {
|
326
|
-
int i;
|
327
312
|
if (val[3] < val[2]) {
|
328
313
|
uint16_t t = val[3];
|
329
314
|
val[3] = val[2];
|
330
315
|
val[2] = t;
|
331
316
|
}
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
table[
|
337
|
-
table[
|
338
|
-
table[
|
339
|
-
table[7]
|
340
|
-
table[3].bits = 3;
|
341
|
-
table[7].bits = 3;
|
317
|
+
table[0] = ConstructHuffmanCode(1, val[0]);
|
318
|
+
table[1] = ConstructHuffmanCode(2, val[1]);
|
319
|
+
table[2] = ConstructHuffmanCode(1, val[0]);
|
320
|
+
table[3] = ConstructHuffmanCode(3, val[2]);
|
321
|
+
table[4] = ConstructHuffmanCode(1, val[0]);
|
322
|
+
table[5] = ConstructHuffmanCode(2, val[1]);
|
323
|
+
table[6] = ConstructHuffmanCode(1, val[0]);
|
324
|
+
table[7] = ConstructHuffmanCode(3, val[3]);
|
342
325
|
table_size = 8;
|
343
326
|
break;
|
344
327
|
}
|
@@ -33,11 +33,66 @@ static const uint16_t kMaxHuffmanTableSize[] = {
|
|
33
33
|
|
34
34
|
#define BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH 5
|
35
35
|
|
36
|
+
#if ((defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_32)) && \
|
37
|
+
BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0))
|
38
|
+
#define BROTLI_HUFFMAN_CODE_FAST_LOAD
|
39
|
+
#endif
|
40
|
+
|
41
|
+
#if !defined(BROTLI_HUFFMAN_CODE_FAST_LOAD)
|
42
|
+
/* Do not create this struct directly - use the ConstructHuffmanCode
|
43
|
+
* constructor below! */
|
36
44
|
typedef struct {
|
37
45
|
uint8_t bits; /* number of bits used for this symbol */
|
38
46
|
uint16_t value; /* symbol value or table offset */
|
39
47
|
} HuffmanCode;
|
40
48
|
|
49
|
+
static BROTLI_INLINE HuffmanCode ConstructHuffmanCode(const uint8_t bits,
|
50
|
+
const uint16_t value) {
|
51
|
+
HuffmanCode h;
|
52
|
+
h.bits = bits;
|
53
|
+
h.value = value;
|
54
|
+
return h;
|
55
|
+
}
|
56
|
+
|
57
|
+
/* Please use the following macros to optimize HuffmanCode accesses in hot
|
58
|
+
* paths.
|
59
|
+
*
|
60
|
+
* For example, assuming |table| contains a HuffmanCode pointer:
|
61
|
+
*
|
62
|
+
* BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
|
63
|
+
* BROTLI_HC_ADJUST_TABLE_INDEX(table, index_into_table);
|
64
|
+
* *bits = BROTLI_HC_GET_BITS(table);
|
65
|
+
* *value = BROTLI_HC_GET_VALUE(table);
|
66
|
+
* BROTLI_HC_ADJUST_TABLE_INDEX(table, offset);
|
67
|
+
* *bits2 = BROTLI_HC_GET_BITS(table);
|
68
|
+
* *value2 = BROTLI_HC_GET_VALUE(table);
|
69
|
+
*
|
70
|
+
*/
|
71
|
+
|
72
|
+
#define BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(H)
|
73
|
+
#define BROTLI_HC_ADJUST_TABLE_INDEX(H, V) H += (V)
|
74
|
+
|
75
|
+
/* These must be given a HuffmanCode pointer! */
|
76
|
+
#define BROTLI_HC_FAST_LOAD_BITS(H) (H->bits)
|
77
|
+
#define BROTLI_HC_FAST_LOAD_VALUE(H) (H->value)
|
78
|
+
|
79
|
+
#else /* BROTLI_HUFFMAN_CODE_FAST_LOAD */
|
80
|
+
|
81
|
+
typedef BROTLI_ALIGNED(4) uint32_t HuffmanCode;
|
82
|
+
|
83
|
+
static BROTLI_INLINE HuffmanCode ConstructHuffmanCode(const uint8_t bits,
|
84
|
+
const uint16_t value) {
|
85
|
+
return ((value & 0xFFFF) << 16) | (bits & 0xFF);
|
86
|
+
}
|
87
|
+
|
88
|
+
#define BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(H) uint32_t __fastload_##H = (*H)
|
89
|
+
#define BROTLI_HC_ADJUST_TABLE_INDEX(H, V) H += (V); __fastload_##H = (*H)
|
90
|
+
|
91
|
+
/* These must be given a HuffmanCode pointer! */
|
92
|
+
#define BROTLI_HC_FAST_LOAD_BITS(H) ((__fastload_##H) & 0xFF)
|
93
|
+
#define BROTLI_HC_FAST_LOAD_VALUE(H) ((__fastload_##H) >> 16)
|
94
|
+
#endif /* BROTLI_HUFFMAN_CODE_FAST_LOAD */
|
95
|
+
|
41
96
|
/* Builds Huffman lookup table assuming code lengths are in symbol order. */
|
42
97
|
BROTLI_INTERNAL void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* root_table,
|
43
98
|
const uint8_t* const code_lengths, uint16_t* count);
|
@@ -330,7 +330,7 @@ static size_t ComputeMinimumCopyLength(const float start_cost,
|
|
330
330
|
REQUIRES: nodes[0..pos] satisfies that "ZopfliNode array invariant". */
|
331
331
|
static uint32_t ComputeDistanceShortcut(const size_t block_start,
|
332
332
|
const size_t pos,
|
333
|
-
const size_t
|
333
|
+
const size_t max_backward_limit,
|
334
334
|
const size_t gap,
|
335
335
|
const ZopfliNode* nodes) {
|
336
336
|
const size_t clen = ZopfliNodeCopyLength(&nodes[pos]);
|
@@ -338,13 +338,13 @@ static uint32_t ComputeDistanceShortcut(const size_t block_start,
|
|
338
338
|
const size_t dist = ZopfliNodeCopyDistance(&nodes[pos]);
|
339
339
|
/* Since |block_start + pos| is the end position of the command, the copy part
|
340
340
|
starts from |block_start + pos - clen|. Distances that are greater than
|
341
|
-
this or greater than |
|
342
|
-
do not update the last distances.
|
343
|
-
does not update the last distances. */
|
341
|
+
this or greater than |max_backward_limit| + |gap| are static dictionary
|
342
|
+
references, and do not update the last distances.
|
343
|
+
Also distance code 0 (last distance) does not update the last distances. */
|
344
344
|
if (pos == 0) {
|
345
345
|
return 0;
|
346
346
|
} else if (dist + clen <= block_start + pos + gap &&
|
347
|
-
dist <=
|
347
|
+
dist <= max_backward_limit + gap &&
|
348
348
|
ZopfliNodeDistanceCode(&nodes[pos]) > 0) {
|
349
349
|
return (uint32_t)pos;
|
350
350
|
} else {
|
@@ -454,9 +454,11 @@ static size_t UpdateNodes(
|
|
454
454
|
break;
|
455
455
|
}
|
456
456
|
if (BROTLI_PREDICT_FALSE(backward > max_distance + gap)) {
|
457
|
+
/* Word dictionary -> ignore. */
|
457
458
|
continue;
|
458
459
|
}
|
459
460
|
if (backward <= max_distance) {
|
461
|
+
/* Regular backward reference. */
|
460
462
|
if (prev_ix >= cur_ix) {
|
461
463
|
continue;
|
462
464
|
}
|
@@ -564,14 +566,10 @@ static size_t ComputeShortestPathFromNodes(size_t num_bytes,
|
|
564
566
|
|
565
567
|
/* REQUIRES: nodes != NULL and len(nodes) >= num_bytes + 1 */
|
566
568
|
void BrotliZopfliCreateCommands(const size_t num_bytes,
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
size_t* last_insert_len,
|
572
|
-
const BrotliEncoderParams* params,
|
573
|
-
Command* commands,
|
574
|
-
size_t* num_literals) {
|
569
|
+
const size_t block_start, const ZopfliNode* nodes, int* dist_cache,
|
570
|
+
size_t* last_insert_len, const BrotliEncoderParams* params,
|
571
|
+
Command* commands, size_t* num_literals) {
|
572
|
+
const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
|
575
573
|
size_t pos = 0;
|
576
574
|
uint32_t offset = nodes[0].u.next;
|
577
575
|
size_t i;
|
@@ -610,18 +608,12 @@ void BrotliZopfliCreateCommands(const size_t num_bytes,
|
|
610
608
|
*last_insert_len += num_bytes - pos;
|
611
609
|
}
|
612
610
|
|
613
|
-
static size_t ZopfliIterate(size_t num_bytes,
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
const size_t gap,
|
620
|
-
const int* dist_cache,
|
621
|
-
const ZopfliCostModel* model,
|
622
|
-
const uint32_t* num_matches,
|
623
|
-
const BackwardMatch* matches,
|
624
|
-
ZopfliNode* nodes) {
|
611
|
+
static size_t ZopfliIterate(size_t num_bytes, size_t position,
|
612
|
+
const uint8_t* ringbuffer, size_t ringbuffer_mask,
|
613
|
+
const BrotliEncoderParams* params, const size_t gap, const int* dist_cache,
|
614
|
+
const ZopfliCostModel* model, const uint32_t* num_matches,
|
615
|
+
const BackwardMatch* matches, ZopfliNode* nodes) {
|
616
|
+
const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
|
625
617
|
const size_t max_zopfli_len = MaxZopfliLen(params);
|
626
618
|
StartPosQueue queue;
|
627
619
|
size_t cur_match_pos = 0;
|
@@ -645,8 +637,8 @@ static size_t ZopfliIterate(size_t num_bytes,
|
|
645
637
|
while (skip) {
|
646
638
|
i++;
|
647
639
|
if (i + 3 >= num_bytes) break;
|
648
|
-
EvaluateNode(position, i, max_backward_limit, gap,
|
649
|
-
&queue, nodes);
|
640
|
+
EvaluateNode(position, i, max_backward_limit, gap,
|
641
|
+
dist_cache, model, &queue, nodes);
|
650
642
|
cur_match_pos += num_matches[i];
|
651
643
|
skip--;
|
652
644
|
}
|
@@ -656,11 +648,11 @@ static size_t ZopfliIterate(size_t num_bytes,
|
|
656
648
|
}
|
657
649
|
|
658
650
|
/* REQUIRES: nodes != NULL and len(nodes) >= num_bytes + 1 */
|
659
|
-
size_t BrotliZopfliComputeShortestPath(MemoryManager* m,
|
660
|
-
size_t
|
661
|
-
|
662
|
-
const
|
663
|
-
|
651
|
+
size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes,
|
652
|
+
size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
|
653
|
+
const BrotliEncoderParams* params,
|
654
|
+
const int* dist_cache, HasherHandle hasher, ZopfliNode* nodes) {
|
655
|
+
const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
|
664
656
|
const size_t max_zopfli_len = MaxZopfliLen(params);
|
665
657
|
ZopfliCostModel model;
|
666
658
|
StartPosQueue queue;
|
@@ -681,9 +673,11 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m,
|
|
681
673
|
const size_t pos = position + i;
|
682
674
|
const size_t max_distance = BROTLI_MIN(size_t, pos, max_backward_limit);
|
683
675
|
size_t skip;
|
684
|
-
size_t num_matches
|
685
|
-
|
686
|
-
params,
|
676
|
+
size_t num_matches;
|
677
|
+
num_matches = FindAllMatchesH10(hasher,
|
678
|
+
¶ms->dictionary,
|
679
|
+
ringbuffer, ringbuffer_mask, pos, num_bytes - i, max_distance,
|
680
|
+
gap, params, &matches[lz_matches_offset]);
|
687
681
|
if (num_matches > 0 &&
|
688
682
|
BackwardMatchLength(&matches[num_matches - 1]) > max_zopfli_len) {
|
689
683
|
matches[0] = matches[num_matches - 1];
|
@@ -704,8 +698,8 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m,
|
|
704
698
|
while (skip) {
|
705
699
|
i++;
|
706
700
|
if (i + HashTypeLengthH10() - 1 >= num_bytes) break;
|
707
|
-
EvaluateNode(position, i, max_backward_limit, gap,
|
708
|
-
&queue, nodes);
|
701
|
+
EvaluateNode(position, i, max_backward_limit, gap,
|
702
|
+
dist_cache, &model, &queue, nodes);
|
709
703
|
skip--;
|
710
704
|
}
|
711
705
|
}
|
@@ -714,28 +708,27 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m,
|
|
714
708
|
return ComputeShortestPathFromNodes(num_bytes, nodes);
|
715
709
|
}
|
716
710
|
|
717
|
-
void BrotliCreateZopfliBackwardReferences(MemoryManager* m,
|
718
|
-
size_t
|
719
|
-
|
711
|
+
void BrotliCreateZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
|
712
|
+
size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
|
713
|
+
const BrotliEncoderParams* params,
|
720
714
|
HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
|
721
715
|
Command* commands, size_t* num_commands, size_t* num_literals) {
|
722
|
-
const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
|
723
716
|
ZopfliNode* nodes;
|
724
717
|
nodes = BROTLI_ALLOC(m, ZopfliNode, num_bytes + 1);
|
725
718
|
if (BROTLI_IS_OOM(m)) return;
|
726
719
|
BrotliInitZopfliNodes(nodes, num_bytes + 1);
|
727
|
-
*num_commands += BrotliZopfliComputeShortestPath(m,
|
728
|
-
|
729
|
-
|
720
|
+
*num_commands += BrotliZopfliComputeShortestPath(m, num_bytes,
|
721
|
+
position, ringbuffer, ringbuffer_mask, params,
|
722
|
+
dist_cache, hasher, nodes);
|
730
723
|
if (BROTLI_IS_OOM(m)) return;
|
731
|
-
BrotliZopfliCreateCommands(num_bytes, position,
|
732
|
-
|
724
|
+
BrotliZopfliCreateCommands(num_bytes, position, nodes, dist_cache,
|
725
|
+
last_insert_len, params, commands, num_literals);
|
733
726
|
BROTLI_FREE(m, nodes);
|
734
727
|
}
|
735
728
|
|
736
|
-
void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m,
|
737
|
-
size_t
|
738
|
-
|
729
|
+
void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes,
|
730
|
+
size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
|
731
|
+
const BrotliEncoderParams* params,
|
739
732
|
HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
|
740
733
|
Command* commands, size_t* num_commands, size_t* num_literals) {
|
741
734
|
const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
|
@@ -767,8 +760,10 @@ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m,
|
|
767
760
|
cur_match_pos + MAX_NUM_MATCHES_H10 + shadow_matches);
|
768
761
|
if (BROTLI_IS_OOM(m)) return;
|
769
762
|
num_found_matches = FindAllMatchesH10(hasher,
|
770
|
-
¶ms->dictionary,
|
771
|
-
|
763
|
+
¶ms->dictionary,
|
764
|
+
ringbuffer, ringbuffer_mask, pos, max_length,
|
765
|
+
max_distance, gap, params,
|
766
|
+
&matches[cur_match_pos + shadow_matches]);
|
772
767
|
cur_match_end = cur_match_pos + num_found_matches;
|
773
768
|
for (j = cur_match_pos; j + 1 < cur_match_end; ++j) {
|
774
769
|
BROTLI_DCHECK(BackwardMatchLength(&matches[j]) <=
|
@@ -814,10 +809,10 @@ void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m,
|
|
814
809
|
*last_insert_len = orig_last_insert_len;
|
815
810
|
memcpy(dist_cache, orig_dist_cache, 4 * sizeof(dist_cache[0]));
|
816
811
|
*num_commands += ZopfliIterate(num_bytes, position, ringbuffer,
|
817
|
-
ringbuffer_mask, params,
|
818
|
-
|
819
|
-
BrotliZopfliCreateCommands(num_bytes, position,
|
820
|
-
|
812
|
+
ringbuffer_mask, params, gap, dist_cache, &model, num_matches, matches,
|
813
|
+
nodes);
|
814
|
+
BrotliZopfliCreateCommands(num_bytes, position, nodes, dist_cache,
|
815
|
+
last_insert_len, params, commands, num_literals);
|
821
816
|
}
|
822
817
|
CleanupZopfliCostModel(m, &model);
|
823
818
|
BROTLI_FREE(m, nodes);
|
@@ -74,15 +74,14 @@ BROTLI_INTERNAL void BrotliInitZopfliNodes(ZopfliNode* array, size_t length);
|
|
74
74
|
(1) nodes[i].copy_length() >= 2
|
75
75
|
(2) nodes[i].command_length() <= i and
|
76
76
|
(3) nodes[i - nodes[i].command_length()].cost < kInfinity */
|
77
|
-
BROTLI_INTERNAL size_t BrotliZopfliComputeShortestPath(
|
78
|
-
|
79
|
-
size_t
|
80
|
-
const
|
81
|
-
ZopfliNode* nodes);
|
77
|
+
BROTLI_INTERNAL size_t BrotliZopfliComputeShortestPath(
|
78
|
+
MemoryManager* m, size_t num_bytes,
|
79
|
+
size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
|
80
|
+
const BrotliEncoderParams* params,
|
81
|
+
const int* dist_cache, HasherHandle hasher, ZopfliNode* nodes);
|
82
82
|
|
83
83
|
BROTLI_INTERNAL void BrotliZopfliCreateCommands(
|
84
|
-
const size_t num_bytes, const size_t block_start,
|
85
|
-
const size_t max_backward_limit, const ZopfliNode* nodes,
|
84
|
+
const size_t num_bytes, const size_t block_start, const ZopfliNode* nodes,
|
86
85
|
int* dist_cache, size_t* last_insert_len, const BrotliEncoderParams* params,
|
87
86
|
Command* commands, size_t* num_literals);
|
88
87
|
|
@@ -10,9 +10,9 @@
|
|
10
10
|
static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
|
11
11
|
size_t num_bytes, size_t position,
|
12
12
|
const uint8_t* ringbuffer, size_t ringbuffer_mask,
|
13
|
-
const BrotliEncoderParams* params,
|
14
|
-
|
15
|
-
size_t* num_literals) {
|
13
|
+
const BrotliEncoderParams* params,
|
14
|
+
HasherHandle hasher, int* dist_cache, size_t* last_insert_len,
|
15
|
+
Command* commands, size_t* num_commands, size_t* num_literals) {
|
16
16
|
/* Set maximum distance, see section 9.1. of the spec. */
|
17
17
|
const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin);
|
18
18
|
|
@@ -42,9 +42,8 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
|
|
42
42
|
sr.distance = 0;
|
43
43
|
sr.score = kMinScore;
|
44
44
|
FN(FindLongestMatch)(hasher, ¶ms->dictionary,
|
45
|
-
|
46
|
-
|
47
|
-
params->dist.max_distance, &sr);
|
45
|
+
ringbuffer, ringbuffer_mask, dist_cache, position, max_length,
|
46
|
+
max_distance, gap, params->dist.max_distance, &sr);
|
48
47
|
if (sr.score > kMinScore) {
|
49
48
|
/* Found a match. Let's look for something even better ahead. */
|
50
49
|
int delayed_backward_references_in_row = 0;
|
@@ -58,7 +57,8 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
|
|
58
57
|
sr2.distance = 0;
|
59
58
|
sr2.score = kMinScore;
|
60
59
|
max_distance = BROTLI_MIN(size_t, position + 1, max_backward_limit);
|
61
|
-
FN(FindLongestMatch)(hasher,
|
60
|
+
FN(FindLongestMatch)(hasher,
|
61
|
+
¶ms->dictionary,
|
62
62
|
ringbuffer, ringbuffer_mask, dist_cache, position + 1, max_length,
|
63
63
|
max_distance, gap, params->dist.max_distance, &sr2);
|
64
64
|
if (sr2.score >= sr.score + cost_diff_lazy) {
|
@@ -80,8 +80,8 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)(
|
|
80
80
|
{
|
81
81
|
/* The first 16 codes are special short-codes,
|
82
82
|
and the minimum offset is 1. */
|
83
|
-
size_t distance_code =
|
84
|
-
|
83
|
+
size_t distance_code = ComputeDistanceCode(
|
84
|
+
sr.distance, max_distance + gap, dist_cache);
|
85
85
|
if ((sr.distance <= (max_distance + gap)) && distance_code > 0) {
|
86
86
|
dist_cache[3] = dist_cache[2];
|
87
87
|
dist_cache[2] = dist_cache[1];
|
@@ -496,6 +496,8 @@ static void DecideOverLiteralContextModeling(const uint8_t* input,
|
|
496
496
|
static BROTLI_BOOL ShouldCompress(
|
497
497
|
const uint8_t* data, const size_t mask, const uint64_t last_flush_pos,
|
498
498
|
const size_t bytes, const size_t num_literals, const size_t num_commands) {
|
499
|
+
/* TODO: find more precise minimal block overhead. */
|
500
|
+
if (bytes <= 2) return BROTLI_FALSE;
|
499
501
|
if (num_commands < (bytes >> 8) + 2) {
|
500
502
|
if (num_literals > 0.99 * (double)bytes) {
|
501
503
|
uint32_t literal_histo[256] = { 0 };
|
@@ -674,12 +676,14 @@ static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s) {
|
|
674
676
|
if (BROTLI_IS_OOM(&s->memory_manager_)) return BROTLI_FALSE;
|
675
677
|
if (s->is_initialized_) return BROTLI_TRUE;
|
676
678
|
|
679
|
+
s->last_bytes_bits_ = 0;
|
680
|
+
s->last_bytes_ = 0;
|
681
|
+
s->remaining_metadata_bytes_ = BROTLI_UINT32_MAX;
|
682
|
+
|
677
683
|
SanitizeParams(&s->params);
|
678
684
|
s->params.lgblock = ComputeLgBlock(&s->params);
|
679
685
|
ChooseDistanceParams(&s->params);
|
680
686
|
|
681
|
-
s->remaining_metadata_bytes_ = BROTLI_UINT32_MAX;
|
682
|
-
|
683
687
|
RingBufferSetup(&s->params, &s->ringbuffer_);
|
684
688
|
|
685
689
|
/* Initialize last byte with stream header. */
|
@@ -1029,23 +1033,20 @@ static BROTLI_BOOL EncodeData(
|
|
1029
1033
|
|
1030
1034
|
if (s->params.quality == ZOPFLIFICATION_QUALITY) {
|
1031
1035
|
BROTLI_DCHECK(s->params.hasher.type == 10);
|
1032
|
-
BrotliCreateZopfliBackwardReferences(m,
|
1033
|
-
bytes, wrapped_last_processed_pos,
|
1036
|
+
BrotliCreateZopfliBackwardReferences(m, bytes, wrapped_last_processed_pos,
|
1034
1037
|
data, mask, &s->params, s->hasher_, s->dist_cache_,
|
1035
1038
|
&s->last_insert_len_, &s->commands_[s->num_commands_],
|
1036
1039
|
&s->num_commands_, &s->num_literals_);
|
1037
1040
|
if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
|
1038
1041
|
} else if (s->params.quality == HQ_ZOPFLIFICATION_QUALITY) {
|
1039
1042
|
BROTLI_DCHECK(s->params.hasher.type == 10);
|
1040
|
-
BrotliCreateHqZopfliBackwardReferences(m,
|
1041
|
-
bytes, wrapped_last_processed_pos,
|
1043
|
+
BrotliCreateHqZopfliBackwardReferences(m, bytes, wrapped_last_processed_pos,
|
1042
1044
|
data, mask, &s->params, s->hasher_, s->dist_cache_,
|
1043
1045
|
&s->last_insert_len_, &s->commands_[s->num_commands_],
|
1044
1046
|
&s->num_commands_, &s->num_literals_);
|
1045
1047
|
if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
|
1046
1048
|
} else {
|
1047
|
-
BrotliCreateBackwardReferences(
|
1048
|
-
bytes, wrapped_last_processed_pos,
|
1049
|
+
BrotliCreateBackwardReferences(bytes, wrapped_last_processed_pos,
|
1049
1050
|
data, mask, &s->params, s->hasher_, s->dist_cache_,
|
1050
1051
|
&s->last_insert_len_, &s->commands_[s->num_commands_],
|
1051
1052
|
&s->num_commands_, &s->num_literals_);
|
@@ -1166,7 +1167,6 @@ static BROTLI_BOOL BrotliCompressBufferQuality10(
|
|
1166
1167
|
MemoryManager* m = &memory_manager;
|
1167
1168
|
|
1168
1169
|
const size_t mask = BROTLI_SIZE_MAX >> 1;
|
1169
|
-
const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(lgwin);
|
1170
1170
|
int dist_cache[4] = { 4, 11, 15, 16 };
|
1171
1171
|
int saved_dist_cache[4] = { 4, 11, 15, 16 };
|
1172
1172
|
BROTLI_BOOL ok = BROTLI_TRUE;
|
@@ -1176,8 +1176,8 @@ static BROTLI_BOOL BrotliCompressBufferQuality10(
|
|
1176
1176
|
uint8_t last_bytes_bits;
|
1177
1177
|
HasherHandle hasher = NULL;
|
1178
1178
|
|
1179
|
-
const size_t hasher_eff_size =
|
1180
|
-
|
1179
|
+
const size_t hasher_eff_size = BROTLI_MIN(size_t,
|
1180
|
+
input_size, BROTLI_MAX_BACKWARD_LIMIT(lgwin) + BROTLI_WINDOW_GAP);
|
1181
1181
|
|
1182
1182
|
BrotliEncoderParams params;
|
1183
1183
|
|
@@ -1238,9 +1238,9 @@ static BROTLI_BOOL BrotliCompressBufferQuality10(
|
|
1238
1238
|
BrotliInitZopfliNodes(nodes, block_size + 1);
|
1239
1239
|
StitchToPreviousBlockH10(hasher, block_size, block_start,
|
1240
1240
|
input_buffer, mask);
|
1241
|
-
path_size = BrotliZopfliComputeShortestPath(m,
|
1242
|
-
|
1243
|
-
|
1241
|
+
path_size = BrotliZopfliComputeShortestPath(m, block_size, block_start,
|
1242
|
+
input_buffer, mask, ¶ms, dist_cache, hasher,
|
1243
|
+
nodes);
|
1244
1244
|
if (BROTLI_IS_OOM(m)) goto oom;
|
1245
1245
|
/* We allocate a command buffer in the first iteration of this loop that
|
1246
1246
|
will be likely big enough for the whole metablock, so that for most
|
@@ -1262,10 +1262,8 @@ static BROTLI_BOOL BrotliCompressBufferQuality10(
|
|
1262
1262
|
}
|
1263
1263
|
commands = new_commands;
|
1264
1264
|
}
|
1265
|
-
BrotliZopfliCreateCommands(block_size, block_start,
|
1266
|
-
|
1267
|
-
¶ms, &commands[num_commands],
|
1268
|
-
&num_literals);
|
1265
|
+
BrotliZopfliCreateCommands(block_size, block_start, &nodes[0], dist_cache,
|
1266
|
+
&last_insert_len, ¶ms, &commands[num_commands], &num_literals);
|
1269
1267
|
num_commands += path_size;
|
1270
1268
|
block_start += block_size;
|
1271
1269
|
metablock_size += block_size;
|
data/vendor/brotli/c/enc/hash.h
CHANGED
@@ -149,9 +149,9 @@ static BROTLI_INLINE score_t BackwardReferencePenaltyUsingLastDistance(
|
|
149
149
|
}
|
150
150
|
|
151
151
|
static BROTLI_INLINE BROTLI_BOOL TestStaticDictionaryItem(
|
152
|
-
const BrotliEncoderDictionary* dictionary, size_t item,
|
153
|
-
|
154
|
-
HasherSearchResult* out) {
|
152
|
+
const BrotliEncoderDictionary* dictionary, size_t item,
|
153
|
+
const uint8_t* data, size_t max_length, size_t max_backward,
|
154
|
+
size_t max_distance, HasherSearchResult* out) {
|
155
155
|
size_t len;
|
156
156
|
size_t word_idx;
|
157
157
|
size_t offset;
|
@@ -208,7 +208,8 @@ static BROTLI_INLINE void SearchInStaticDictionary(
|
|
208
208
|
self->dict_num_lookups++;
|
209
209
|
if (item != 0) {
|
210
210
|
BROTLI_BOOL item_matches = TestStaticDictionaryItem(
|
211
|
-
dictionary, item, data,
|
211
|
+
dictionary, item, data,
|
212
|
+
max_length, max_backward, max_distance, out);
|
212
213
|
if (item_matches) {
|
213
214
|
self->dict_num_matches++;
|
214
215
|
}
|
@@ -121,13 +121,16 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
|
|
121
121
|
const BrotliEncoderDictionary* dictionary,
|
122
122
|
const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
|
123
123
|
const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
|
124
|
-
const size_t max_length, const size_t max_backward,
|
125
|
-
const size_t
|
124
|
+
const size_t max_length, const size_t max_backward,
|
125
|
+
const size_t gap, const size_t max_distance,
|
126
|
+
HasherSearchResult* BROTLI_RESTRICT out) {
|
126
127
|
HashComposite* self = FN(Self)(handle);
|
127
128
|
FN_A(FindLongestMatch)(self->ha, dictionary, data, ring_buffer_mask,
|
128
|
-
distance_cache, cur_ix, max_length, max_backward, gap,
|
129
|
+
distance_cache, cur_ix, max_length, max_backward, gap,
|
130
|
+
max_distance, out);
|
129
131
|
FN_B(FindLongestMatch)(self->hb, dictionary, data, ring_buffer_mask,
|
130
|
-
distance_cache, cur_ix, max_length, max_backward, gap,
|
132
|
+
distance_cache, cur_ix, max_length, max_backward, gap,
|
133
|
+
max_distance, out);
|
131
134
|
}
|
132
135
|
|
133
136
|
#undef HashComposite
|
@@ -161,8 +161,9 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
|
|
161
161
|
const BrotliEncoderDictionary* dictionary,
|
162
162
|
const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
|
163
163
|
const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
|
164
|
-
const size_t max_length, const size_t max_backward,
|
165
|
-
const size_t
|
164
|
+
const size_t max_length, const size_t max_backward,
|
165
|
+
const size_t gap, const size_t max_distance,
|
166
|
+
HasherSearchResult* BROTLI_RESTRICT out) {
|
166
167
|
HasherCommon* common = GetHasherCommon(handle);
|
167
168
|
HashLongestMatch* self = FN(Self)(handle);
|
168
169
|
uint16_t* num = FN(Num)(self);
|
@@ -154,8 +154,9 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
|
|
154
154
|
const BrotliEncoderDictionary* dictionary,
|
155
155
|
const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
|
156
156
|
const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
|
157
|
-
const size_t max_length, const size_t max_backward,
|
158
|
-
const size_t
|
157
|
+
const size_t max_length, const size_t max_backward,
|
158
|
+
const size_t gap, const size_t max_distance,
|
159
|
+
HasherSearchResult* BROTLI_RESTRICT out) {
|
159
160
|
HasherCommon* common = GetHasherCommon(handle);
|
160
161
|
HashLongestMatch* self = FN(Self)(handle);
|
161
162
|
uint16_t* num = FN(Num)(self);
|
@@ -155,8 +155,9 @@ static BROTLI_INLINE void FN(FindLongestMatch)(HasherHandle handle,
|
|
155
155
|
const BrotliEncoderDictionary* dictionary,
|
156
156
|
const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
|
157
157
|
const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
|
158
|
-
const size_t max_length, const size_t max_backward,
|
159
|
-
const size_t
|
158
|
+
const size_t max_length, const size_t max_backward,
|
159
|
+
const size_t gap, const size_t max_distance,
|
160
|
+
HasherSearchResult* BROTLI_RESTRICT out) {
|
160
161
|
HashRolling* self = FN(Self)(handle);
|
161
162
|
const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
|
162
163
|
size_t pos = self->next_ix;
|
@@ -202,8 +202,9 @@ static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)(
|
|
202
202
|
static BROTLI_INLINE size_t FN(FindAllMatches)(HasherHandle handle,
|
203
203
|
const BrotliEncoderDictionary* dictionary, const uint8_t* data,
|
204
204
|
const size_t ring_buffer_mask, const size_t cur_ix,
|
205
|
-
const size_t max_length, const size_t max_backward,
|
206
|
-
const BrotliEncoderParams* params,
|
205
|
+
const size_t max_length, const size_t max_backward,
|
206
|
+
const size_t gap, const BrotliEncoderParams* params,
|
207
|
+
BackwardMatch* matches) {
|
207
208
|
BackwardMatch* const orig_matches = matches;
|
208
209
|
const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
|
209
210
|
size_t best_len = 1;
|
@@ -181,7 +181,8 @@ void BrotliBuildMetaBlock(MemoryManager* m,
|
|
181
181
|
ComputeDistanceCost(cmds, num_commands,
|
182
182
|
&orig_params.dist, &orig_params.dist, &dist_cost);
|
183
183
|
if (dist_cost < best_dist_cost) {
|
184
|
-
|
184
|
+
/* NB: currently unused; uncomment when more param tuning is added. */
|
185
|
+
/* best_dist_cost = dist_cost; */
|
185
186
|
params->dist = orig_params.dist;
|
186
187
|
}
|
187
188
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brotli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- miyucy
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -229,7 +229,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
229
229
|
version: '0'
|
230
230
|
requirements: []
|
231
231
|
rubyforge_project:
|
232
|
-
rubygems_version: 2.7.
|
232
|
+
rubygems_version: 2.7.7
|
233
233
|
signing_key:
|
234
234
|
specification_version: 4
|
235
235
|
summary: Brotli compressor/decompressor
|