mirror of
https://github.com/google/brotli.git
synced 2024-12-26 17:51:04 +00:00
0.4-1.5% decoder speedup
PiperOrigin-RevId: 513248503
This commit is contained in:
parent
6f7f5a163d
commit
6db17c87f5
31
.github/workflows/build_test.yml
vendored
31
.github/workflows/build_test.yml
vendored
@ -33,7 +33,7 @@ jobs:
|
||||
build_system: cmake
|
||||
c_compiler: gcc-9
|
||||
cxx_compiler: g++-9
|
||||
os: ubuntu-20.04
|
||||
os: ubuntu-18.04
|
||||
|
||||
# TODO: consider running this combination in docker
|
||||
#- name: cmake:clang3.5
|
||||
@ -114,13 +114,12 @@ jobs:
|
||||
# TODO: consider running this combination in docker
|
||||
#- name: python2.7:gcc5
|
||||
|
||||
# TODO: consider running this combination in docker
|
||||
#- name: python27:clang9
|
||||
# build_system: python
|
||||
# c_compiler: clang-9
|
||||
# python_version: 2.7
|
||||
# cxx_compiler: clang++-9
|
||||
# os: ubuntu-20.04
|
||||
- name: python27:clang9
|
||||
build_system: python
|
||||
c_compiler: clang-9
|
||||
python_version: 2.7
|
||||
cxx_compiler: clang++-9
|
||||
os: ubuntu-18.04
|
||||
|
||||
# TODO: consider running this combination in docker
|
||||
#- name: python27-win
|
||||
@ -203,7 +202,7 @@ jobs:
|
||||
- name: bazel-win:root
|
||||
build_system: bazel
|
||||
bazel_project: .
|
||||
os: windows-2019
|
||||
os: windows-latest
|
||||
|
||||
# TODO: use single dll on windows, otherwise it fails to link
|
||||
#- name: bazel-win:go
|
||||
@ -214,7 +213,7 @@ jobs:
|
||||
- name: bazel-win:java
|
||||
build_system: bazel
|
||||
bazel_project: java
|
||||
os: windows-2019
|
||||
os: windows-latest
|
||||
|
||||
# TODO: blocked by Bazel Closure rules issue
|
||||
#- name: bazel-win:js
|
||||
@ -225,7 +224,7 @@ jobs:
|
||||
- name: bazel-win:research
|
||||
build_system: bazel
|
||||
bazel_project: research
|
||||
os: windows-2019
|
||||
os: windows-latest
|
||||
|
||||
- name: make
|
||||
build_system: make
|
||||
@ -246,7 +245,7 @@ jobs:
|
||||
steps:
|
||||
- name: Install extra deps @ Ubuntu
|
||||
if: ${{ runner.os == 'Linux' }}
|
||||
# Already installed: bazel, clang{10-12}, cmake, gcc{9,10}, java{8,11}, maven, python{3.5-3.9}
|
||||
# Already installed: bazel, clang{10-12}, cmake, gcc{9,10}, java{8,11}, maven, python{2.7,3.5-3.9}
|
||||
run: |
|
||||
EXTRA_PACKAGES="${{ matrix.extra_apt_pkgs || '' }}"
|
||||
sudo apt update
|
||||
@ -294,7 +293,7 @@ jobs:
|
||||
if: ${{ matrix.build_system == 'bazel' }}
|
||||
run: |
|
||||
cd ${GITHUB_WORKSPACE}/${{ matrix.bazel_project }}
|
||||
bazelisk build -c opt ...:all
|
||||
bazel build -c opt ...:all
|
||||
|
||||
- name: Fix symlinks for Bazel (Windows)
|
||||
if: ${{ matrix.build_system == 'bazel' && runner.os == 'Windows' && matrix.bazel_project == 'java' }}
|
||||
@ -338,9 +337,9 @@ jobs:
|
||||
if: ${{ matrix.build_system == 'bazel' }}
|
||||
run: |
|
||||
cd ${GITHUB_WORKSPACE}/${{ matrix.bazel_project }}
|
||||
bazelisk query "tests(...)" --output=label > ${RUNNER_TEMP}/tests.lst
|
||||
[ -s ${RUNNER_TEMP}/tests.lst ] && bazelisk test -c opt ...:all
|
||||
bazelisk clean
|
||||
bazel query "tests(...)" --output=label > ${RUNNER_TEMP}/tests.lst
|
||||
[ -s ${RUNNER_TEMP}/tests.lst ] && bazel test -c opt ...:all
|
||||
bazel clean
|
||||
|
||||
- name: Build / Test with Maven
|
||||
if: ${{ matrix.build_system == 'maven' }}
|
||||
|
63
.github/workflows/codeql.yml
vendored
63
.github/workflows/codeql.yml
vendored
@ -1,63 +0,0 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "master" ]
|
||||
schedule:
|
||||
- cron: '18 15 * * 0'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: 'ubuntu-latest'
|
||||
timeout-minutes: 360
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'cpp', 'java', 'javascript', 'python' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config: |
|
||||
paths-ignore:
|
||||
- research
|
||||
|
||||
- if: matrix.language == 'cpp'
|
||||
name: Build CPP
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
- if: matrix.language == 'cpp' || matrix.language == 'java'
|
||||
name: Build Java
|
||||
run: |
|
||||
cd ${GITHUB_WORKSPACE}/java
|
||||
bazelisk build --spawn_strategy=local --nouse_action_cache -c opt ...:all
|
||||
|
||||
- if: matrix.language == 'javascript'
|
||||
name: Build JS
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
- if: matrix.language == 'cpp' || matrix.language == 'python'
|
||||
name: Build Python
|
||||
run: |
|
||||
python setup.py build_ext
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
72
.github/workflows/scorecard.yml
vendored
72
.github/workflows/scorecard.yml
vendored
@ -1,72 +0,0 @@
|
||||
# This workflow uses actions that are not certified by GitHub. They are provided
|
||||
# by a third-party and are governed by separate terms of service, privacy
|
||||
# policy, and support documentation.
|
||||
|
||||
name: Scorecard supply-chain security
|
||||
on:
|
||||
# For Branch-Protection check. Only the default branch is supported. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
|
||||
branch_protection_rule:
|
||||
# To guarantee Maintained check is occasionally updated. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
|
||||
schedule:
|
||||
- cron: '23 21 * * 1'
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
analysis:
|
||||
name: Scorecard analysis
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# Needed to upload the results to code-scanning dashboard.
|
||||
security-events: write
|
||||
# Needed to publish results and get a badge (see publish_results below).
|
||||
id-token: write
|
||||
# Uncomment the permissions below if installing in a private repository.
|
||||
# contents: read
|
||||
# actions: read
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # v2.1.2
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
|
||||
# - you want to enable the Branch-Protection check on a *public* repository, or
|
||||
# - you are installing Scorecard on a *private* repository
|
||||
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
|
||||
# repo_token: ${{ secrets.SCORECARD_TOKEN }}
|
||||
|
||||
# Public repositories:
|
||||
# - Publish results to OpenSSF REST API for easy access by consumers
|
||||
# - Allows the repository to include the Scorecard badge.
|
||||
# - See https://github.com/ossf/scorecard-action#publishing-results.
|
||||
# For private repositories:
|
||||
# - `publish_results` will always be set to `false`, regardless
|
||||
# of the value entered here.
|
||||
publish_results: true
|
||||
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4
|
||||
with:
|
||||
sarif_file: results.sarif
|
12
BUILD
12
BUILD
@ -45,17 +45,6 @@ create_msvc_config()
|
||||
|
||||
STRICT_C_OPTIONS = select({
|
||||
":msvc": [],
|
||||
":clang-cl": [
|
||||
"/W4",
|
||||
"-Wconversion",
|
||||
"-Wlong-long",
|
||||
"-Wmissing-declarations",
|
||||
"-Wmissing-prototypes",
|
||||
"-Wno-strict-aliasing",
|
||||
"-Wshadow",
|
||||
"-Wsign-compare",
|
||||
"-Wno-sign-conversion",
|
||||
],
|
||||
"//conditions:default": [
|
||||
"--pedantic-errors",
|
||||
"-Wall",
|
||||
@ -135,7 +124,6 @@ cc_library(
|
||||
hdrs = [":enc_headers"],
|
||||
copts = STRICT_C_OPTIONS,
|
||||
linkopts = select({
|
||||
":clang-cl": [],
|
||||
":msvc": [],
|
||||
"//conditions:default": ["-lm"],
|
||||
}),
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Available CMake versions:
|
||||
# - Ubuntu 20.04 LTS : 3.16.3
|
||||
# - Solaris 11.4 SRU 15 : 3.15
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
# - Ubuntu 18.04 LTS (deprecated on GitHub Actions) : 3.10.4
|
||||
# - Solaris 11.4 SRU 15 : 3.15
|
||||
cmake_minimum_required(VERSION 3.10.4)
|
||||
|
||||
# Since this project's version is loaded from other files, this policy
|
||||
# will help suppress the warning generated by cmake.
|
||||
|
@ -208,13 +208,8 @@ OR:
|
||||
#define BROTLI_TARGET_RISCV64
|
||||
#endif
|
||||
|
||||
#if defined(__loongarch_lp64)
|
||||
#define BROTLI_TARGET_LOONGARCH64
|
||||
#endif
|
||||
|
||||
#if defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \
|
||||
defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64) || \
|
||||
defined(BROTLI_TARGET_LOONGARCH64)
|
||||
defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64)
|
||||
#define BROTLI_TARGET_64_BITS 1
|
||||
#else
|
||||
#define BROTLI_TARGET_64_BITS 0
|
||||
@ -273,7 +268,7 @@ OR:
|
||||
#define BROTLI_UNALIGNED_READ_FAST (!!0)
|
||||
#elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
|
||||
defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) || \
|
||||
defined(BROTLI_TARGET_RISCV64) || defined(BROTLI_TARGET_LOONGARCH64)
|
||||
defined(BROTLI_TARGET_RISCV64)
|
||||
/* These targets are known to generate efficient code for unaligned reads
|
||||
* (e.g. a single instruction, not multiple 1-byte loads, shifted and or'd
|
||||
* together). */
|
||||
|
@ -16,7 +16,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const uint32_t kBrotliBitMask[33] = { 0x00000000,
|
||||
const brotli_reg_t kBrotliBitMask[33] = { 0x00000000,
|
||||
0x00000001, 0x00000003, 0x00000007, 0x0000000F,
|
||||
0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
|
||||
0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
|
||||
@ -56,9 +56,9 @@ BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
|
||||
}
|
||||
|
||||
BROTLI_BOOL BrotliSafeReadBits32Slow(BrotliBitReader* const br,
|
||||
uint32_t n_bits, uint32_t* val) {
|
||||
uint32_t low_val;
|
||||
uint32_t high_val;
|
||||
brotli_reg_t n_bits, brotli_reg_t* val) {
|
||||
brotli_reg_t low_val;
|
||||
brotli_reg_t high_val;
|
||||
BrotliBitReaderState memento;
|
||||
BROTLI_DCHECK(n_bits <= 32);
|
||||
BROTLI_DCHECK(n_bits > 24);
|
||||
|
@ -22,13 +22,13 @@ extern "C" {
|
||||
|
||||
#define BROTLI_SHORT_FILL_BIT_WINDOW_READ (sizeof(brotli_reg_t) >> 1)
|
||||
|
||||
BROTLI_INTERNAL extern const uint32_t kBrotliBitMask[33];
|
||||
BROTLI_INTERNAL extern const brotli_reg_t kBrotliBitMask[33];
|
||||
|
||||
static BROTLI_INLINE uint32_t BitMask(uint32_t n) {
|
||||
static BROTLI_INLINE brotli_reg_t BitMask(brotli_reg_t n) {
|
||||
if (BROTLI_IS_CONSTANT(n) || BROTLI_HAS_UBFX) {
|
||||
/* Masking with this expression turns to a single
|
||||
"Unsigned Bit Field Extract" UBFX instruction on ARM. */
|
||||
return ~((0xFFFFFFFFu) << n);
|
||||
return ~(~((brotli_reg_t)0) << n);
|
||||
} else {
|
||||
return kBrotliBitMask[n];
|
||||
}
|
||||
@ -36,33 +36,33 @@ static BROTLI_INLINE uint32_t BitMask(uint32_t n) {
|
||||
|
||||
typedef struct {
|
||||
brotli_reg_t val_; /* pre-fetched bits */
|
||||
uint32_t bit_pos_; /* current bit-reading position in val_ */
|
||||
brotli_reg_t bit_pos_; /* current bit-reading position in val_ */
|
||||
const uint8_t* next_in; /* the byte we're reading from */
|
||||
size_t avail_in;
|
||||
} BrotliBitReader;
|
||||
|
||||
typedef struct {
|
||||
brotli_reg_t val_;
|
||||
uint32_t bit_pos_;
|
||||
brotli_reg_t bit_pos_;
|
||||
const uint8_t* next_in;
|
||||
size_t avail_in;
|
||||
} BrotliBitReaderState;
|
||||
|
||||
/* Initializes the BrotliBitReader fields. */
|
||||
BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* const br);
|
||||
BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* br);
|
||||
|
||||
/* Ensures that accumulator is not empty.
|
||||
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.
|
||||
For !BROTLI_UNALIGNED_READ_FAST this function also prepares bit reader for
|
||||
aligned reading. */
|
||||
BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br);
|
||||
BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* br);
|
||||
|
||||
/* Fallback for BrotliSafeReadBits32. Extracted as noninlined method to unburden
|
||||
the main code-path. Never called for RFC brotli streams, required only for
|
||||
"large-window" mode and other extensions. */
|
||||
BROTLI_INTERNAL BROTLI_NOINLINE BROTLI_BOOL BrotliSafeReadBits32Slow(
|
||||
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val);
|
||||
BrotliBitReader* br, brotli_reg_t n_bits, brotli_reg_t* val);
|
||||
|
||||
static BROTLI_INLINE void BrotliBitReaderSaveState(
|
||||
BrotliBitReader* const from, BrotliBitReaderState* to) {
|
||||
@ -80,7 +80,7 @@ static BROTLI_INLINE void BrotliBitReaderRestoreState(
|
||||
to->avail_in = from->avail_in;
|
||||
}
|
||||
|
||||
static BROTLI_INLINE uint32_t BrotliGetAvailableBits(
|
||||
static BROTLI_INLINE brotli_reg_t BrotliGetAvailableBits(
|
||||
const BrotliBitReader* br) {
|
||||
return (BROTLI_64_BITS ? 64 : 32) - br->bit_pos_;
|
||||
}
|
||||
@ -106,11 +106,11 @@ static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount(
|
||||
|n_bits| should be in the range [1..24] for regular build. For portable
|
||||
non-64-bit little-endian build only 16 bits are safe to request. */
|
||||
static BROTLI_INLINE void BrotliFillBitWindow(
|
||||
BrotliBitReader* const br, uint32_t n_bits) {
|
||||
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
||||
#if (BROTLI_64_BITS)
|
||||
if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
|
||||
(n_bits <= 8)) {
|
||||
uint32_t bit_pos = br->bit_pos_;
|
||||
brotli_reg_t bit_pos = br->bit_pos_;
|
||||
if (bit_pos >= 56) {
|
||||
br->val_ =
|
||||
(br->val_ >> 56) | (BROTLI_UNALIGNED_LOAD64LE(br->next_in) << 8);
|
||||
@ -121,7 +121,7 @@ static BROTLI_INLINE void BrotliFillBitWindow(
|
||||
}
|
||||
} else if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
|
||||
(n_bits <= 16)) {
|
||||
uint32_t bit_pos = br->bit_pos_;
|
||||
brotli_reg_t bit_pos = br->bit_pos_;
|
||||
if (bit_pos >= 48) {
|
||||
br->val_ =
|
||||
(br->val_ >> 48) | (BROTLI_UNALIGNED_LOAD64LE(br->next_in) << 16);
|
||||
@ -131,7 +131,7 @@ static BROTLI_INLINE void BrotliFillBitWindow(
|
||||
br->next_in += 6;
|
||||
}
|
||||
} else {
|
||||
uint32_t bit_pos = br->bit_pos_;
|
||||
brotli_reg_t bit_pos = br->bit_pos_;
|
||||
if (bit_pos >= 32) {
|
||||
br->val_ = (br->val_ >> 32) |
|
||||
(((uint64_t)BROTLI_UNALIGNED_LOAD32LE(br->next_in)) << 32);
|
||||
@ -144,7 +144,7 @@ static BROTLI_INLINE void BrotliFillBitWindow(
|
||||
#else
|
||||
if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
|
||||
(n_bits <= 8)) {
|
||||
uint32_t bit_pos = br->bit_pos_;
|
||||
brotli_reg_t bit_pos = br->bit_pos_;
|
||||
if (bit_pos >= 24) {
|
||||
br->val_ =
|
||||
(br->val_ >> 24) | (BROTLI_UNALIGNED_LOAD32LE(br->next_in) << 8);
|
||||
@ -154,10 +154,10 @@ static BROTLI_INLINE void BrotliFillBitWindow(
|
||||
br->next_in += 3;
|
||||
}
|
||||
} else {
|
||||
uint32_t bit_pos = br->bit_pos_;
|
||||
brotli_reg_t bit_pos = br->bit_pos_;
|
||||
if (bit_pos >= 16) {
|
||||
br->val_ = (br->val_ >> 16) |
|
||||
(((uint32_t)BROTLI_UNALIGNED_LOAD16LE(br->next_in)) << 16);
|
||||
(((brotli_reg_t)BROTLI_UNALIGNED_LOAD16LE(br->next_in)) << 16);
|
||||
br->bit_pos_ =
|
||||
bit_pos ^ 16; /* here same as -= 16 because of the if condition */
|
||||
br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
|
||||
@ -183,7 +183,7 @@ static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) {
|
||||
#if (BROTLI_64_BITS)
|
||||
br->val_ |= ((uint64_t)*br->next_in) << 56;
|
||||
#else
|
||||
br->val_ |= ((uint32_t)*br->next_in) << 24;
|
||||
br->val_ |= ((brotli_reg_t)*br->next_in) << 24;
|
||||
#endif
|
||||
br->bit_pos_ -= 8;
|
||||
--br->avail_in;
|
||||
@ -200,42 +200,42 @@ static BROTLI_INLINE brotli_reg_t BrotliGetBitsUnmasked(
|
||||
|
||||
/* Like BrotliGetBits, but does not mask the result.
|
||||
The result contains at least 16 valid bits. */
|
||||
static BROTLI_INLINE uint32_t BrotliGet16BitsUnmasked(
|
||||
static BROTLI_INLINE brotli_reg_t BrotliGet16BitsUnmasked(
|
||||
BrotliBitReader* const br) {
|
||||
BrotliFillBitWindow(br, 16);
|
||||
return (uint32_t)BrotliGetBitsUnmasked(br);
|
||||
return (brotli_reg_t)BrotliGetBitsUnmasked(br);
|
||||
}
|
||||
|
||||
/* Returns the specified number of bits from |br| without advancing bit
|
||||
position. */
|
||||
static BROTLI_INLINE uint32_t BrotliGetBits(
|
||||
BrotliBitReader* const br, uint32_t n_bits) {
|
||||
static BROTLI_INLINE brotli_reg_t BrotliGetBits(
|
||||
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
||||
BrotliFillBitWindow(br, n_bits);
|
||||
return (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
||||
return BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
||||
}
|
||||
|
||||
/* Tries to peek the specified amount of bits. Returns BROTLI_FALSE, if there
|
||||
is not enough input. */
|
||||
static BROTLI_INLINE BROTLI_BOOL BrotliSafeGetBits(
|
||||
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
||||
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
||||
while (BrotliGetAvailableBits(br) < n_bits) {
|
||||
if (!BrotliPullByte(br)) {
|
||||
return BROTLI_FALSE;
|
||||
}
|
||||
}
|
||||
*val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
||||
*val = BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
||||
return BROTLI_TRUE;
|
||||
}
|
||||
|
||||
/* Advances the bit pos by |n_bits|. */
|
||||
static BROTLI_INLINE void BrotliDropBits(
|
||||
BrotliBitReader* const br, uint32_t n_bits) {
|
||||
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
||||
br->bit_pos_ += n_bits;
|
||||
}
|
||||
|
||||
static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) {
|
||||
uint32_t unused_bytes = BrotliGetAvailableBits(br) >> 3;
|
||||
uint32_t unused_bits = unused_bytes << 3;
|
||||
brotli_reg_t unused_bytes = BrotliGetAvailableBits(br) >> 3;
|
||||
brotli_reg_t unused_bits = unused_bytes << 3;
|
||||
br->avail_in += unused_bytes;
|
||||
br->next_in -= unused_bytes;
|
||||
if (unused_bits == sizeof(br->val_) << 3) {
|
||||
@ -249,8 +249,8 @@ static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) {
|
||||
/* Reads the specified number of bits from |br| and advances the bit pos.
|
||||
Precondition: accumulator MUST contain at least |n_bits|. */
|
||||
static BROTLI_INLINE void BrotliTakeBits(
|
||||
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
||||
*val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
||||
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
||||
*val = BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
||||
BROTLI_LOG(("[BrotliTakeBits] %d %d %d val: %6x\n",
|
||||
(int)br->avail_in, (int)br->bit_pos_, (int)n_bits, (int)*val));
|
||||
BrotliDropBits(br, n_bits);
|
||||
@ -259,17 +259,17 @@ static BROTLI_INLINE void BrotliTakeBits(
|
||||
/* Reads the specified number of bits from |br| and advances the bit pos.
|
||||
Assumes that there is enough input to perform BrotliFillBitWindow.
|
||||
Up to 24 bits are allowed to be requested from this method. */
|
||||
static BROTLI_INLINE uint32_t BrotliReadBits24(
|
||||
BrotliBitReader* const br, uint32_t n_bits) {
|
||||
static BROTLI_INLINE brotli_reg_t BrotliReadBits24(
|
||||
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
||||
BROTLI_DCHECK(n_bits <= 24);
|
||||
if (BROTLI_64_BITS || (n_bits <= 16)) {
|
||||
uint32_t val;
|
||||
brotli_reg_t val;
|
||||
BrotliFillBitWindow(br, n_bits);
|
||||
BrotliTakeBits(br, n_bits, &val);
|
||||
return val;
|
||||
} else {
|
||||
uint32_t low_val;
|
||||
uint32_t high_val;
|
||||
brotli_reg_t low_val;
|
||||
brotli_reg_t high_val;
|
||||
BrotliFillBitWindow(br, 16);
|
||||
BrotliTakeBits(br, 16, &low_val);
|
||||
BrotliFillBitWindow(br, 8);
|
||||
@ -279,17 +279,17 @@ static BROTLI_INLINE uint32_t BrotliReadBits24(
|
||||
}
|
||||
|
||||
/* Same as BrotliReadBits24, but allows reading up to 32 bits. */
|
||||
static BROTLI_INLINE uint32_t BrotliReadBits32(
|
||||
BrotliBitReader* const br, uint32_t n_bits) {
|
||||
static BROTLI_INLINE brotli_reg_t BrotliReadBits32(
|
||||
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
||||
BROTLI_DCHECK(n_bits <= 32);
|
||||
if (BROTLI_64_BITS || (n_bits <= 16)) {
|
||||
uint32_t val;
|
||||
brotli_reg_t val;
|
||||
BrotliFillBitWindow(br, n_bits);
|
||||
BrotliTakeBits(br, n_bits, &val);
|
||||
return val;
|
||||
} else {
|
||||
uint32_t low_val;
|
||||
uint32_t high_val;
|
||||
brotli_reg_t low_val;
|
||||
brotli_reg_t high_val;
|
||||
BrotliFillBitWindow(br, 16);
|
||||
BrotliTakeBits(br, 16, &low_val);
|
||||
BrotliFillBitWindow(br, 16);
|
||||
@ -302,7 +302,7 @@ static BROTLI_INLINE uint32_t BrotliReadBits32(
|
||||
is not enough input. |n_bits| MUST be positive.
|
||||
Up to 24 bits are allowed to be requested from this method. */
|
||||
static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
|
||||
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
||||
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
||||
BROTLI_DCHECK(n_bits <= 24);
|
||||
while (BrotliGetAvailableBits(br) < n_bits) {
|
||||
if (!BrotliPullByte(br)) {
|
||||
@ -315,7 +315,7 @@ static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
|
||||
|
||||
/* Same as BrotliSafeReadBits, but allows reading up to 32 bits. */
|
||||
static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits32(
|
||||
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
||||
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
||||
BROTLI_DCHECK(n_bits <= 32);
|
||||
if (BROTLI_64_BITS || (n_bits <= 24)) {
|
||||
while (BrotliGetAvailableBits(br) < n_bits) {
|
||||
@ -333,8 +333,8 @@ static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits32(
|
||||
/* Advances the bit reader position to the next byte boundary and verifies
|
||||
that any skipped bits are set to zero. */
|
||||
static BROTLI_INLINE BROTLI_BOOL BrotliJumpToByteBoundary(BrotliBitReader* br) {
|
||||
uint32_t pad_bits_count = BrotliGetAvailableBits(br) & 0x7;
|
||||
uint32_t pad_bits = 0;
|
||||
brotli_reg_t pad_bits_count = BrotliGetAvailableBits(br) & 0x7;
|
||||
brotli_reg_t pad_bits = 0;
|
||||
if (pad_bits_count != 0) {
|
||||
BrotliTakeBits(br, pad_bits_count, &pad_bits);
|
||||
}
|
||||
@ -363,6 +363,25 @@ static BROTLI_INLINE void BrotliCopyBytes(uint8_t* dest,
|
||||
}
|
||||
}
|
||||
|
||||
BROTLI_UNUSED_FUNCTION void BrotliBitReaderSuppressUnusedFunctions(void) {
|
||||
BROTLI_UNUSED(&BrotliBitReaderSuppressUnusedFunctions);
|
||||
BROTLI_UNUSED(&BrotliBitReaderSaveState);
|
||||
BROTLI_UNUSED(&BrotliBitReaderRestoreState);
|
||||
BROTLI_UNUSED(&BrotliGetRemainingBytes);
|
||||
BROTLI_UNUSED(&BrotliCheckInputAmount);
|
||||
BROTLI_UNUSED(&BrotliFillBitWindow16);
|
||||
BROTLI_UNUSED(&BrotliGet16BitsUnmasked);
|
||||
BROTLI_UNUSED(&BrotliGetBits);
|
||||
BROTLI_UNUSED(&BrotliSafeGetBits);
|
||||
BROTLI_UNUSED(&BrotliBitReaderUnload);
|
||||
BROTLI_UNUSED(&BrotliReadBits24);
|
||||
BROTLI_UNUSED(&BrotliReadBits32);
|
||||
BROTLI_UNUSED(&BrotliSafeReadBits);
|
||||
BROTLI_UNUSED(&BrotliSafeReadBits32);
|
||||
BROTLI_UNUSED(&BrotliJumpToByteBoundary);
|
||||
BROTLI_UNUSED(&BrotliCopyBytes);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
288
c/dec/decode.c
288
c/dec/decode.c
@ -44,7 +44,7 @@ extern "C" {
|
||||
- doing up to two 16-byte copies for fast backward copying
|
||||
- inserting transformed dictionary word:
|
||||
255 prefix + 32 base + 255 suffix */
|
||||
static const uint32_t kRingBufferWriteAheadSlack = 542;
|
||||
static const brotli_reg_t kRingBufferWriteAheadSlack = 542;
|
||||
|
||||
static const uint8_t kCodeLengthCodeOrder[BROTLI_CODE_LENGTH_CODES] = {
|
||||
1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
@ -135,7 +135,7 @@ static BROTLI_NOINLINE BrotliDecoderResult SaveErrorCode(
|
||||
Precondition: bit-reader accumulator has at least 8 bits. */
|
||||
static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s,
|
||||
BrotliBitReader* br) {
|
||||
uint32_t n;
|
||||
brotli_reg_t n;
|
||||
BROTLI_BOOL large_window = s->large_window;
|
||||
s->large_window = BROTLI_FALSE;
|
||||
BrotliTakeBits(br, 1, &n);
|
||||
@ -181,8 +181,8 @@ static BROTLI_INLINE void memmove16(uint8_t* dst, uint8_t* src) {
|
||||
|
||||
/* Decodes a number in the range [0..255], by reading 1 - 11 bits. */
|
||||
static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
|
||||
BrotliDecoderState* s, BrotliBitReader* br, uint32_t* value) {
|
||||
uint32_t bits;
|
||||
BrotliDecoderState* s, BrotliBitReader* br, brotli_reg_t* value) {
|
||||
brotli_reg_t bits;
|
||||
switch (s->substate_decode_uint8) {
|
||||
case BROTLI_STATE_DECODE_UINT8_NONE:
|
||||
if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, 1, &bits))) {
|
||||
@ -226,7 +226,7 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
|
||||
/* Decodes a metablock length and flags by reading 2 - 31 bits. */
|
||||
static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
||||
BrotliDecoderState* s, BrotliBitReader* br) {
|
||||
uint32_t bits;
|
||||
brotli_reg_t bits;
|
||||
int i;
|
||||
for (;;) {
|
||||
switch (s->substate_metablock_header) {
|
||||
@ -349,13 +349,13 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
||||
This method doesn't read data from the bit reader, BUT drops the amount of
|
||||
bits that correspond to the decoded symbol.
|
||||
bits MUST contain at least 15 (BROTLI_HUFFMAN_MAX_CODE_LENGTH) valid bits. */
|
||||
static BROTLI_INLINE uint32_t DecodeSymbol(uint32_t bits,
|
||||
const HuffmanCode* table,
|
||||
BrotliBitReader* br) {
|
||||
static BROTLI_INLINE brotli_reg_t DecodeSymbol(brotli_reg_t bits,
|
||||
const HuffmanCode* table,
|
||||
BrotliBitReader* br) {
|
||||
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
|
||||
BROTLI_HC_ADJUST_TABLE_INDEX(table, bits & HUFFMAN_TABLE_MASK);
|
||||
if (BROTLI_HC_FAST_LOAD_BITS(table) > HUFFMAN_TABLE_BITS) {
|
||||
uint32_t nbits = BROTLI_HC_FAST_LOAD_BITS(table) - HUFFMAN_TABLE_BITS;
|
||||
brotli_reg_t nbits = BROTLI_HC_FAST_LOAD_BITS(table) - HUFFMAN_TABLE_BITS;
|
||||
BrotliDropBits(br, HUFFMAN_TABLE_BITS);
|
||||
BROTLI_HC_ADJUST_TABLE_INDEX(table,
|
||||
BROTLI_HC_FAST_LOAD_VALUE(table) +
|
||||
@ -367,17 +367,17 @@ static BROTLI_INLINE uint32_t DecodeSymbol(uint32_t bits,
|
||||
|
||||
/* Reads and decodes the next Huffman code from bit-stream.
|
||||
This method peeks 16 bits of input and drops 0 - 15 of them. */
|
||||
static BROTLI_INLINE uint32_t ReadSymbol(const HuffmanCode* table,
|
||||
BrotliBitReader* br) {
|
||||
static BROTLI_INLINE brotli_reg_t ReadSymbol(const HuffmanCode* table,
|
||||
BrotliBitReader* br) {
|
||||
return DecodeSymbol(BrotliGet16BitsUnmasked(br), table, br);
|
||||
}
|
||||
|
||||
/* Same as DecodeSymbol, but it is known that there is less than 15 bits of
|
||||
input are currently available. */
|
||||
static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
|
||||
const HuffmanCode* table, BrotliBitReader* br, uint32_t* result) {
|
||||
uint32_t val;
|
||||
uint32_t available_bits = BrotliGetAvailableBits(br);
|
||||
const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) {
|
||||
brotli_reg_t val;
|
||||
brotli_reg_t available_bits = BrotliGetAvailableBits(br);
|
||||
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
|
||||
if (available_bits == 0) {
|
||||
if (BROTLI_HC_FAST_LOAD_BITS(table) == 0) {
|
||||
@ -386,7 +386,7 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
|
||||
}
|
||||
return BROTLI_FALSE; /* No valid bits at all. */
|
||||
}
|
||||
val = (uint32_t)BrotliGetBitsUnmasked(br);
|
||||
val = BrotliGetBitsUnmasked(br);
|
||||
BROTLI_HC_ADJUST_TABLE_INDEX(table, val & HUFFMAN_TABLE_MASK);
|
||||
if (BROTLI_HC_FAST_LOAD_BITS(table) <= HUFFMAN_TABLE_BITS) {
|
||||
if (BROTLI_HC_FAST_LOAD_BITS(table) <= available_bits) {
|
||||
@ -415,8 +415,8 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
|
||||
}
|
||||
|
||||
static BROTLI_INLINE BROTLI_BOOL SafeReadSymbol(
|
||||
const HuffmanCode* table, BrotliBitReader* br, uint32_t* result) {
|
||||
uint32_t val;
|
||||
const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) {
|
||||
brotli_reg_t val;
|
||||
if (BROTLI_PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) {
|
||||
*result = DecodeSymbol(val, table, br);
|
||||
return BROTLI_TRUE;
|
||||
@ -428,8 +428,8 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadSymbol(
|
||||
static BROTLI_INLINE void PreloadSymbol(int safe,
|
||||
const HuffmanCode* table,
|
||||
BrotliBitReader* br,
|
||||
uint32_t* bits,
|
||||
uint32_t* value) {
|
||||
brotli_reg_t* bits,
|
||||
brotli_reg_t* value) {
|
||||
if (safe) {
|
||||
return;
|
||||
}
|
||||
@ -441,15 +441,15 @@ static BROTLI_INLINE void PreloadSymbol(int safe,
|
||||
|
||||
/* Decodes the next Huffman code using data prepared by PreloadSymbol.
|
||||
Reads 0 - 15 bits. Also peeks 8 following bits. */
|
||||
static BROTLI_INLINE uint32_t ReadPreloadedSymbol(const HuffmanCode* table,
|
||||
static BROTLI_INLINE brotli_reg_t ReadPreloadedSymbol(const HuffmanCode* table,
|
||||
BrotliBitReader* br,
|
||||
uint32_t* bits,
|
||||
uint32_t* value) {
|
||||
uint32_t result = *value;
|
||||
brotli_reg_t* bits,
|
||||
brotli_reg_t* value) {
|
||||
brotli_reg_t result = *value;
|
||||
if (BROTLI_PREDICT_FALSE(*bits > HUFFMAN_TABLE_BITS)) {
|
||||
uint32_t val = BrotliGet16BitsUnmasked(br);
|
||||
brotli_reg_t val = BrotliGet16BitsUnmasked(br);
|
||||
const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value;
|
||||
uint32_t mask = BitMask((*bits - HUFFMAN_TABLE_BITS));
|
||||
brotli_reg_t mask = BitMask((*bits - HUFFMAN_TABLE_BITS));
|
||||
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(ext);
|
||||
BrotliDropBits(br, HUFFMAN_TABLE_BITS);
|
||||
BROTLI_HC_ADJUST_TABLE_INDEX(ext, (val >> HUFFMAN_TABLE_BITS) & mask);
|
||||
@ -462,8 +462,8 @@ static BROTLI_INLINE uint32_t ReadPreloadedSymbol(const HuffmanCode* table,
|
||||
return result;
|
||||
}
|
||||
|
||||
static BROTLI_INLINE uint32_t Log2Floor(uint32_t x) {
|
||||
uint32_t result = 0;
|
||||
static BROTLI_INLINE brotli_reg_t Log2Floor(brotli_reg_t x) {
|
||||
brotli_reg_t result = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
++result;
|
||||
@ -475,16 +475,16 @@ static BROTLI_INLINE uint32_t Log2Floor(uint32_t x) {
|
||||
Totally 1..4 symbols are read, 1..11 bits each.
|
||||
The list of symbols MUST NOT contain duplicates. */
|
||||
static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
|
||||
uint32_t alphabet_size_max, uint32_t alphabet_size_limit,
|
||||
brotli_reg_t alphabet_size_max, brotli_reg_t alphabet_size_limit,
|
||||
BrotliDecoderState* s) {
|
||||
/* max_bits == 1..11; symbol == 0..3; 1..44 bits will be read. */
|
||||
BrotliBitReader* br = &s->br;
|
||||
BrotliMetablockHeaderArena* h = &s->arena.header;
|
||||
uint32_t max_bits = Log2Floor(alphabet_size_max - 1);
|
||||
uint32_t i = h->sub_loop_counter;
|
||||
uint32_t num_symbols = h->symbol;
|
||||
brotli_reg_t max_bits = Log2Floor(alphabet_size_max - 1);
|
||||
brotli_reg_t i = h->sub_loop_counter;
|
||||
brotli_reg_t num_symbols = h->symbol;
|
||||
while (i <= num_symbols) {
|
||||
uint32_t v;
|
||||
brotli_reg_t v;
|
||||
if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) {
|
||||
h->sub_loop_counter = i;
|
||||
h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ;
|
||||
@ -500,7 +500,7 @@ static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
|
||||
}
|
||||
|
||||
for (i = 0; i < num_symbols; ++i) {
|
||||
uint32_t k = i + 1;
|
||||
brotli_reg_t k = i + 1;
|
||||
for (; k <= num_symbols; ++k) {
|
||||
if (h->symbols_lists_array[i] == h->symbols_lists_array[k]) {
|
||||
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME);
|
||||
@ -517,9 +517,9 @@ static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
|
||||
C) extend corresponding index-chain
|
||||
D) reduce the Huffman space
|
||||
E) update the histogram */
|
||||
static BROTLI_INLINE void ProcessSingleCodeLength(uint32_t code_len,
|
||||
uint32_t* symbol, uint32_t* repeat, uint32_t* space,
|
||||
uint32_t* prev_code_len, uint16_t* symbol_lists,
|
||||
static BROTLI_INLINE void ProcessSingleCodeLength(brotli_reg_t code_len,
|
||||
brotli_reg_t* symbol, brotli_reg_t* repeat, brotli_reg_t* space,
|
||||
brotli_reg_t* prev_code_len, uint16_t* symbol_lists,
|
||||
uint16_t* code_length_histo, int* next_symbol) {
|
||||
*repeat = 0;
|
||||
if (code_len != 0) { /* code_len == 1..15 */
|
||||
@ -544,14 +544,14 @@ static BROTLI_INLINE void ProcessSingleCodeLength(uint32_t code_len,
|
||||
|
||||
PRECONDITION: code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH or
|
||||
code_len == BROTLI_REPEAT_ZERO_CODE_LENGTH */
|
||||
static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
|
||||
uint32_t repeat_delta, uint32_t alphabet_size, uint32_t* symbol,
|
||||
uint32_t* repeat, uint32_t* space, uint32_t* prev_code_len,
|
||||
uint32_t* repeat_code_len, uint16_t* symbol_lists,
|
||||
static BROTLI_INLINE void ProcessRepeatedCodeLength(brotli_reg_t code_len,
|
||||
brotli_reg_t repeat_delta, brotli_reg_t alphabet_size, brotli_reg_t* symbol,
|
||||
brotli_reg_t* repeat, brotli_reg_t* space, brotli_reg_t* prev_code_len,
|
||||
brotli_reg_t* repeat_code_len, uint16_t* symbol_lists,
|
||||
uint16_t* code_length_histo, int* next_symbol) {
|
||||
uint32_t old_repeat;
|
||||
uint32_t extra_bits = 3; /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */
|
||||
uint32_t new_len = 0; /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */
|
||||
brotli_reg_t old_repeat;
|
||||
brotli_reg_t extra_bits = 3; /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */
|
||||
brotli_reg_t new_len = 0; /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */
|
||||
if (code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) {
|
||||
new_len = *prev_code_len;
|
||||
extra_bits = 2;
|
||||
@ -576,7 +576,7 @@ static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
|
||||
BROTLI_LOG(("[ReadHuffmanCode] code_length[%d..%d] = %d\n",
|
||||
(int)*symbol, (int)(*symbol + repeat_delta - 1), (int)*repeat_code_len));
|
||||
if (*repeat_code_len != 0) {
|
||||
unsigned last = *symbol + repeat_delta;
|
||||
brotli_reg_t last = *symbol + repeat_delta;
|
||||
int next = next_symbol[*repeat_code_len];
|
||||
do {
|
||||
symbol_lists[next] = (uint16_t)*symbol;
|
||||
@ -593,14 +593,14 @@ static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
|
||||
|
||||
/* Reads and decodes symbol codelengths. */
|
||||
static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
||||
uint32_t alphabet_size, BrotliDecoderState* s) {
|
||||
brotli_reg_t alphabet_size, BrotliDecoderState* s) {
|
||||
BrotliBitReader* br = &s->br;
|
||||
BrotliMetablockHeaderArena* h = &s->arena.header;
|
||||
uint32_t symbol = h->symbol;
|
||||
uint32_t repeat = h->repeat;
|
||||
uint32_t space = h->space;
|
||||
uint32_t prev_code_len = h->prev_code_len;
|
||||
uint32_t repeat_code_len = h->repeat_code_len;
|
||||
brotli_reg_t symbol = h->symbol;
|
||||
brotli_reg_t repeat = h->repeat;
|
||||
brotli_reg_t space = h->space;
|
||||
brotli_reg_t prev_code_len = h->prev_code_len;
|
||||
brotli_reg_t repeat_code_len = h->repeat_code_len;
|
||||
uint16_t* symbol_lists = h->symbol_lists;
|
||||
uint16_t* code_length_histo = h->code_length_histo;
|
||||
int* next_symbol = h->next_symbol;
|
||||
@ -609,7 +609,7 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
||||
}
|
||||
while (symbol < alphabet_size && space > 0) {
|
||||
const HuffmanCode* p = h->table;
|
||||
uint32_t code_len;
|
||||
brotli_reg_t code_len;
|
||||
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
|
||||
if (!BrotliCheckInputAmount(br, BROTLI_SHORT_FILL_BIT_WINDOW_READ)) {
|
||||
h->symbol = symbol;
|
||||
@ -628,10 +628,10 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
||||
ProcessSingleCodeLength(code_len, &symbol, &repeat, &space,
|
||||
&prev_code_len, symbol_lists, code_length_histo, next_symbol);
|
||||
} else { /* code_len == 16..17, extra_bits == 2..3 */
|
||||
uint32_t extra_bits =
|
||||
brotli_reg_t extra_bits =
|
||||
(code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) ? 2 : 3;
|
||||
uint32_t repeat_delta =
|
||||
(uint32_t)BrotliGetBitsUnmasked(br) & BitMask(extra_bits);
|
||||
brotli_reg_t repeat_delta =
|
||||
BrotliGetBitsUnmasked(br) & BitMask(extra_bits);
|
||||
BrotliDropBits(br, extra_bits);
|
||||
ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
|
||||
&symbol, &repeat, &space, &prev_code_len, &repeat_code_len,
|
||||
@ -643,15 +643,15 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
|
||||
}
|
||||
|
||||
static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
||||
uint32_t alphabet_size, BrotliDecoderState* s) {
|
||||
brotli_reg_t alphabet_size, BrotliDecoderState* s) {
|
||||
BrotliBitReader* br = &s->br;
|
||||
BrotliMetablockHeaderArena* h = &s->arena.header;
|
||||
BROTLI_BOOL get_byte = BROTLI_FALSE;
|
||||
while (h->symbol < alphabet_size && h->space > 0) {
|
||||
const HuffmanCode* p = h->table;
|
||||
uint32_t code_len;
|
||||
uint32_t available_bits;
|
||||
uint32_t bits = 0;
|
||||
brotli_reg_t code_len;
|
||||
brotli_reg_t available_bits;
|
||||
brotli_reg_t bits = 0;
|
||||
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
|
||||
if (get_byte && !BrotliPullByte(br)) return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
||||
get_byte = BROTLI_FALSE;
|
||||
@ -672,8 +672,8 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
||||
&h->prev_code_len, h->symbol_lists, h->code_length_histo,
|
||||
h->next_symbol);
|
||||
} else { /* code_len == 16..17, extra_bits == 2..3 */
|
||||
uint32_t extra_bits = code_len - 14U;
|
||||
uint32_t repeat_delta = (bits >> BROTLI_HC_FAST_LOAD_BITS(p)) &
|
||||
brotli_reg_t extra_bits = code_len - 14U;
|
||||
brotli_reg_t repeat_delta = (bits >> BROTLI_HC_FAST_LOAD_BITS(p)) &
|
||||
BitMask(extra_bits);
|
||||
if (available_bits < BROTLI_HC_FAST_LOAD_BITS(p) + extra_bits) {
|
||||
get_byte = BROTLI_TRUE;
|
||||
@ -694,15 +694,15 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
|
||||
static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
|
||||
BrotliBitReader* br = &s->br;
|
||||
BrotliMetablockHeaderArena* h = &s->arena.header;
|
||||
uint32_t num_codes = h->repeat;
|
||||
unsigned space = h->space;
|
||||
uint32_t i = h->sub_loop_counter;
|
||||
brotli_reg_t num_codes = h->repeat;
|
||||
brotli_reg_t space = h->space;
|
||||
brotli_reg_t i = h->sub_loop_counter;
|
||||
for (; i < BROTLI_CODE_LENGTH_CODES; ++i) {
|
||||
const uint8_t code_len_idx = kCodeLengthCodeOrder[i];
|
||||
uint32_t ix;
|
||||
uint32_t v;
|
||||
brotli_reg_t ix;
|
||||
brotli_reg_t v;
|
||||
if (BROTLI_PREDICT_FALSE(!BrotliSafeGetBits(br, 4, &ix))) {
|
||||
uint32_t available_bits = BrotliGetAvailableBits(br);
|
||||
brotli_reg_t available_bits = BrotliGetAvailableBits(br);
|
||||
if (available_bits != 0) {
|
||||
ix = BrotliGetBitsUnmasked(br) & 0xF;
|
||||
} else {
|
||||
@ -747,10 +747,10 @@ static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
|
||||
encoded with predefined entropy code. 32 - 74 bits are used.
|
||||
B.2) Decoded table is used to decode code lengths of symbols in resulting
|
||||
Huffman table. In worst case 3520 bits are read. */
|
||||
static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
|
||||
uint32_t alphabet_size_limit,
|
||||
static BrotliDecoderErrorCode ReadHuffmanCode(brotli_reg_t alphabet_size_max,
|
||||
brotli_reg_t alphabet_size_limit,
|
||||
HuffmanCode* table,
|
||||
uint32_t* opt_table_size,
|
||||
brotli_reg_t* opt_table_size,
|
||||
BrotliDecoderState* s) {
|
||||
BrotliBitReader* br = &s->br;
|
||||
BrotliMetablockHeaderArena* h = &s->arena.header;
|
||||
@ -796,9 +796,9 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
|
||||
/* Fall through. */
|
||||
|
||||
case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: {
|
||||
uint32_t table_size;
|
||||
brotli_reg_t table_size;
|
||||
if (h->symbol == 3) {
|
||||
uint32_t bits;
|
||||
brotli_reg_t bits;
|
||||
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
||||
h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
|
||||
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
||||
@ -806,8 +806,9 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
|
||||
h->symbol += bits;
|
||||
}
|
||||
BROTLI_LOG_UINT(h->symbol);
|
||||
table_size = BrotliBuildSimpleHuffmanTable(
|
||||
table, HUFFMAN_TABLE_BITS, h->symbols_lists_array, h->symbol);
|
||||
table_size = BrotliBuildSimpleHuffmanTable(table, HUFFMAN_TABLE_BITS,
|
||||
h->symbols_lists_array,
|
||||
(uint32_t)h->symbol);
|
||||
if (opt_table_size) {
|
||||
*opt_table_size = table_size;
|
||||
}
|
||||
@ -817,7 +818,7 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
|
||||
|
||||
/* Decode Huffman-coded code lengths. */
|
||||
case BROTLI_STATE_HUFFMAN_COMPLEX: {
|
||||
uint32_t i;
|
||||
brotli_reg_t i;
|
||||
BrotliDecoderErrorCode result = ReadCodeLengthCodeLengths(s);
|
||||
if (result != BROTLI_DECODER_SUCCESS) {
|
||||
return result;
|
||||
@ -841,7 +842,7 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
|
||||
/* Fall through. */
|
||||
|
||||
case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: {
|
||||
uint32_t table_size;
|
||||
brotli_reg_t table_size;
|
||||
BrotliDecoderErrorCode result = ReadSymbolCodeLengths(
|
||||
alphabet_size_limit, s);
|
||||
if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) {
|
||||
@ -872,10 +873,10 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
|
||||
}
|
||||
|
||||
/* Decodes a block length by reading 3..39 bits. */
|
||||
static BROTLI_INLINE uint32_t ReadBlockLength(const HuffmanCode* table,
|
||||
BrotliBitReader* br) {
|
||||
uint32_t code;
|
||||
uint32_t nbits;
|
||||
static BROTLI_INLINE brotli_reg_t ReadBlockLength(const HuffmanCode* table,
|
||||
BrotliBitReader* br) {
|
||||
brotli_reg_t code;
|
||||
brotli_reg_t nbits;
|
||||
code = ReadSymbol(table, br);
|
||||
nbits = _kBrotliPrefixCodeRanges[code].nbits; /* nbits == 2..24 */
|
||||
return _kBrotliPrefixCodeRanges[code].offset + BrotliReadBits24(br, nbits);
|
||||
@ -884,9 +885,9 @@ static BROTLI_INLINE uint32_t ReadBlockLength(const HuffmanCode* table,
|
||||
/* WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then
|
||||
reading can't be continued with ReadBlockLength. */
|
||||
static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
|
||||
BrotliDecoderState* s, uint32_t* result, const HuffmanCode* table,
|
||||
BrotliDecoderState* s, brotli_reg_t* result, const HuffmanCode* table,
|
||||
BrotliBitReader* br) {
|
||||
uint32_t index;
|
||||
brotli_reg_t index;
|
||||
if (s->substate_read_block_length == BROTLI_STATE_READ_BLOCK_LENGTH_NONE) {
|
||||
if (!SafeReadSymbol(table, br, &index)) {
|
||||
return BROTLI_FALSE;
|
||||
@ -895,9 +896,9 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
|
||||
index = s->block_length_index;
|
||||
}
|
||||
{
|
||||
uint32_t bits;
|
||||
uint32_t nbits = _kBrotliPrefixCodeRanges[index].nbits;
|
||||
uint32_t offset = _kBrotliPrefixCodeRanges[index].offset;
|
||||
brotli_reg_t bits;
|
||||
brotli_reg_t nbits = _kBrotliPrefixCodeRanges[index].nbits;
|
||||
brotli_reg_t offset = _kBrotliPrefixCodeRanges[index].offset;
|
||||
if (!BrotliSafeReadBits(br, nbits, &bits)) {
|
||||
s->block_length_index = index;
|
||||
s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX;
|
||||
@ -924,10 +925,10 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
|
||||
Most of input values are 0 and 1. To reduce number of branches, we replace
|
||||
inner for loop with do-while. */
|
||||
static BROTLI_NOINLINE void InverseMoveToFrontTransform(
|
||||
uint8_t* v, uint32_t v_len, BrotliDecoderState* state) {
|
||||
uint8_t* v, brotli_reg_t v_len, BrotliDecoderState* state) {
|
||||
/* Reinitialize elements that could have been changed. */
|
||||
uint32_t i = 1;
|
||||
uint32_t upper_bound = state->mtf_upper_bound;
|
||||
brotli_reg_t i = 1;
|
||||
brotli_reg_t upper_bound = state->mtf_upper_bound;
|
||||
uint32_t* mtf = &state->mtf[1]; /* Make mtf[-1] addressable. */
|
||||
uint8_t* mtf_u8 = (uint8_t*)mtf;
|
||||
/* Load endian-aware constant. */
|
||||
@ -970,7 +971,7 @@ static BrotliDecoderErrorCode HuffmanTreeGroupDecode(
|
||||
h->substate_tree_group = BROTLI_STATE_TREE_GROUP_LOOP;
|
||||
}
|
||||
while (h->htree_index < group->num_htrees) {
|
||||
uint32_t table_size;
|
||||
brotli_reg_t table_size;
|
||||
BrotliDecoderErrorCode result = ReadHuffmanCode(group->alphabet_size_max,
|
||||
group->alphabet_size_limit, h->next, &table_size, s);
|
||||
if (result != BROTLI_DECODER_SUCCESS) return result;
|
||||
@ -990,8 +991,8 @@ static BrotliDecoderErrorCode HuffmanTreeGroupDecode(
|
||||
This table will be used for reading context map items.
|
||||
3) Read context map items; "0" values could be run-length encoded.
|
||||
4) Optionally, apply InverseMoveToFront transform to the resulting map. */
|
||||
static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
||||
uint32_t* num_htrees,
|
||||
static BrotliDecoderErrorCode DecodeContextMap(brotli_reg_t context_map_size,
|
||||
brotli_reg_t* num_htrees,
|
||||
uint8_t** context_map_arg,
|
||||
BrotliDecoderState* s) {
|
||||
BrotliBitReader* br = &s->br;
|
||||
@ -1021,7 +1022,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
||||
/* Fall through. */
|
||||
|
||||
case BROTLI_STATE_CONTEXT_MAP_READ_PREFIX: {
|
||||
uint32_t bits;
|
||||
brotli_reg_t bits;
|
||||
/* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe
|
||||
to peek 4 bits ahead. */
|
||||
if (!BrotliSafeGetBits(br, 5, &bits)) {
|
||||
@ -1040,7 +1041,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
||||
/* Fall through. */
|
||||
|
||||
case BROTLI_STATE_CONTEXT_MAP_HUFFMAN: {
|
||||
uint32_t alphabet_size = *num_htrees + h->max_run_length_prefix;
|
||||
brotli_reg_t alphabet_size = *num_htrees + h->max_run_length_prefix;
|
||||
result = ReadHuffmanCode(alphabet_size, alphabet_size,
|
||||
h->context_map_table, NULL, s);
|
||||
if (result != BROTLI_DECODER_SUCCESS) return result;
|
||||
@ -1050,10 +1051,10 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
||||
/* Fall through. */
|
||||
|
||||
case BROTLI_STATE_CONTEXT_MAP_DECODE: {
|
||||
uint32_t context_index = h->context_index;
|
||||
uint32_t max_run_length_prefix = h->max_run_length_prefix;
|
||||
brotli_reg_t context_index = h->context_index;
|
||||
brotli_reg_t max_run_length_prefix = h->max_run_length_prefix;
|
||||
uint8_t* context_map = *context_map_arg;
|
||||
uint32_t code = h->code;
|
||||
brotli_reg_t code = h->code;
|
||||
BROTLI_BOOL skip_preamble = (code != 0xFFFF);
|
||||
while (context_index < context_map_size || skip_preamble) {
|
||||
if (!skip_preamble) {
|
||||
@ -1078,7 +1079,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
||||
}
|
||||
/* RLE sub-stage. */
|
||||
{
|
||||
uint32_t reps;
|
||||
brotli_reg_t reps;
|
||||
if (!BrotliSafeReadBits(br, code, &reps)) {
|
||||
h->code = code;
|
||||
h->context_index = context_index;
|
||||
@ -1099,7 +1100,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
||||
/* Fall through. */
|
||||
|
||||
case BROTLI_STATE_CONTEXT_MAP_TRANSFORM: {
|
||||
uint32_t bits;
|
||||
brotli_reg_t bits;
|
||||
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
||||
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
|
||||
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
||||
@ -1121,14 +1122,14 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
|
||||
Reads 3..54 bits. */
|
||||
static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
|
||||
int safe, BrotliDecoderState* s, int tree_type) {
|
||||
uint32_t max_block_type = s->num_block_types[tree_type];
|
||||
brotli_reg_t max_block_type = s->num_block_types[tree_type];
|
||||
const HuffmanCode* type_tree = &s->block_type_trees[
|
||||
tree_type * BROTLI_HUFFMAN_MAX_SIZE_258];
|
||||
const HuffmanCode* len_tree = &s->block_len_trees[
|
||||
tree_type * BROTLI_HUFFMAN_MAX_SIZE_26];
|
||||
BrotliBitReader* br = &s->br;
|
||||
uint32_t* ringbuffer = &s->block_type_rb[tree_type * 2];
|
||||
uint32_t block_type;
|
||||
brotli_reg_t* ringbuffer = &s->block_type_rb[tree_type * 2];
|
||||
brotli_reg_t block_type;
|
||||
if (max_block_type <= 1) {
|
||||
return BROTLI_FALSE;
|
||||
}
|
||||
@ -1173,6 +1174,7 @@ static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(
|
||||
size_t sample = s->context_map[offset];
|
||||
size_t j;
|
||||
for (j = 0; j < (1u << BROTLI_LITERAL_CONTEXT_BITS);) {
|
||||
/* NOLINTNEXTLINE(bugprone-macro-repeated-side-effects) */
|
||||
BROTLI_REPEAT_4({ error |= s->context_map[offset + j++] ^ sample; })
|
||||
}
|
||||
if (error == 0) {
|
||||
@ -1184,8 +1186,8 @@ static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(
|
||||
static BROTLI_INLINE void PrepareLiteralDecoding(BrotliDecoderState* s) {
|
||||
uint8_t context_mode;
|
||||
size_t trivial;
|
||||
uint32_t block_type = s->block_type_rb[1];
|
||||
uint32_t context_offset = block_type << BROTLI_LITERAL_CONTEXT_BITS;
|
||||
brotli_reg_t block_type = s->block_type_rb[1];
|
||||
brotli_reg_t context_offset = block_type << BROTLI_LITERAL_CONTEXT_BITS;
|
||||
s->context_map_slice = s->context_map + context_offset;
|
||||
trivial = s->trivial_literal_contexts[block_type >> 5];
|
||||
s->trivial_literal_context = (trivial >> (block_type & 31)) & 1;
|
||||
@ -1549,8 +1551,8 @@ static int CopyFromCompoundDictionary(BrotliDecoderState* s, int pos) {
|
||||
BROTLI_BOOL BrotliDecoderAttachDictionary(
|
||||
BrotliDecoderState* state, BrotliSharedDictionaryType type,
|
||||
size_t data_size, const uint8_t data[BROTLI_ARRAY_PARAM(data_size)]) {
|
||||
uint32_t i;
|
||||
uint32_t num_prefix_before = state->dictionary->num_prefix;
|
||||
brotli_reg_t i;
|
||||
brotli_reg_t num_prefix_before = state->dictionary->num_prefix;
|
||||
if (state->state != BROTLI_STATE_UNINITED) return BROTLI_FALSE;
|
||||
if (!BrotliSharedDictionaryAttach(state->dictionary, type, data_size, data)) {
|
||||
return BROTLI_FALSE;
|
||||
@ -1616,7 +1618,7 @@ static BrotliDecoderErrorCode ReadContextModes(BrotliDecoderState* s) {
|
||||
int i = s->loop_counter;
|
||||
|
||||
while (i < (int)s->num_block_types[0]) {
|
||||
uint32_t bits;
|
||||
brotli_reg_t bits;
|
||||
if (!BrotliSafeReadBits(br, 2, &bits)) {
|
||||
s->loop_counter = i;
|
||||
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
||||
@ -1656,7 +1658,7 @@ static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliDecoderState* s) {
|
||||
}
|
||||
|
||||
static BROTLI_INLINE BROTLI_BOOL SafeReadBits(
|
||||
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
||||
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
||||
if (n_bits != 0) {
|
||||
return BrotliSafeReadBits(br, n_bits, val);
|
||||
} else {
|
||||
@ -1666,7 +1668,7 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBits(
|
||||
}
|
||||
|
||||
static BROTLI_INLINE BROTLI_BOOL SafeReadBits32(
|
||||
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
||||
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
||||
if (n_bits != 0) {
|
||||
return BrotliSafeReadBits32(br, n_bits, val);
|
||||
} else {
|
||||
@ -1744,16 +1746,16 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBits32(
|
||||
NB: it is possible to have all 64 tables precalculated. */
|
||||
static void CalculateDistanceLut(BrotliDecoderState* s) {
|
||||
BrotliMetablockBodyArena* b = &s->arena.body;
|
||||
uint32_t npostfix = s->distance_postfix_bits;
|
||||
uint32_t ndirect = s->num_direct_distance_codes;
|
||||
uint32_t alphabet_size_limit = s->distance_hgroup.alphabet_size_limit;
|
||||
uint32_t postfix = 1u << npostfix;
|
||||
uint32_t j;
|
||||
uint32_t bits = 1;
|
||||
uint32_t half = 0;
|
||||
brotli_reg_t npostfix = s->distance_postfix_bits;
|
||||
brotli_reg_t ndirect = s->num_direct_distance_codes;
|
||||
brotli_reg_t alphabet_size_limit = s->distance_hgroup.alphabet_size_limit;
|
||||
brotli_reg_t postfix = 1u << npostfix;
|
||||
brotli_reg_t j;
|
||||
brotli_reg_t bits = 1;
|
||||
brotli_reg_t half = 0;
|
||||
|
||||
/* Skip short codes. */
|
||||
uint32_t i = BROTLI_NUM_DISTANCE_SHORT_CODES;
|
||||
brotli_reg_t i = BROTLI_NUM_DISTANCE_SHORT_CODES;
|
||||
|
||||
/* Fill direct codes. */
|
||||
for (j = 0; j < ndirect; ++j) {
|
||||
@ -1764,7 +1766,7 @@ static void CalculateDistanceLut(BrotliDecoderState* s) {
|
||||
|
||||
/* Fill regular distance codes. */
|
||||
while (i < alphabet_size_limit) {
|
||||
uint32_t base = ndirect + ((((2 + half) << bits) - 4) << npostfix) + 1;
|
||||
brotli_reg_t base = ndirect + ((((2 + half) << bits) - 4) << npostfix) + 1;
|
||||
/* Always fill the complete group. */
|
||||
for (j = 0; j < postfix; ++j) {
|
||||
b->dist_extra_bits[i] = (uint8_t)bits;
|
||||
@ -1780,8 +1782,8 @@ static void CalculateDistanceLut(BrotliDecoderState* s) {
|
||||
static BROTLI_INLINE BROTLI_BOOL ReadDistanceInternal(
|
||||
int safe, BrotliDecoderState* s, BrotliBitReader* br) {
|
||||
BrotliMetablockBodyArena* b = &s->arena.body;
|
||||
uint32_t code;
|
||||
uint32_t bits;
|
||||
brotli_reg_t code;
|
||||
brotli_reg_t bits;
|
||||
BrotliBitReaderState memento;
|
||||
HuffmanCode* distance_tree = s->distance_hgroup.htrees[s->dist_htree_index];
|
||||
if (!safe) {
|
||||
@ -1827,9 +1829,9 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadDistance(
|
||||
|
||||
static BROTLI_INLINE BROTLI_BOOL ReadCommandInternal(
|
||||
int safe, BrotliDecoderState* s, BrotliBitReader* br, int* insert_length) {
|
||||
uint32_t cmd_code;
|
||||
uint32_t insert_len_extra = 0;
|
||||
uint32_t copy_length;
|
||||
brotli_reg_t cmd_code;
|
||||
brotli_reg_t insert_len_extra = 0;
|
||||
brotli_reg_t copy_length;
|
||||
CmdLutElement v;
|
||||
BrotliBitReaderState memento;
|
||||
if (!safe) {
|
||||
@ -1950,8 +1952,8 @@ CommandInner:
|
||||
}
|
||||
/* Read the literals in the command. */
|
||||
if (s->trivial_literal_context) {
|
||||
uint32_t bits;
|
||||
uint32_t value;
|
||||
brotli_reg_t bits;
|
||||
brotli_reg_t value;
|
||||
PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
|
||||
do {
|
||||
if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */
|
||||
@ -1968,7 +1970,7 @@ CommandInner:
|
||||
s->ringbuffer[pos] =
|
||||
(uint8_t)ReadPreloadedSymbol(s->literal_htree, br, &bits, &value);
|
||||
} else {
|
||||
uint32_t literal;
|
||||
brotli_reg_t literal;
|
||||
if (!SafeReadSymbol(s->literal_htree, br, &literal)) {
|
||||
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
||||
goto saveStateAndReturn;
|
||||
@ -2006,7 +2008,7 @@ CommandInner:
|
||||
if (!safe) {
|
||||
p1 = (uint8_t)ReadSymbol(hc, br);
|
||||
} else {
|
||||
uint32_t literal;
|
||||
brotli_reg_t literal;
|
||||
if (!SafeReadSymbol(hc, br, &literal)) {
|
||||
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
||||
goto saveStateAndReturn;
|
||||
@ -2087,7 +2089,7 @@ CommandPostDecodeLiterals:
|
||||
const BrotliDictionary* words = s->dictionary->words[dict_id];
|
||||
const BrotliTransforms* transforms = s->dictionary->transforms[dict_id];
|
||||
int offset = (int)words->offsets_by_length[i];
|
||||
uint32_t shift = words->size_bits_by_length[i];
|
||||
brotli_reg_t shift = words->size_bits_by_length[i];
|
||||
int address =
|
||||
s->distance_code - s->max_distance - 1 - compound_dictionary_size;
|
||||
int mask = (int)BitMask(shift);
|
||||
@ -2110,7 +2112,7 @@ CommandPostDecodeLiterals:
|
||||
if (dict_id2 != dict_id && words2->size_bits_by_length[i] != 0) {
|
||||
const BrotliTransforms* transforms2 =
|
||||
s->dictionary->transforms[dict_id2];
|
||||
uint32_t shift2 = words2->size_bits_by_length[i];
|
||||
brotli_reg_t shift2 = words2->size_bits_by_length[i];
|
||||
int num = (int)((1u << shift2) & ~1u) *
|
||||
(int)transforms2->num_transforms;
|
||||
if (dist_remaining < num) {
|
||||
@ -2410,17 +2412,20 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||
s->state = BROTLI_STATE_INITIALIZE;
|
||||
break;
|
||||
|
||||
case BROTLI_STATE_LARGE_WINDOW_BITS:
|
||||
if (!BrotliSafeReadBits(br, 6, &s->window_bits)) {
|
||||
case BROTLI_STATE_LARGE_WINDOW_BITS: {
|
||||
brotli_reg_t bits;
|
||||
if (!BrotliSafeReadBits(br, 6, &bits)) {
|
||||
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
||||
break;
|
||||
}
|
||||
s->window_bits = (brotli_reg_t)bits;
|
||||
if (s->window_bits < BROTLI_LARGE_MIN_WBITS ||
|
||||
s->window_bits > BROTLI_LARGE_MAX_WBITS) {
|
||||
result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS);
|
||||
break;
|
||||
}
|
||||
s->state = BROTLI_STATE_INITIALIZE;
|
||||
}
|
||||
/* Fall through. */
|
||||
|
||||
case BROTLI_STATE_INITIALIZE:
|
||||
@ -2518,7 +2523,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||
/* Fall through. */
|
||||
|
||||
case BROTLI_STATE_HUFFMAN_CODE_1: {
|
||||
uint32_t alphabet_size = s->num_block_types[s->loop_counter] + 2;
|
||||
brotli_reg_t alphabet_size = s->num_block_types[s->loop_counter] + 2;
|
||||
int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_258;
|
||||
result = ReadHuffmanCode(alphabet_size, alphabet_size,
|
||||
&s->block_type_trees[tree_offset], NULL, s);
|
||||
@ -2528,7 +2533,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||
/* Fall through. */
|
||||
|
||||
case BROTLI_STATE_HUFFMAN_CODE_2: {
|
||||
uint32_t alphabet_size = BROTLI_NUM_BLOCK_LEN_SYMBOLS;
|
||||
brotli_reg_t alphabet_size = BROTLI_NUM_BLOCK_LEN_SYMBOLS;
|
||||
int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26;
|
||||
result = ReadHuffmanCode(alphabet_size, alphabet_size,
|
||||
&s->block_len_trees[tree_offset], NULL, s);
|
||||
@ -2569,7 +2574,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||
break;
|
||||
|
||||
case BROTLI_STATE_METABLOCK_HEADER_2: {
|
||||
uint32_t bits;
|
||||
brotli_reg_t bits;
|
||||
if (!BrotliSafeReadBits(br, 6, &bits)) {
|
||||
result = BROTLI_DECODER_NEEDS_MORE_INPUT;
|
||||
break;
|
||||
@ -2610,15 +2615,16 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||
/* Fall through. */
|
||||
|
||||
case BROTLI_STATE_CONTEXT_MAP_2: {
|
||||
uint32_t npostfix = s->distance_postfix_bits;
|
||||
uint32_t ndirect = s->num_direct_distance_codes;
|
||||
uint32_t distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
|
||||
brotli_reg_t npostfix = s->distance_postfix_bits;
|
||||
brotli_reg_t ndirect = s->num_direct_distance_codes;
|
||||
brotli_reg_t distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
|
||||
npostfix, ndirect, BROTLI_MAX_DISTANCE_BITS);
|
||||
uint32_t distance_alphabet_size_limit = distance_alphabet_size_max;
|
||||
brotli_reg_t distance_alphabet_size_limit = distance_alphabet_size_max;
|
||||
BROTLI_BOOL allocation_success = BROTLI_TRUE;
|
||||
if (s->large_window) {
|
||||
BrotliDistanceCodeLimit limit = BrotliCalculateDistanceCodeLimit(
|
||||
BROTLI_MAX_ALLOWED_DISTANCE, npostfix, ndirect);
|
||||
BROTLI_MAX_ALLOWED_DISTANCE, (uint32_t)npostfix,
|
||||
(uint32_t)ndirect);
|
||||
distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
|
||||
npostfix, ndirect, BROTLI_LARGE_MAX_DISTANCE_BITS);
|
||||
distance_alphabet_size_limit = limit.max_alphabet_size;
|
||||
@ -2846,16 +2852,16 @@ void BrotliDecoderSetMetadataCallbacks(
|
||||
/* Escalate internal functions visibility; for testing purposes only. */
|
||||
#if defined(BROTLI_TEST)
|
||||
BROTLI_BOOL SafeReadSymbolForTest(
|
||||
const HuffmanCode*, BrotliBitReader*, uint32_t*);
|
||||
const HuffmanCode*, BrotliBitReader*, brotli_reg_t*);
|
||||
BROTLI_BOOL SafeReadSymbolForTest(
|
||||
const HuffmanCode* table, BrotliBitReader* br, uint32_t* result) {
|
||||
const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) {
|
||||
return SafeReadSymbol(table, br, result);
|
||||
}
|
||||
|
||||
void InverseMoveToFrontTransformForTest(
|
||||
uint8_t*, uint32_t, BrotliDecoderState*);
|
||||
uint8_t*, brotli_reg_t, BrotliDecoderState*);
|
||||
void InverseMoveToFrontTransformForTest(
|
||||
uint8_t* v, uint32_t l, BrotliDecoderState* s) {
|
||||
uint8_t* v, brotli_reg_t l, BrotliDecoderState* s) {
|
||||
InverseMoveToFrontTransform(v, l, s);
|
||||
}
|
||||
#endif
|
||||
|
@ -158,8 +158,8 @@ void BrotliDecoderStateCleanup(BrotliDecoderState* s) {
|
||||
}
|
||||
|
||||
BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s,
|
||||
HuffmanTreeGroup* group, uint32_t alphabet_size_max,
|
||||
uint32_t alphabet_size_limit, uint32_t ntrees) {
|
||||
HuffmanTreeGroup* group, brotli_reg_t alphabet_size_max,
|
||||
brotli_reg_t alphabet_size_limit, brotli_reg_t ntrees) {
|
||||
/* 376 = 256 (1-st level table) + 4 + 7 + 15 + 31 + 63 (2-nd level mix-tables)
|
||||
This number is discovered "unlimited" "enough" calculator; it is actually
|
||||
a wee bigger than required in several cases (especially for alphabets with
|
||||
|
@ -211,15 +211,15 @@ typedef struct BrotliMetablockHeaderArena {
|
||||
BrotliRunningContextMapState substate_context_map;
|
||||
BrotliRunningHuffmanState substate_huffman;
|
||||
|
||||
uint32_t sub_loop_counter;
|
||||
brotli_reg_t sub_loop_counter;
|
||||
|
||||
uint32_t repeat_code_len;
|
||||
uint32_t prev_code_len;
|
||||
brotli_reg_t repeat_code_len;
|
||||
brotli_reg_t prev_code_len;
|
||||
|
||||
/* For ReadHuffmanCode. */
|
||||
uint32_t symbol;
|
||||
uint32_t repeat;
|
||||
uint32_t space;
|
||||
brotli_reg_t symbol;
|
||||
brotli_reg_t repeat;
|
||||
brotli_reg_t space;
|
||||
|
||||
/* Huffman table for "histograms". */
|
||||
HuffmanCode table[32];
|
||||
@ -239,15 +239,15 @@ typedef struct BrotliMetablockHeaderArena {
|
||||
HuffmanCode* next;
|
||||
|
||||
/* For DecodeContextMap. */
|
||||
uint32_t context_index;
|
||||
uint32_t max_run_length_prefix;
|
||||
uint32_t code;
|
||||
brotli_reg_t context_index;
|
||||
brotli_reg_t max_run_length_prefix;
|
||||
brotli_reg_t code;
|
||||
HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
|
||||
} BrotliMetablockHeaderArena;
|
||||
|
||||
typedef struct BrotliMetablockBodyArena {
|
||||
uint8_t dist_extra_bits[544];
|
||||
uint32_t dist_offset[544];
|
||||
brotli_reg_t dist_offset[544];
|
||||
} BrotliMetablockBodyArena;
|
||||
|
||||
struct BrotliDecoderStateStruct {
|
||||
@ -268,7 +268,7 @@ struct BrotliDecoderStateStruct {
|
||||
uint64_t u64;
|
||||
uint8_t u8[8];
|
||||
} buffer;
|
||||
uint32_t buffer_length;
|
||||
brotli_reg_t buffer_length;
|
||||
|
||||
int pos;
|
||||
int max_backward_distance;
|
||||
@ -298,14 +298,14 @@ struct BrotliDecoderStateStruct {
|
||||
/* Distance context is actual after command is decoded and before distance is
|
||||
computed. After distance computation it is used as a temporary variable. */
|
||||
int distance_context;
|
||||
brotli_reg_t block_length[3];
|
||||
int meta_block_remaining_len;
|
||||
uint32_t block_length_index;
|
||||
uint32_t block_length[3];
|
||||
uint32_t num_block_types[3];
|
||||
uint32_t block_type_rb[6];
|
||||
uint32_t distance_postfix_bits;
|
||||
uint32_t num_direct_distance_codes;
|
||||
uint32_t num_dist_htrees;
|
||||
brotli_reg_t block_length_index;
|
||||
brotli_reg_t num_block_types[3];
|
||||
brotli_reg_t block_type_rb[6];
|
||||
brotli_reg_t distance_postfix_bits;
|
||||
brotli_reg_t num_direct_distance_codes;
|
||||
brotli_reg_t num_dist_htrees;
|
||||
uint8_t* dist_context_map;
|
||||
HuffmanCode* literal_htree;
|
||||
uint8_t dist_htree_index;
|
||||
@ -318,7 +318,7 @@ struct BrotliDecoderStateStruct {
|
||||
size_t partial_pos_out; /* how much output to the user in total */
|
||||
|
||||
/* For InverseMoveToFrontTransform. */
|
||||
uint32_t mtf_upper_bound;
|
||||
brotli_reg_t mtf_upper_bound;
|
||||
uint32_t mtf[64 + 1];
|
||||
|
||||
/* Less used attributes are at the end of this struct. */
|
||||
@ -343,11 +343,11 @@ struct BrotliDecoderStateStruct {
|
||||
unsigned int canny_ringbuffer_allocation : 1;
|
||||
unsigned int large_window : 1;
|
||||
unsigned int size_nibbles : 8;
|
||||
uint32_t window_bits;
|
||||
brotli_reg_t window_bits;
|
||||
|
||||
int new_ringbuffer_size;
|
||||
|
||||
uint32_t num_literal_htrees;
|
||||
brotli_reg_t num_literal_htrees;
|
||||
uint8_t* context_map;
|
||||
uint8_t* context_modes;
|
||||
|
||||
@ -372,8 +372,9 @@ BROTLI_INTERNAL void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s);
|
||||
BROTLI_INTERNAL void BrotliDecoderStateCleanupAfterMetablock(
|
||||
BrotliDecoderState* s);
|
||||
BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(
|
||||
BrotliDecoderState* s, HuffmanTreeGroup* group, uint32_t alphabet_size_max,
|
||||
uint32_t alphabet_size_limit, uint32_t ntrees);
|
||||
BrotliDecoderState* s, HuffmanTreeGroup* group,
|
||||
brotli_reg_t alphabet_size_max, brotli_reg_t alphabet_size_limit,
|
||||
brotli_reg_t ntrees);
|
||||
|
||||
#define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
|
||||
|
||||
|
@ -27,11 +27,6 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
size_t total_out = 0;
|
||||
|
||||
BrotliDecoderState* state = BrotliDecoderCreateInstance(0, 0, 0);
|
||||
if (!state) {
|
||||
// OOM is out-of-scope here.
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (addend == 0)
|
||||
addend = size;
|
||||
|
@ -13,13 +13,6 @@ def create_msvc_config():
|
||||
# flag_values{"@bazel_tools//tools/cpp:compiler"} and the else branch can
|
||||
# be removed.
|
||||
if hasattr(cc_common, "do_not_use_tools_cpp_compiler_present"):
|
||||
native.config_setting(
|
||||
name = "clang-cl",
|
||||
flag_values = {
|
||||
"@bazel_tools//tools/cpp:compiler": "clang-cl",
|
||||
},
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
native.config_setting(
|
||||
name = "msvc",
|
||||
flag_values = {
|
||||
@ -28,11 +21,6 @@ def create_msvc_config():
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
else:
|
||||
native.config_setting(
|
||||
name = "clang-cl",
|
||||
values = {"compiler": "clang-cl"},
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
native.config_setting(
|
||||
name = "msvc",
|
||||
values = {"compiler": "msvc-cl"},
|
||||
|
Loading…
Reference in New Issue
Block a user