parent
65fa775ff6
commit
7770e4447d
|
@ -47,12 +47,13 @@ fix build with our own copy of zstd (patch in `patches`).
|
||||||
## brotli
|
## brotli
|
||||||
|
|
||||||
- Upstream: https://github.com/google/brotli
|
- Upstream: https://github.com/google/brotli
|
||||||
- Version: git (f4153a09f87cbb9c826d8fc12c74642bb2d879ea, 2022)
|
- Version: git (ed1995b6bda19244070ab5d331111f16f67c8054, 2023)
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|
||||||
Files extracted from upstream source:
|
Files extracted from upstream source:
|
||||||
|
|
||||||
- `common/`, `dec/` and `include/` folders
|
- `common/`, `dec/` and `include/` folders from `c/`,
|
||||||
|
minus the `dictionary.bin*` files
|
||||||
- `LICENSE`
|
- `LICENSE`
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,11 @@
|
||||||
#ifndef BROTLI_COMMON_CONSTANTS_H_
|
#ifndef BROTLI_COMMON_CONSTANTS_H_
|
||||||
#define BROTLI_COMMON_CONSTANTS_H_
|
#define BROTLI_COMMON_CONSTANTS_H_
|
||||||
|
|
||||||
#include "platform.h"
|
|
||||||
#include <brotli/port.h>
|
#include <brotli/port.h>
|
||||||
#include <brotli/types.h>
|
#include <brotli/types.h>
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
|
||||||
/* Specification: 7.3. Encoding of the context map */
|
/* Specification: 7.3. Encoding of the context map */
|
||||||
#define BROTLI_CONTEXT_MAP_MAX_RLE 16
|
#define BROTLI_CONTEXT_MAP_MAX_RLE 16
|
||||||
|
|
||||||
|
|
|
@ -5897,7 +5897,7 @@ static BrotliDictionary kBrotliDictionary = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
const BrotliDictionary* BrotliGetDictionary() {
|
const BrotliDictionary* BrotliGetDictionary(void) {
|
||||||
return &kBrotliDictionary;
|
return &kBrotliDictionary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,10 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "platform.h"
|
|
||||||
#include <brotli/types.h>
|
#include <brotli/types.h>
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
|
||||||
/* Default brotli_alloc_func */
|
/* Default brotli_alloc_func */
|
||||||
void* BrotliDefaultAllocFunc(void* opaque, size_t size) {
|
void* BrotliDefaultAllocFunc(void* opaque, size_t size) {
|
||||||
BROTLI_UNUSED(opaque);
|
BROTLI_UNUSED(opaque);
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
* BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations
|
* BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations
|
||||||
* BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations
|
* BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations
|
||||||
* BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations
|
* BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations
|
||||||
* BROTLI_BUILD_PORTABLE disables dangerous optimizations, like unaligned
|
|
||||||
read and overlapping memcpy; this reduces decompression speed by 5%
|
|
||||||
* BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs
|
* BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs
|
||||||
|
* BROTLI_BUILD_NO_UNALIGNED_READ_FAST forces off the fast-unaligned-read
|
||||||
|
optimizations (mainly for testing purposes).
|
||||||
* BROTLI_DEBUG dumps file name and line number when decoder detects stream
|
* BROTLI_DEBUG dumps file name and line number when decoder detects stream
|
||||||
or memory error
|
or memory error
|
||||||
* BROTLI_ENABLE_LOG enables asserts and dumps various state information
|
* BROTLI_ENABLE_LOG enables asserts and dumps various state information
|
||||||
|
@ -208,15 +208,19 @@ OR:
|
||||||
#define BROTLI_TARGET_RISCV64
|
#define BROTLI_TARGET_RISCV64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \
|
||||||
|
defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64)
|
||||||
|
#define BROTLI_TARGET_64_BITS 1
|
||||||
|
#else
|
||||||
|
#define BROTLI_TARGET_64_BITS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(BROTLI_BUILD_64_BIT)
|
#if defined(BROTLI_BUILD_64_BIT)
|
||||||
#define BROTLI_64_BITS 1
|
#define BROTLI_64_BITS 1
|
||||||
#elif defined(BROTLI_BUILD_32_BIT)
|
#elif defined(BROTLI_BUILD_32_BIT)
|
||||||
#define BROTLI_64_BITS 0
|
#define BROTLI_64_BITS 0
|
||||||
#elif defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \
|
|
||||||
defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64)
|
|
||||||
#define BROTLI_64_BITS 1
|
|
||||||
#else
|
#else
|
||||||
#define BROTLI_64_BITS 0
|
#define BROTLI_64_BITS BROTLI_TARGET_64_BITS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (BROTLI_64_BITS)
|
#if (BROTLI_64_BITS)
|
||||||
|
@ -260,18 +264,19 @@ OR:
|
||||||
#undef BROTLI_X_BIG_ENDIAN
|
#undef BROTLI_X_BIG_ENDIAN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BROTLI_BUILD_PORTABLE)
|
#if defined(BROTLI_BUILD_NO_UNALIGNED_READ_FAST)
|
||||||
#define BROTLI_ALIGNED_READ (!!1)
|
#define BROTLI_UNALIGNED_READ_FAST (!!0)
|
||||||
#elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
|
#elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
|
||||||
defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) || \
|
defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) || \
|
||||||
defined(BROTLI_TARGET_RISCV64)
|
defined(BROTLI_TARGET_RISCV64)
|
||||||
/* Allow unaligned read only for white-listed CPUs. */
|
/* These targets are known to generate efficient code for unaligned reads
|
||||||
#define BROTLI_ALIGNED_READ (!!0)
|
* (e.g. a single instruction, not multiple 1-byte loads, shifted and or'd
|
||||||
|
* together). */
|
||||||
|
#define BROTLI_UNALIGNED_READ_FAST (!!1)
|
||||||
#else
|
#else
|
||||||
#define BROTLI_ALIGNED_READ (!!1)
|
#define BROTLI_UNALIGNED_READ_FAST (!!0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BROTLI_ALIGNED_READ
|
|
||||||
/* Portable unaligned memory access: read / write values via memcpy. */
|
/* Portable unaligned memory access: read / write values via memcpy. */
|
||||||
static BROTLI_INLINE uint16_t BrotliUnalignedRead16(const void* p) {
|
static BROTLI_INLINE uint16_t BrotliUnalignedRead16(const void* p) {
|
||||||
uint16_t t;
|
uint16_t t;
|
||||||
|
@ -291,75 +296,6 @@ static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) {
|
||||||
static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
|
static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
|
||||||
memcpy(p, &v, sizeof v);
|
memcpy(p, &v, sizeof v);
|
||||||
}
|
}
|
||||||
#else /* BROTLI_ALIGNED_READ */
|
|
||||||
/* Unaligned memory access is allowed: just cast pointer to requested type. */
|
|
||||||
#if BROTLI_SANITIZED
|
|
||||||
/* Consider we have an unaligned load/store of 4 bytes from address 0x...05.
|
|
||||||
AddressSanitizer will treat it as a 3-byte access to the range 05:07 and
|
|
||||||
will miss a bug if 08 is the first unaddressable byte.
|
|
||||||
ThreadSanitizer will also treat this as a 3-byte access to 05:07 and will
|
|
||||||
miss a race between this access and some other accesses to 08.
|
|
||||||
MemorySanitizer will correctly propagate the shadow on unaligned stores
|
|
||||||
and correctly report bugs on unaligned loads, but it may not properly
|
|
||||||
update and report the origin of the uninitialized memory.
|
|
||||||
For all three tools, replacing an unaligned access with a tool-specific
|
|
||||||
callback solves the problem. */
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
uint16_t __sanitizer_unaligned_load16(const void* p);
|
|
||||||
uint32_t __sanitizer_unaligned_load32(const void* p);
|
|
||||||
uint64_t __sanitizer_unaligned_load64(const void* p);
|
|
||||||
void __sanitizer_unaligned_store64(void* p, uint64_t v);
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#define BrotliUnalignedRead16 __sanitizer_unaligned_load16
|
|
||||||
#define BrotliUnalignedRead32 __sanitizer_unaligned_load32
|
|
||||||
#define BrotliUnalignedRead64 __sanitizer_unaligned_load64
|
|
||||||
#define BrotliUnalignedWrite64 __sanitizer_unaligned_store64
|
|
||||||
#else /* BROTLI_SANITIZED */
|
|
||||||
static BROTLI_INLINE uint16_t BrotliUnalignedRead16(const void* p) {
|
|
||||||
return *(const uint16_t*)p;
|
|
||||||
}
|
|
||||||
static BROTLI_INLINE uint32_t BrotliUnalignedRead32(const void* p) {
|
|
||||||
return *(const uint32_t*)p;
|
|
||||||
}
|
|
||||||
#if (BROTLI_64_BITS)
|
|
||||||
static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) {
|
|
||||||
return *(const uint64_t*)p;
|
|
||||||
}
|
|
||||||
static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
|
|
||||||
*(uint64_t*)p = v;
|
|
||||||
}
|
|
||||||
#else /* BROTLI_64_BITS */
|
|
||||||
/* Avoid emitting LDRD / STRD, which require properly aligned address. */
|
|
||||||
/* If __attribute__(aligned) is available, use that. Otherwise, memcpy. */
|
|
||||||
|
|
||||||
#if BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0)
|
|
||||||
typedef BROTLI_ALIGNED(1) uint64_t brotli_unaligned_uint64_t;
|
|
||||||
|
|
||||||
static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) {
|
|
||||||
return (uint64_t) ((const brotli_unaligned_uint64_t*) p)[0];
|
|
||||||
}
|
|
||||||
static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
|
|
||||||
brotli_unaligned_uint64_t* dwords = (brotli_unaligned_uint64_t*) p;
|
|
||||||
dwords[0] = (brotli_unaligned_uint64_t) v;
|
|
||||||
}
|
|
||||||
#else /* BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0) */
|
|
||||||
static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) {
|
|
||||||
uint64_t v;
|
|
||||||
memcpy(&v, p, sizeof(uint64_t));
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
|
|
||||||
memcpy(p, &v, sizeof(uint64_t));
|
|
||||||
}
|
|
||||||
#endif /* BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0) */
|
|
||||||
#endif /* BROTLI_64_BITS */
|
|
||||||
#endif /* BROTLI_SANITIZED */
|
|
||||||
#endif /* BROTLI_ALIGNED_READ */
|
|
||||||
|
|
||||||
#if BROTLI_LITTLE_ENDIAN
|
#if BROTLI_LITTLE_ENDIAN
|
||||||
/* Straight endianness. Just read / write values. */
|
/* Straight endianness. Just read / write values. */
|
||||||
|
@ -435,6 +371,16 @@ static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) {
|
||||||
}
|
}
|
||||||
#endif /* BROTLI_LITTLE_ENDIAN */
|
#endif /* BROTLI_LITTLE_ENDIAN */
|
||||||
|
|
||||||
|
static BROTLI_INLINE void* BROTLI_UNALIGNED_LOAD_PTR(const void* p) {
|
||||||
|
void* v;
|
||||||
|
memcpy(&v, p, sizeof(void*));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BROTLI_INLINE void BROTLI_UNALIGNED_STORE_PTR(void* p, const void* v) {
|
||||||
|
memcpy(p, &v, sizeof(void*));
|
||||||
|
}
|
||||||
|
|
||||||
/* BROTLI_IS_CONSTANT macros returns true for compile-time constants. */
|
/* BROTLI_IS_CONSTANT macros returns true for compile-time constants. */
|
||||||
#if BROTLI_GNUC_HAS_BUILTIN(__builtin_constant_p, 3, 0, 1) || \
|
#if BROTLI_GNUC_HAS_BUILTIN(__builtin_constant_p, 3, 0, 1) || \
|
||||||
BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
|
BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
|
||||||
|
@ -467,6 +413,8 @@ static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) {
|
||||||
#define BROTLI_DUMP() (void)(0)
|
#define BROTLI_DUMP() (void)(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* BrotliRBit assumes brotli_reg_t fits native CPU register type. */
|
||||||
|
#if (BROTLI_64_BITS == BROTLI_TARGET_64_BITS)
|
||||||
/* TODO(eustas): add appropriate icc/sunpro/arm/ibm/ti checks. */
|
/* TODO(eustas): add appropriate icc/sunpro/arm/ibm/ti checks. */
|
||||||
#if (BROTLI_GNUC_VERSION_CHECK(3, 0, 0) || defined(__llvm__)) && \
|
#if (BROTLI_GNUC_VERSION_CHECK(3, 0, 0) || defined(__llvm__)) && \
|
||||||
!defined(BROTLI_BUILD_NO_RBIT)
|
!defined(BROTLI_BUILD_NO_RBIT)
|
||||||
|
@ -480,15 +428,14 @@ static BROTLI_INLINE brotli_reg_t BrotliRBit(brotli_reg_t input) {
|
||||||
#define BROTLI_RBIT(x) BrotliRBit(x)
|
#define BROTLI_RBIT(x) BrotliRBit(x)
|
||||||
#endif /* armv7 / armv8 */
|
#endif /* armv7 / armv8 */
|
||||||
#endif /* gcc || clang */
|
#endif /* gcc || clang */
|
||||||
|
#endif /* brotli_reg_t is native */
|
||||||
#if !defined(BROTLI_RBIT)
|
#if !defined(BROTLI_RBIT)
|
||||||
static BROTLI_INLINE void BrotliRBit(void) { /* Should break build if used. */ }
|
static BROTLI_INLINE void BrotliRBit(void) { /* Should break build if used. */ }
|
||||||
#endif /* BROTLI_RBIT */
|
#endif /* BROTLI_RBIT */
|
||||||
|
|
||||||
#define BROTLI_REPEAT(N, X) { \
|
#define BROTLI_REPEAT_4(X) {X; X; X; X;}
|
||||||
if ((N & 1) != 0) {X;} \
|
#define BROTLI_REPEAT_5(X) {X; X; X; X; X;}
|
||||||
if ((N & 2) != 0) {X; X;} \
|
#define BROTLI_REPEAT_6(X) {X; X; X; X; X; X;}
|
||||||
if ((N & 4) != 0) {X; X; X; X;} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BROTLI_UNUSED(X) (void)(X)
|
#define BROTLI_UNUSED(X) (void)(X)
|
||||||
|
|
||||||
|
@ -553,6 +500,8 @@ BROTLI_UNUSED_FUNCTION void BrotliSuppressUnusedFunctions(void) {
|
||||||
BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD32LE);
|
BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD32LE);
|
||||||
BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD64LE);
|
BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD64LE);
|
||||||
BROTLI_UNUSED(&BROTLI_UNALIGNED_STORE64LE);
|
BROTLI_UNUSED(&BROTLI_UNALIGNED_STORE64LE);
|
||||||
|
BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD_PTR);
|
||||||
|
BROTLI_UNUSED(&BROTLI_UNALIGNED_STORE_PTR);
|
||||||
BROTLI_UNUSED(&BrotliRBit);
|
BROTLI_UNUSED(&BrotliRBit);
|
||||||
BROTLI_UNUSED(&brotli_min_double);
|
BROTLI_UNUSED(&brotli_min_double);
|
||||||
BROTLI_UNUSED(&brotli_max_double);
|
BROTLI_UNUSED(&brotli_max_double);
|
||||||
|
|
|
@ -9,11 +9,12 @@
|
||||||
#ifndef BROTLI_COMMON_SHARED_DICTIONARY_INTERNAL_H_
|
#ifndef BROTLI_COMMON_SHARED_DICTIONARY_INTERNAL_H_
|
||||||
#define BROTLI_COMMON_SHARED_DICTIONARY_INTERNAL_H_
|
#define BROTLI_COMMON_SHARED_DICTIONARY_INTERNAL_H_
|
||||||
|
|
||||||
#include "dictionary.h"
|
|
||||||
#include <brotli/shared_dictionary.h>
|
#include <brotli/shared_dictionary.h>
|
||||||
#include "transform.h"
|
|
||||||
#include <brotli/types.h>
|
#include <brotli/types.h>
|
||||||
|
|
||||||
|
#include "dictionary.h"
|
||||||
|
#include "transform.h"
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,9 +8,10 @@
|
||||||
|
|
||||||
#include "bit_reader.h"
|
#include "bit_reader.h"
|
||||||
|
|
||||||
#include "../common/platform.h"
|
|
||||||
#include <brotli/types.h>
|
#include <brotli/types.h>
|
||||||
|
|
||||||
|
#include "../common/platform.h"
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -36,7 +37,7 @@ BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
|
||||||
/* Fixing alignment after unaligned BrotliFillWindow would result accumulator
|
/* Fixing alignment after unaligned BrotliFillWindow would result accumulator
|
||||||
overflow. If unalignment is caused by BrotliSafeReadBits, then there is
|
overflow. If unalignment is caused by BrotliSafeReadBits, then there is
|
||||||
enough space in accumulator to fix alignment. */
|
enough space in accumulator to fix alignment. */
|
||||||
if (!BROTLI_ALIGNED_READ) {
|
if (BROTLI_UNALIGNED_READ_FAST) {
|
||||||
aligned_read_mask = 0;
|
aligned_read_mask = 0;
|
||||||
}
|
}
|
||||||
if (BrotliGetAvailableBits(br) == 0) {
|
if (BrotliGetAvailableBits(br) == 0) {
|
||||||
|
|
|
@ -11,9 +11,10 @@
|
||||||
|
|
||||||
#include <string.h> /* memcpy */
|
#include <string.h> /* memcpy */
|
||||||
|
|
||||||
|
#include <brotli/types.h>
|
||||||
|
|
||||||
#include "../common/constants.h"
|
#include "../common/constants.h"
|
||||||
#include "../common/platform.h"
|
#include "../common/platform.h"
|
||||||
#include <brotli/types.h>
|
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -53,8 +54,8 @@ BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* const br);
|
||||||
/* Ensures that accumulator is not empty.
|
/* Ensures that accumulator is not empty.
|
||||||
May consume up to sizeof(brotli_reg_t) - 1 bytes of input.
|
May consume up to sizeof(brotli_reg_t) - 1 bytes of input.
|
||||||
Returns BROTLI_FALSE if data is required but there is no input available.
|
Returns BROTLI_FALSE if data is required but there is no input available.
|
||||||
For BROTLI_ALIGNED_READ this function also prepares bit reader for aligned
|
For !BROTLI_UNALIGNED_READ_FAST this function also prepares bit reader for
|
||||||
reading. */
|
aligned reading. */
|
||||||
BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br);
|
BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br);
|
||||||
|
|
||||||
/* Fallback for BrotliSafeReadBits32. Extracted as noninlined method to unburden
|
/* Fallback for BrotliSafeReadBits32. Extracted as noninlined method to unburden
|
||||||
|
@ -107,7 +108,8 @@ static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount(
|
||||||
static BROTLI_INLINE void BrotliFillBitWindow(
|
static BROTLI_INLINE void BrotliFillBitWindow(
|
||||||
BrotliBitReader* const br, uint32_t n_bits) {
|
BrotliBitReader* const br, uint32_t n_bits) {
|
||||||
#if (BROTLI_64_BITS)
|
#if (BROTLI_64_BITS)
|
||||||
if (!BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 8)) {
|
if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
|
||||||
|
(n_bits <= 8)) {
|
||||||
uint32_t bit_pos = br->bit_pos_;
|
uint32_t bit_pos = br->bit_pos_;
|
||||||
if (bit_pos >= 56) {
|
if (bit_pos >= 56) {
|
||||||
br->val_ =
|
br->val_ =
|
||||||
|
@ -117,8 +119,8 @@ static BROTLI_INLINE void BrotliFillBitWindow(
|
||||||
br->avail_in -= 7;
|
br->avail_in -= 7;
|
||||||
br->next_in += 7;
|
br->next_in += 7;
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
|
||||||
!BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 16)) {
|
(n_bits <= 16)) {
|
||||||
uint32_t bit_pos = br->bit_pos_;
|
uint32_t bit_pos = br->bit_pos_;
|
||||||
if (bit_pos >= 48) {
|
if (bit_pos >= 48) {
|
||||||
br->val_ =
|
br->val_ =
|
||||||
|
@ -140,7 +142,8 @@ static BROTLI_INLINE void BrotliFillBitWindow(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (!BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 8)) {
|
if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
|
||||||
|
(n_bits <= 8)) {
|
||||||
uint32_t bit_pos = br->bit_pos_;
|
uint32_t bit_pos = br->bit_pos_;
|
||||||
if (bit_pos >= 24) {
|
if (bit_pos >= 24) {
|
||||||
br->val_ =
|
br->val_ =
|
||||||
|
@ -338,6 +341,11 @@ static BROTLI_INLINE BROTLI_BOOL BrotliJumpToByteBoundary(BrotliBitReader* br) {
|
||||||
return TO_BROTLI_BOOL(pad_bits == 0);
|
return TO_BROTLI_BOOL(pad_bits == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BROTLI_INLINE void BrotliDropBytes(BrotliBitReader* br, size_t num) {
|
||||||
|
br->avail_in -= num;
|
||||||
|
br->next_in += num;
|
||||||
|
}
|
||||||
|
|
||||||
/* Copies remaining input bytes stored in the bit reader to the output. Value
|
/* Copies remaining input bytes stored in the bit reader to the output. Value
|
||||||
|num| may not be larger than BrotliGetRemainingBytes. The bit reader must be
|
|num| may not be larger than BrotliGetRemainingBytes. The bit reader must be
|
||||||
warmed up again after this. */
|
warmed up again after this. */
|
||||||
|
@ -349,9 +357,10 @@ static BROTLI_INLINE void BrotliCopyBytes(uint8_t* dest,
|
||||||
++dest;
|
++dest;
|
||||||
--num;
|
--num;
|
||||||
}
|
}
|
||||||
memcpy(dest, br->next_in, num);
|
if (num > 0) {
|
||||||
br->avail_in -= num;
|
memcpy(dest, br->next_in, num);
|
||||||
br->next_in += num;
|
BrotliDropBytes(br, num);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
|
|
|
@ -113,8 +113,9 @@ void BrotliDecoderDestroyInstance(BrotliDecoderState* state) {
|
||||||
|
|
||||||
/* Saves error code and converts it to BrotliDecoderResult. */
|
/* Saves error code and converts it to BrotliDecoderResult. */
|
||||||
static BROTLI_NOINLINE BrotliDecoderResult SaveErrorCode(
|
static BROTLI_NOINLINE BrotliDecoderResult SaveErrorCode(
|
||||||
BrotliDecoderState* s, BrotliDecoderErrorCode e) {
|
BrotliDecoderState* s, BrotliDecoderErrorCode e, size_t consumed_input) {
|
||||||
s->error_code = (int)e;
|
s->error_code = (int)e;
|
||||||
|
s->used_input += consumed_input;
|
||||||
switch (e) {
|
switch (e) {
|
||||||
case BROTLI_DECODER_SUCCESS:
|
case BROTLI_DECODER_SUCCESS:
|
||||||
return BROTLI_DECODER_RESULT_SUCCESS;
|
return BROTLI_DECODER_RESULT_SUCCESS;
|
||||||
|
@ -1172,7 +1173,7 @@ static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(
|
||||||
size_t sample = s->context_map[offset];
|
size_t sample = s->context_map[offset];
|
||||||
size_t j;
|
size_t j;
|
||||||
for (j = 0; j < (1u << BROTLI_LITERAL_CONTEXT_BITS);) {
|
for (j = 0; j < (1u << BROTLI_LITERAL_CONTEXT_BITS);) {
|
||||||
BROTLI_REPEAT(4, error |= s->context_map[offset + j++] ^ sample;)
|
BROTLI_REPEAT_4({ error |= s->context_map[offset + j++] ^ sample; })
|
||||||
}
|
}
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
s->trivial_literal_contexts[i >> 5] |= 1u << (i & 31);
|
s->trivial_literal_contexts[i >> 5] |= 1u << (i & 31);
|
||||||
|
@ -1353,6 +1354,57 @@ static BROTLI_BOOL BROTLI_NOINLINE BrotliEnsureRingBuffer(
|
||||||
return BROTLI_TRUE;
|
return BROTLI_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BrotliDecoderErrorCode BROTLI_NOINLINE
|
||||||
|
SkipMetadataBlock(BrotliDecoderState* s) {
|
||||||
|
BrotliBitReader* br = &s->br;
|
||||||
|
|
||||||
|
if (s->meta_block_remaining_len == 0) {
|
||||||
|
return BROTLI_DECODER_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
BROTLI_DCHECK((BrotliGetAvailableBits(br) & 7) == 0);
|
||||||
|
|
||||||
|
/* Drain accumulator. */
|
||||||
|
if (BrotliGetAvailableBits(br) >= 8) {
|
||||||
|
uint8_t buffer[8];
|
||||||
|
int nbytes = (int)(BrotliGetAvailableBits(br)) >> 3;
|
||||||
|
BROTLI_DCHECK(nbytes <= 8);
|
||||||
|
if (nbytes > s->meta_block_remaining_len) {
|
||||||
|
nbytes = s->meta_block_remaining_len;
|
||||||
|
}
|
||||||
|
BrotliCopyBytes(buffer, br, (size_t)nbytes);
|
||||||
|
if (s->metadata_chunk_func) {
|
||||||
|
s->metadata_chunk_func(s->metadata_callback_opaque, buffer,
|
||||||
|
(size_t)nbytes);
|
||||||
|
}
|
||||||
|
s->meta_block_remaining_len -= nbytes;
|
||||||
|
if (s->meta_block_remaining_len == 0) {
|
||||||
|
return BROTLI_DECODER_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Direct access to metadata is possible. */
|
||||||
|
int nbytes = (int)BrotliGetRemainingBytes(br);
|
||||||
|
if (nbytes > s->meta_block_remaining_len) {
|
||||||
|
nbytes = s->meta_block_remaining_len;
|
||||||
|
}
|
||||||
|
if (nbytes > 0) {
|
||||||
|
if (s->metadata_chunk_func) {
|
||||||
|
s->metadata_chunk_func(s->metadata_callback_opaque, br->next_in,
|
||||||
|
(size_t)nbytes);
|
||||||
|
}
|
||||||
|
BrotliDropBytes(br, (size_t)nbytes);
|
||||||
|
s->meta_block_remaining_len -= nbytes;
|
||||||
|
if (s->meta_block_remaining_len == 0) {
|
||||||
|
return BROTLI_DECODER_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BROTLI_DCHECK(BrotliGetRemainingBytes(br) == 0);
|
||||||
|
|
||||||
|
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
||||||
|
}
|
||||||
|
|
||||||
static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
|
static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
|
||||||
size_t* available_out, uint8_t** next_out, size_t* total_out,
|
size_t* available_out, uint8_t** next_out, size_t* total_out,
|
||||||
BrotliDecoderState* s) {
|
BrotliDecoderState* s) {
|
||||||
|
@ -2243,6 +2295,9 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||||
size_t* available_out, uint8_t** next_out, size_t* total_out) {
|
size_t* available_out, uint8_t** next_out, size_t* total_out) {
|
||||||
BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS;
|
BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS;
|
||||||
BrotliBitReader* br = &s->br;
|
BrotliBitReader* br = &s->br;
|
||||||
|
size_t input_size = *available_in;
|
||||||
|
#define BROTLI_SAVE_ERROR_CODE(code) \
|
||||||
|
SaveErrorCode(s, (code), input_size - *available_in)
|
||||||
/* Ensure that |total_out| is set, even if no data will ever be pushed out. */
|
/* Ensure that |total_out| is set, even if no data will ever be pushed out. */
|
||||||
if (total_out) {
|
if (total_out) {
|
||||||
*total_out = s->partial_pos_out;
|
*total_out = s->partial_pos_out;
|
||||||
|
@ -2252,8 +2307,8 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||||
return BROTLI_DECODER_RESULT_ERROR;
|
return BROTLI_DECODER_RESULT_ERROR;
|
||||||
}
|
}
|
||||||
if (*available_out && (!next_out || !*next_out)) {
|
if (*available_out && (!next_out || !*next_out)) {
|
||||||
return SaveErrorCode(
|
return BROTLI_SAVE_ERROR_CODE(
|
||||||
s, BROTLI_FAILURE(BROTLI_DECODER_ERROR_INVALID_ARGUMENTS));
|
BROTLI_FAILURE(BROTLI_DECODER_ERROR_INVALID_ARGUMENTS));
|
||||||
}
|
}
|
||||||
if (!*available_out) next_out = 0;
|
if (!*available_out) next_out = 0;
|
||||||
if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */
|
if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */
|
||||||
|
@ -2410,6 +2465,10 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||||
}
|
}
|
||||||
if (s->is_metadata) {
|
if (s->is_metadata) {
|
||||||
s->state = BROTLI_STATE_METADATA;
|
s->state = BROTLI_STATE_METADATA;
|
||||||
|
if (s->metadata_start_func) {
|
||||||
|
s->metadata_start_func(s->metadata_callback_opaque,
|
||||||
|
(size_t)s->meta_block_remaining_len);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (s->meta_block_remaining_len == 0) {
|
if (s->meta_block_remaining_len == 0) {
|
||||||
|
@ -2502,17 +2561,11 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||||
}
|
}
|
||||||
|
|
||||||
case BROTLI_STATE_METADATA:
|
case BROTLI_STATE_METADATA:
|
||||||
for (; s->meta_block_remaining_len > 0; --s->meta_block_remaining_len) {
|
result = SkipMetadataBlock(s);
|
||||||
uint32_t bits;
|
if (result != BROTLI_DECODER_SUCCESS) {
|
||||||
/* Read one byte and ignore it. */
|
break;
|
||||||
if (!BrotliSafeReadBits(br, 8, &bits)) {
|
|
||||||
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (result == BROTLI_DECODER_SUCCESS) {
|
|
||||||
s->state = BROTLI_STATE_METABLOCK_DONE;
|
|
||||||
}
|
}
|
||||||
|
s->state = BROTLI_STATE_METABLOCK_DONE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BROTLI_STATE_METABLOCK_HEADER_2: {
|
case BROTLI_STATE_METABLOCK_HEADER_2: {
|
||||||
|
@ -2586,7 +2639,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||||
s, &s->distance_hgroup, distance_alphabet_size_max,
|
s, &s->distance_hgroup, distance_alphabet_size_max,
|
||||||
distance_alphabet_size_limit, s->num_dist_htrees);
|
distance_alphabet_size_limit, s->num_dist_htrees);
|
||||||
if (!allocation_success) {
|
if (!allocation_success) {
|
||||||
return SaveErrorCode(s,
|
return BROTLI_SAVE_ERROR_CODE(
|
||||||
BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS));
|
BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS));
|
||||||
}
|
}
|
||||||
s->loop_counter = 0;
|
s->loop_counter = 0;
|
||||||
|
@ -2600,7 +2653,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||||
case 0: hgroup = &s->literal_hgroup; break;
|
case 0: hgroup = &s->literal_hgroup; break;
|
||||||
case 1: hgroup = &s->insert_copy_hgroup; break;
|
case 1: hgroup = &s->insert_copy_hgroup; break;
|
||||||
case 2: hgroup = &s->distance_hgroup; break;
|
case 2: hgroup = &s->distance_hgroup; break;
|
||||||
default: return SaveErrorCode(s, BROTLI_FAILURE(
|
default: return BROTLI_SAVE_ERROR_CODE(BROTLI_FAILURE(
|
||||||
BROTLI_DECODER_ERROR_UNREACHABLE)); /* COV_NF_LINE */
|
BROTLI_DECODER_ERROR_UNREACHABLE)); /* COV_NF_LINE */
|
||||||
}
|
}
|
||||||
result = HuffmanTreeGroupDecode(hgroup, s);
|
result = HuffmanTreeGroupDecode(hgroup, s);
|
||||||
|
@ -2710,10 +2763,11 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SaveErrorCode(s, result);
|
return BROTLI_SAVE_ERROR_CODE(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SaveErrorCode(s, result);
|
return BROTLI_SAVE_ERROR_CODE(result);
|
||||||
|
#undef BROTLI_SAVE_ERROR_CODE
|
||||||
}
|
}
|
||||||
|
|
||||||
BROTLI_BOOL BrotliDecoderHasMoreOutput(const BrotliDecoderState* s) {
|
BROTLI_BOOL BrotliDecoderHasMoreOutput(const BrotliDecoderState* s) {
|
||||||
|
@ -2743,7 +2797,7 @@ const uint8_t* BrotliDecoderTakeOutput(BrotliDecoderState* s, size_t* size) {
|
||||||
} else {
|
} else {
|
||||||
/* ... or stream is broken. Normally this should be caught by
|
/* ... or stream is broken. Normally this should be caught by
|
||||||
BrotliDecoderDecompressStream, this is just a safeguard. */
|
BrotliDecoderDecompressStream, this is just a safeguard. */
|
||||||
if ((int)status < 0) SaveErrorCode(s, status);
|
if ((int)status < 0) SaveErrorCode(s, status, 0);
|
||||||
*size = 0;
|
*size = 0;
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
|
@ -2776,10 +2830,19 @@ const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t BrotliDecoderVersion() {
|
uint32_t BrotliDecoderVersion(void) {
|
||||||
return BROTLI_VERSION;
|
return BROTLI_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BrotliDecoderSetMetadataCallbacks(
|
||||||
|
BrotliDecoderState* state,
|
||||||
|
brotli_decoder_metadata_start_func start_func,
|
||||||
|
brotli_decoder_metadata_chunk_func chunk_func, void* opaque) {
|
||||||
|
state->metadata_start_func = start_func;
|
||||||
|
state->metadata_chunk_func = chunk_func;
|
||||||
|
state->metadata_callback_opaque = opaque;
|
||||||
|
}
|
||||||
|
|
||||||
/* Escalate internal functions visibility; for testing purposes only. */
|
/* Escalate internal functions visibility; for testing purposes only. */
|
||||||
#if defined(BROTLI_TEST)
|
#if defined(BROTLI_TEST)
|
||||||
BROTLI_BOOL SafeReadSymbolForTest(
|
BROTLI_BOOL SafeReadSymbolForTest(
|
||||||
|
|
|
@ -10,9 +10,10 @@
|
||||||
|
|
||||||
#include <string.h> /* memcpy, memset */
|
#include <string.h> /* memcpy, memset */
|
||||||
|
|
||||||
|
#include <brotli/types.h>
|
||||||
|
|
||||||
#include "../common/constants.h"
|
#include "../common/constants.h"
|
||||||
#include "../common/platform.h"
|
#include "../common/platform.h"
|
||||||
#include <brotli/types.h>
|
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -117,11 +118,13 @@ void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
|
||||||
int bits_count;
|
int bits_count;
|
||||||
BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH <=
|
BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH <=
|
||||||
BROTLI_REVERSE_BITS_MAX);
|
BROTLI_REVERSE_BITS_MAX);
|
||||||
|
BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH == 5);
|
||||||
|
|
||||||
/* Generate offsets into sorted symbol table by code length. */
|
/* Generate offsets into sorted symbol table by code length. */
|
||||||
symbol = -1;
|
symbol = -1;
|
||||||
bits = 1;
|
bits = 1;
|
||||||
BROTLI_REPEAT(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH, {
|
/* BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH == 5 */
|
||||||
|
BROTLI_REPEAT_5({
|
||||||
symbol += count[bits];
|
symbol += count[bits];
|
||||||
offset[bits] = symbol;
|
offset[bits] = symbol;
|
||||||
bits++;
|
bits++;
|
||||||
|
@ -132,7 +135,7 @@ void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
|
||||||
/* Sort symbols by length, by symbol order within each length. */
|
/* Sort symbols by length, by symbol order within each length. */
|
||||||
symbol = BROTLI_CODE_LENGTH_CODES;
|
symbol = BROTLI_CODE_LENGTH_CODES;
|
||||||
do {
|
do {
|
||||||
BROTLI_REPEAT(6, {
|
BROTLI_REPEAT_6({
|
||||||
symbol--;
|
symbol--;
|
||||||
sorted[offset[code_lengths[symbol]]--] = symbol;
|
sorted[offset[code_lengths[symbol]]--] = symbol;
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,9 +9,10 @@
|
||||||
#ifndef BROTLI_DEC_HUFFMAN_H_
|
#ifndef BROTLI_DEC_HUFFMAN_H_
|
||||||
#define BROTLI_DEC_HUFFMAN_H_
|
#define BROTLI_DEC_HUFFMAN_H_
|
||||||
|
|
||||||
#include "../common/platform.h"
|
|
||||||
#include <brotli/types.h>
|
#include <brotli/types.h>
|
||||||
|
|
||||||
|
#include "../common/platform.h"
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,9 +10,10 @@
|
||||||
#ifndef BROTLI_DEC_PREFIX_H_
|
#ifndef BROTLI_DEC_PREFIX_H_
|
||||||
#define BROTLI_DEC_PREFIX_H_
|
#define BROTLI_DEC_PREFIX_H_
|
||||||
|
|
||||||
#include "../common/constants.h"
|
|
||||||
#include <brotli/types.h>
|
#include <brotli/types.h>
|
||||||
|
|
||||||
|
#include "../common/constants.h"
|
||||||
|
|
||||||
typedef struct CmdLutElement {
|
typedef struct CmdLutElement {
|
||||||
uint8_t insert_len_extra_bits;
|
uint8_t insert_len_extra_bits;
|
||||||
uint8_t copy_len_extra_bits;
|
uint8_t copy_len_extra_bits;
|
||||||
|
|
|
@ -8,8 +8,9 @@
|
||||||
|
|
||||||
#include <stdlib.h> /* free, malloc */
|
#include <stdlib.h> /* free, malloc */
|
||||||
|
|
||||||
#include "../common/dictionary.h"
|
|
||||||
#include <brotli/types.h>
|
#include <brotli/types.h>
|
||||||
|
|
||||||
|
#include "../common/dictionary.h"
|
||||||
#include "huffman.h"
|
#include "huffman.h"
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
|
@ -43,6 +44,7 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
|
||||||
s->pos = 0;
|
s->pos = 0;
|
||||||
s->rb_roundtrips = 0;
|
s->rb_roundtrips = 0;
|
||||||
s->partial_pos_out = 0;
|
s->partial_pos_out = 0;
|
||||||
|
s->used_input = 0;
|
||||||
|
|
||||||
s->block_type_trees = NULL;
|
s->block_type_trees = NULL;
|
||||||
s->block_len_trees = NULL;
|
s->block_len_trees = NULL;
|
||||||
|
@ -87,6 +89,10 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
|
||||||
BrotliSharedDictionaryCreateInstance(alloc_func, free_func, opaque);
|
BrotliSharedDictionaryCreateInstance(alloc_func, free_func, opaque);
|
||||||
if (!s->dictionary) return BROTLI_FALSE;
|
if (!s->dictionary) return BROTLI_FALSE;
|
||||||
|
|
||||||
|
s->metadata_start_func = NULL;
|
||||||
|
s->metadata_chunk_func = NULL;
|
||||||
|
s->metadata_callback_opaque = 0;
|
||||||
|
|
||||||
return BROTLI_TRUE;
|
return BROTLI_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,9 +135,21 @@ void BrotliDecoderStateCleanupAfterMetablock(BrotliDecoderState* s) {
|
||||||
BROTLI_DECODER_FREE(s, s->distance_hgroup.htrees);
|
BROTLI_DECODER_FREE(s, s->distance_hgroup.htrees);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BROTLI_REPORTING
|
||||||
|
/* When BROTLI_REPORTING is defined extra reporting module have to be linked. */
|
||||||
|
void BrotliDecoderOnFinish(const BrotliDecoderState* s);
|
||||||
|
#define BROTLI_DECODER_ON_FINISH(s) BrotliDecoderOnFinish(s);
|
||||||
|
#else
|
||||||
|
#if !defined(BROTLI_DECODER_ON_FINISH)
|
||||||
|
#define BROTLI_DECODER_ON_FINISH(s) (void)(s);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
void BrotliDecoderStateCleanup(BrotliDecoderState* s) {
|
void BrotliDecoderStateCleanup(BrotliDecoderState* s) {
|
||||||
BrotliDecoderStateCleanupAfterMetablock(s);
|
BrotliDecoderStateCleanupAfterMetablock(s);
|
||||||
|
|
||||||
|
BROTLI_DECODER_ON_FINISH(s);
|
||||||
|
|
||||||
BROTLI_DECODER_FREE(s, s->compound_dictionary);
|
BROTLI_DECODER_FREE(s, s->compound_dictionary);
|
||||||
BrotliSharedDictionaryDestroyInstance(s->dictionary);
|
BrotliSharedDictionaryDestroyInstance(s->dictionary);
|
||||||
s->dictionary = NULL;
|
s->dictionary = NULL;
|
||||||
|
|
|
@ -9,12 +9,14 @@
|
||||||
#ifndef BROTLI_DEC_STATE_H_
|
#ifndef BROTLI_DEC_STATE_H_
|
||||||
#define BROTLI_DEC_STATE_H_
|
#define BROTLI_DEC_STATE_H_
|
||||||
|
|
||||||
|
#include <brotli/decode.h>
|
||||||
|
#include <brotli/shared_dictionary.h>
|
||||||
|
#include <brotli/types.h>
|
||||||
|
|
||||||
#include "../common/constants.h"
|
#include "../common/constants.h"
|
||||||
#include "../common/dictionary.h"
|
#include "../common/dictionary.h"
|
||||||
#include "../common/platform.h"
|
#include "../common/platform.h"
|
||||||
#include <brotli/shared_dictionary.h>
|
|
||||||
#include "../common/transform.h"
|
#include "../common/transform.h"
|
||||||
#include <brotli/types.h>
|
|
||||||
#include "bit_reader.h"
|
#include "bit_reader.h"
|
||||||
#include "huffman.h"
|
#include "huffman.h"
|
||||||
|
|
||||||
|
@ -321,6 +323,13 @@ struct BrotliDecoderStateStruct {
|
||||||
|
|
||||||
/* Less used attributes are at the end of this struct. */
|
/* Less used attributes are at the end of this struct. */
|
||||||
|
|
||||||
|
brotli_decoder_metadata_start_func metadata_start_func;
|
||||||
|
brotli_decoder_metadata_chunk_func metadata_chunk_func;
|
||||||
|
void* metadata_callback_opaque;
|
||||||
|
|
||||||
|
/* For reporting. */
|
||||||
|
uint64_t used_input; /* how many bytes of input are consumed */
|
||||||
|
|
||||||
/* States inside function calls. */
|
/* States inside function calls. */
|
||||||
BrotliRunningMetablockHeaderState substate_metablock_header;
|
BrotliRunningMetablockHeaderState substate_metablock_header;
|
||||||
BrotliRunningUncompressedState substate_uncompressed;
|
BrotliRunningUncompressedState substate_uncompressed;
|
||||||
|
|
|
@ -361,6 +361,47 @@ BROTLI_DEC_API const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c);
|
||||||
*/
|
*/
|
||||||
BROTLI_DEC_API uint32_t BrotliDecoderVersion(void);
|
BROTLI_DEC_API uint32_t BrotliDecoderVersion(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to fire on metadata block start.
|
||||||
|
*
|
||||||
|
* After this callback is fired, if @p size is not @c 0, it is followed by
|
||||||
|
* ::brotli_decoder_metadata_chunk_func as more metadata block contents become
|
||||||
|
* accessible.
|
||||||
|
*
|
||||||
|
* @param opaque callback handle
|
||||||
|
* @param size size of metadata block
|
||||||
|
*/
|
||||||
|
typedef void (*brotli_decoder_metadata_start_func)(void* opaque, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to fire on metadata block chunk becomes available.
|
||||||
|
*
|
||||||
|
* This function can be invoked multiple times per metadata block; block should
|
||||||
|
* be considered finished when sum of @p size matches the announced metadata
|
||||||
|
* block size. Chunks contents pointed by @p data are transient and shouln not
|
||||||
|
* be accessed after leaving the callback.
|
||||||
|
*
|
||||||
|
* @param opaque callback handle
|
||||||
|
* @param data pointer to metadata contents
|
||||||
|
* @param size size of metadata block chunk, at least @c 1
|
||||||
|
*/
|
||||||
|
typedef void (*brotli_decoder_metadata_chunk_func)(void* opaque,
|
||||||
|
const uint8_t* data,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets callback for receiving metadata blocks.
|
||||||
|
*
|
||||||
|
* @param state decoder instance
|
||||||
|
* @param start_func callback on metadata block start
|
||||||
|
* @param chunk_func callback on metadata block chunk
|
||||||
|
* @param opaque callback handle
|
||||||
|
*/
|
||||||
|
BROTLI_DEC_API void BrotliDecoderSetMetadataCallbacks(
|
||||||
|
BrotliDecoderState* state,
|
||||||
|
brotli_decoder_metadata_start_func start_func,
|
||||||
|
brotli_decoder_metadata_chunk_func chunk_func, void* opaque);
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -453,7 +453,7 @@ BROTLI_ENC_API BROTLI_BOOL BrotliEncoderHasMoreOutput(
|
||||||
*
|
*
|
||||||
* This method is used to make language bindings easier and more efficient:
|
* This method is used to make language bindings easier and more efficient:
|
||||||
* -# push data to ::BrotliEncoderCompressStream,
|
* -# push data to ::BrotliEncoderCompressStream,
|
||||||
* until ::BrotliEncoderHasMoreOutput returns BROTL_TRUE
|
* until ::BrotliEncoderHasMoreOutput returns BROTLI_TRUE
|
||||||
* -# use ::BrotliEncoderTakeOutput to peek bytes and copy to language-specific
|
* -# use ::BrotliEncoderTakeOutput to peek bytes and copy to language-specific
|
||||||
* entity
|
* entity
|
||||||
*
|
*
|
||||||
|
|
|
@ -224,14 +224,6 @@
|
||||||
#define BROTLI_HAS_FEATURE(feature) (0)
|
#define BROTLI_HAS_FEATURE(feature) (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ADDRESS_SANITIZER) || BROTLI_HAS_FEATURE(address_sanitizer) || \
|
|
||||||
defined(THREAD_SANITIZER) || BROTLI_HAS_FEATURE(thread_sanitizer) || \
|
|
||||||
defined(MEMORY_SANITIZER) || BROTLI_HAS_FEATURE(memory_sanitizer)
|
|
||||||
#define BROTLI_SANITIZED 1
|
|
||||||
#else
|
|
||||||
#define BROTLI_SANITIZED 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
#define BROTLI_PUBLIC
|
#define BROTLI_PUBLIC
|
||||||
#elif BROTLI_GNUC_VERSION_CHECK(3, 3, 0) || \
|
#elif BROTLI_GNUC_VERSION_CHECK(3, 3, 0) || \
|
||||||
|
|
Loading…
Reference in New Issue