mirror of
https://github.com/google/brotli.git
synced 2024-11-09 13:40:06 +00:00
Merge branch 'master' into dependabot/github_actions/actions/setup-python-4.7.1
This commit is contained in:
commit
bf867c126b
50
.github/workflows/build_test.yml
vendored
50
.github/workflows/build_test.yml
vendored
@ -43,28 +43,28 @@ jobs:
|
|||||||
# TODO: consider running this combination in docker
|
# TODO: consider running this combination in docker
|
||||||
#- name: cmake:clang3.5
|
#- name: cmake:clang3.5
|
||||||
|
|
||||||
- name: cmake:clang12
|
- name: cmake:clang15
|
||||||
build_system: cmake
|
build_system: cmake
|
||||||
c_compiler: clang-12
|
c_compiler: clang-15
|
||||||
cxx_compiler: clang++12
|
cxx_compiler: clang++15
|
||||||
|
|
||||||
- name: cmake:clang12:asan
|
- name: cmake:clang15:asan
|
||||||
build_system: cmake
|
build_system: cmake
|
||||||
sanitizer: address
|
sanitizer: address
|
||||||
c_compiler: clang-12
|
c_compiler: clang-15
|
||||||
cxx_compiler: clang++12
|
cxx_compiler: clang++15
|
||||||
|
|
||||||
- name: cmake:clang12:tsan
|
- name: cmake:clang15:tsan
|
||||||
build_system: cmake
|
build_system: cmake
|
||||||
sanitizer: thread
|
sanitizer: thread
|
||||||
c_compiler: clang-12
|
c_compiler: clang-15
|
||||||
cxx_compiler: clang++12
|
cxx_compiler: clang++15
|
||||||
|
|
||||||
- name: cmake:clang12:ubsan
|
- name: cmake:clang15:ubsan
|
||||||
build_system: cmake
|
build_system: cmake
|
||||||
sanitizer: undefined
|
sanitizer: undefined
|
||||||
c_compiler: clang-12
|
c_compiler: clang-15
|
||||||
cxx_compiler: clang++-12
|
cxx_compiler: clang++-15
|
||||||
c_flags: -fno-sanitize-recover=undefined,integer
|
c_flags: -fno-sanitize-recover=undefined,integer
|
||||||
|
|
||||||
- name: cmake:qemu-arm-neon-gcc
|
- name: cmake:qemu-arm-neon-gcc
|
||||||
@ -98,10 +98,10 @@ jobs:
|
|||||||
cmake_config: Debug
|
cmake_config: Debug
|
||||||
os: windows-2019
|
os: windows-2019
|
||||||
|
|
||||||
- name: fuzz:clang12
|
- name: fuzz:clang15
|
||||||
build_system: fuzz
|
build_system: fuzz
|
||||||
c_compiler: clang-12
|
c_compiler: clang-15
|
||||||
cxx_compiler: clang++12
|
cxx_compiler: clang++15
|
||||||
|
|
||||||
# TODO: consider running this combination in docker
|
# TODO: consider running this combination in docker
|
||||||
#- name: python2.7:gcc5
|
#- name: python2.7:gcc5
|
||||||
@ -131,15 +131,15 @@ jobs:
|
|||||||
# TODO: consider running this combination in docker
|
# TODO: consider running this combination in docker
|
||||||
#- name: python3.8:gcc5
|
#- name: python3.8:gcc5
|
||||||
|
|
||||||
- name: python39:clang12
|
- name: python3.10:clang15
|
||||||
build_system: python
|
build_system: python
|
||||||
python_version: 3.9
|
python_version: "3.10"
|
||||||
c_compiler: clang-12
|
c_compiler: clang-15
|
||||||
cxx_compiler: clang++-12
|
cxx_compiler: clang++-15
|
||||||
|
|
||||||
- name: python39-win
|
- name: python3.10-win
|
||||||
build_system: python
|
build_system: python
|
||||||
python_version: 3.9
|
python_version: "3.10"
|
||||||
# TODO: investigate why win-builds can't run tests
|
# TODO: investigate why win-builds can't run tests
|
||||||
py_setuptools_cmd: build_ext
|
py_setuptools_cmd: build_ext
|
||||||
os: windows-2019
|
os: windows-2019
|
||||||
@ -195,7 +195,7 @@ jobs:
|
|||||||
- name: bazel-win:root
|
- name: bazel-win:root
|
||||||
build_system: bazel
|
build_system: bazel
|
||||||
bazel_project: .
|
bazel_project: .
|
||||||
os: windows-2019
|
os: windows-latest
|
||||||
|
|
||||||
# TODO: use single dll on windows, otherwise it fails to link
|
# TODO: use single dll on windows, otherwise it fails to link
|
||||||
#- name: bazel-win:go
|
#- name: bazel-win:go
|
||||||
@ -206,7 +206,7 @@ jobs:
|
|||||||
- name: bazel-win:java
|
- name: bazel-win:java
|
||||||
build_system: bazel
|
build_system: bazel
|
||||||
bazel_project: java
|
bazel_project: java
|
||||||
os: windows-2019
|
os: windows-latest
|
||||||
|
|
||||||
# TODO: blocked by Bazel Closure rules issue
|
# TODO: blocked by Bazel Closure rules issue
|
||||||
#- name: bazel-win:js
|
#- name: bazel-win:js
|
||||||
@ -217,7 +217,7 @@ jobs:
|
|||||||
- name: bazel-win:research
|
- name: bazel-win:research
|
||||||
build_system: bazel
|
build_system: bazel
|
||||||
bazel_project: research
|
bazel_project: research
|
||||||
os: windows-2019
|
os: windows-latest
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.c_compiler || 'gcc' }}
|
CC: ${{ matrix.c_compiler || 'gcc' }}
|
||||||
@ -226,7 +226,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Install extra deps @ Ubuntu
|
- name: Install extra deps @ Ubuntu
|
||||||
if: ${{ runner.os == 'Linux' }}
|
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{13-15}, cmake, gcc{9.5-13.1}, java{8,11,17,21}, maven, python{3.10}
|
||||||
run: |
|
run: |
|
||||||
EXTRA_PACKAGES="${{ matrix.extra_apt_pkgs || '' }}"
|
EXTRA_PACKAGES="${{ matrix.extra_apt_pkgs || '' }}"
|
||||||
sudo apt update
|
sudo apt update
|
||||||
|
2
.github/workflows/release.yaml
vendored
2
.github/workflows/release.yaml
vendored
@ -23,7 +23,7 @@ concurrency:
|
|||||||
jobs:
|
jobs:
|
||||||
windows_build:
|
windows_build:
|
||||||
name: Windows Build (vcpkg / ${{ matrix.triplet }})
|
name: Windows Build (vcpkg / ${{ matrix.triplet }})
|
||||||
runs-on: [windows-2022]
|
runs-on: [windows-latest]
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -11,10 +11,11 @@ cmake_policy(SET CMP0048 NEW)
|
|||||||
project(brotli C)
|
project(brotli C)
|
||||||
|
|
||||||
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
||||||
|
set(BROTLI_BUILD_TOOLS ON CACHE BOOL "Build/install CLI tools")
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
message(STATUS "Setting build type to Release as none was specified.")
|
message(STATUS "Setting build type to Release as none was specified.")
|
||||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
|
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build" FORCE)
|
||||||
else()
|
else()
|
||||||
message(STATUS "Build type is '${CMAKE_BUILD_TYPE}'")
|
message(STATUS "Build type is '${CMAKE_BUILD_TYPE}'")
|
||||||
endif()
|
endif()
|
||||||
@ -81,7 +82,7 @@ include(CheckFunctionExists)
|
|||||||
set(LIBM_LIBRARY)
|
set(LIBM_LIBRARY)
|
||||||
CHECK_FUNCTION_EXISTS(log2 LOG2_RES)
|
CHECK_FUNCTION_EXISTS(log2 LOG2_RES)
|
||||||
if(NOT LOG2_RES)
|
if(NOT LOG2_RES)
|
||||||
set(orig_req_libs "${CMAKE_REQUIRED_LIBRARIES}")
|
set(_ORIG_REQ_LIBS "${CMAKE_REQUIRED_LIBRARIES}")
|
||||||
set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};m")
|
set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};m")
|
||||||
CHECK_FUNCTION_EXISTS(log2 LOG2_LIBM_RES)
|
CHECK_FUNCTION_EXISTS(log2 LOG2_LIBM_RES)
|
||||||
if(LOG2_LIBM_RES)
|
if(LOG2_LIBM_RES)
|
||||||
@ -91,9 +92,9 @@ if(NOT LOG2_RES)
|
|||||||
add_definitions(-DBROTLI_HAVE_LOG2=0)
|
add_definitions(-DBROTLI_HAVE_LOG2=0)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES "${orig_req_libs}")
|
set(CMAKE_REQUIRED_LIBRARIES "${_ORIG_REQ_LIBS}")
|
||||||
unset(LOG2_LIBM_RES)
|
unset(LOG2_LIBM_RES)
|
||||||
unset(orig_req_libs)
|
unset(_ORIG_REQ_LIBS)
|
||||||
else()
|
else()
|
||||||
add_definitions(-DBROTLI_HAVE_LOG2=1)
|
add_definitions(-DBROTLI_HAVE_LOG2=1)
|
||||||
endif()
|
endif()
|
||||||
@ -153,8 +154,8 @@ foreach(lib ${BROTLI_LIBRARIES_CORE})
|
|||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
if(NOT BROTLI_EMSCRIPTEN)
|
if(NOT BROTLI_EMSCRIPTEN)
|
||||||
target_link_libraries(brotlidec brotlicommon)
|
target_link_libraries(brotlidec brotlicommon)
|
||||||
target_link_libraries(brotlienc brotlicommon)
|
target_link_libraries(brotlienc brotlicommon)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# For projects stuck on older versions of CMake, this will set the
|
# For projects stuck on older versions of CMake, this will set the
|
||||||
@ -169,15 +170,19 @@ if(BROTLI_PARENT_DIRECTORY)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Build the brotli executable
|
# Build the brotli executable
|
||||||
add_executable(brotli c/tools/brotli.c)
|
if(BROTLI_BUILD_TOOLS)
|
||||||
target_link_libraries(brotli ${BROTLI_LIBRARIES})
|
add_executable(brotli c/tools/brotli.c)
|
||||||
|
target_link_libraries(brotli ${BROTLI_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
if(NOT BROTLI_BUNDLED_MODE)
|
if(NOT BROTLI_BUNDLED_MODE)
|
||||||
install(
|
if (BROTLI_BUILD_TOOLS)
|
||||||
TARGETS brotli
|
install(
|
||||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
TARGETS brotli
|
||||||
)
|
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS ${BROTLI_LIBRARIES_CORE}
|
TARGETS ${BROTLI_LIBRARIES_CORE}
|
||||||
@ -194,9 +199,10 @@ endif() # BROTLI_BUNDLED_MODE
|
|||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
|
|
||||||
# If we're targeting Windows but not running on Windows, we need Wine
|
# Integration tests, those depend on `brotli` binary
|
||||||
# to run the tests...
|
if(NOT BROTLI_DISABLE_TESTS AND BROTLI_BUILD_TOOLS)
|
||||||
if(NOT BROTLI_DISABLE_TESTS)
|
# If we're targeting Windows but not running on Windows, we need Wine
|
||||||
|
# to run the tests...
|
||||||
if(WIN32 AND NOT CMAKE_HOST_WIN32)
|
if(WIN32 AND NOT CMAKE_HOST_WIN32)
|
||||||
find_program(BROTLI_WRAPPER NAMES wine)
|
find_program(BROTLI_WRAPPER NAMES wine)
|
||||||
|
|
||||||
@ -205,11 +211,8 @@ if(NOT BROTLI_DISABLE_TESTS)
|
|||||||
set(BROTLI_DISABLE_TESTS TRUE)
|
set(BROTLI_DISABLE_TESTS TRUE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
# If our compiler is a cross-compiler that we know about (arm/aarch64),
|
||||||
|
# then we need to use qemu to execute the tests.
|
||||||
# If our compiler is a cross-compiler that we know about (arm/aarch64),
|
|
||||||
# then we need to use qemu to execute the tests.
|
|
||||||
if(NOT BROTLI_DISABLE_TESTS)
|
|
||||||
if ("${CMAKE_C_COMPILER}" MATCHES "^.*/arm-linux-gnueabihf-.*$")
|
if ("${CMAKE_C_COMPILER}" MATCHES "^.*/arm-linux-gnueabihf-.*$")
|
||||||
message(STATUS "Detected arm-linux-gnueabihf cross-compilation")
|
message(STATUS "Detected arm-linux-gnueabihf cross-compilation")
|
||||||
set(BROTLI_WRAPPER "qemu-arm")
|
set(BROTLI_WRAPPER "qemu-arm")
|
||||||
@ -227,9 +230,7 @@ if(NOT BROTLI_DISABLE_TESTS)
|
|||||||
set(BROTLI_WRAPPER "qemu-aarch64")
|
set(BROTLI_WRAPPER "qemu-aarch64")
|
||||||
set(BROTLI_WRAPPER_LD_PREFIX "/usr/aarch64-linux-gnu")
|
set(BROTLI_WRAPPER_LD_PREFIX "/usr/aarch64-linux-gnu")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT BROTLI_DISABLE_TESTS)
|
|
||||||
include(CTest)
|
include(CTest)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
@ -279,7 +280,7 @@ if(NOT BROTLI_DISABLE_TESTS)
|
|||||||
-DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${INPUT}
|
-DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${INPUT}
|
||||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/run-compatibility-test.cmake)
|
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/run-compatibility-test.cmake)
|
||||||
endforeach()
|
endforeach()
|
||||||
endif()
|
endif() # BROTLI_DISABLE_TESTS
|
||||||
|
|
||||||
# Generate a pkg-config files
|
# Generate a pkg-config files
|
||||||
|
|
||||||
@ -359,10 +360,14 @@ if(NOT BROTLI_BUNDLED_MODE)
|
|||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||||
endif() # BROTLI_BUNDLED_MODE
|
endif() # BROTLI_BUNDLED_MODE
|
||||||
|
|
||||||
INSTALL(FILES "docs/brotli.1" DESTINATION "${SHARE_INSTALL_PREFIX}/man/man1")
|
if (BROTLI_BUILD_TOOLS)
|
||||||
INSTALL(FILES docs/constants.h.3 docs/decode.h.3 docs/encode.h.3 docs/types.h.3
|
install(FILES "docs/brotli.1"
|
||||||
|
DESTINATION "${SHARE_INSTALL_PREFIX}/man/man1")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(FILES docs/constants.h.3 docs/decode.h.3 docs/encode.h.3 docs/types.h.3
|
||||||
DESTINATION "${SHARE_INSTALL_PREFIX}/man/man3")
|
DESTINATION "${SHARE_INSTALL_PREFIX}/man/man3")
|
||||||
|
|
||||||
if (ENABLE_COVERAGE STREQUAL "yes")
|
if (ENABLE_COVERAGE STREQUAL "yes")
|
||||||
SETUP_TARGET_FOR_COVERAGE(coverage test coverage)
|
setup_target_for_coverage(coverage test coverage)
|
||||||
endif ()
|
endif()
|
||||||
|
@ -271,18 +271,18 @@ static void ChooseContextMap(int quality,
|
|||||||
uint32_t two_prefix_histo[6] = { 0 };
|
uint32_t two_prefix_histo[6] = { 0 };
|
||||||
size_t total;
|
size_t total;
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t dummy;
|
size_t sink;
|
||||||
double entropy[4];
|
double entropy[4];
|
||||||
for (i = 0; i < 9; ++i) {
|
for (i = 0; i < 9; ++i) {
|
||||||
monogram_histo[i % 3] += bigram_histo[i];
|
monogram_histo[i % 3] += bigram_histo[i];
|
||||||
two_prefix_histo[i % 6] += bigram_histo[i];
|
two_prefix_histo[i % 6] += bigram_histo[i];
|
||||||
}
|
}
|
||||||
entropy[1] = ShannonEntropy(monogram_histo, 3, &dummy);
|
entropy[1] = ShannonEntropy(monogram_histo, 3, &sink);
|
||||||
entropy[2] = (ShannonEntropy(two_prefix_histo, 3, &dummy) +
|
entropy[2] = (ShannonEntropy(two_prefix_histo, 3, &sink) +
|
||||||
ShannonEntropy(two_prefix_histo + 3, 3, &dummy));
|
ShannonEntropy(two_prefix_histo + 3, 3, &sink));
|
||||||
entropy[3] = 0;
|
entropy[3] = 0;
|
||||||
for (i = 0; i < 3; ++i) {
|
for (i = 0; i < 3; ++i) {
|
||||||
entropy[3] += ShannonEntropy(bigram_histo + 3 * i, 3, &dummy);
|
entropy[3] += ShannonEntropy(bigram_histo + 3 * i, 3, &sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
total = monogram_histo[0] + monogram_histo[1] + monogram_histo[2];
|
total = monogram_histo[0] + monogram_histo[1] + monogram_histo[2];
|
||||||
@ -348,7 +348,7 @@ static BROTLI_BOOL ShouldUseComplexStaticContextMap(const uint8_t* input,
|
|||||||
uint32_t* BROTLI_RESTRICT const context_histo = arena + 32;
|
uint32_t* BROTLI_RESTRICT const context_histo = arena + 32;
|
||||||
uint32_t total = 0;
|
uint32_t total = 0;
|
||||||
double entropy[3];
|
double entropy[3];
|
||||||
size_t dummy;
|
size_t sink;
|
||||||
size_t i;
|
size_t i;
|
||||||
ContextLut utf8_lut = BROTLI_CONTEXT_LUT(CONTEXT_UTF8);
|
ContextLut utf8_lut = BROTLI_CONTEXT_LUT(CONTEXT_UTF8);
|
||||||
memset(arena, 0, sizeof(arena[0]) * 32 * 14);
|
memset(arena, 0, sizeof(arena[0]) * 32 * 14);
|
||||||
@ -370,10 +370,10 @@ static BROTLI_BOOL ShouldUseComplexStaticContextMap(const uint8_t* input,
|
|||||||
prev1 = literal;
|
prev1 = literal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entropy[1] = ShannonEntropy(combined_histo, 32, &dummy);
|
entropy[1] = ShannonEntropy(combined_histo, 32, &sink);
|
||||||
entropy[2] = 0;
|
entropy[2] = 0;
|
||||||
for (i = 0; i < 13; ++i) {
|
for (i = 0; i < 13; ++i) {
|
||||||
entropy[2] += ShannonEntropy(context_histo + (i << 5), 32, &dummy);
|
entropy[2] += ShannonEntropy(context_histo + (i << 5), 32, &sink);
|
||||||
}
|
}
|
||||||
entropy[0] = 1.0 / (double)total;
|
entropy[0] = 1.0 / (double)total;
|
||||||
entropy[1] *= entropy[0];
|
entropy[1] *= entropy[0];
|
||||||
@ -817,7 +817,7 @@ static void CopyInputToRingBuffer(BrotliEncoderState* s,
|
|||||||
reading new bytes from the input. However, at the last few indexes of
|
reading new bytes from the input. However, at the last few indexes of
|
||||||
the ring buffer, there are not enough bytes to build full-length
|
the ring buffer, there are not enough bytes to build full-length
|
||||||
substrings from. Since the hash table always contains full-length
|
substrings from. Since the hash table always contains full-length
|
||||||
substrings, we erase with dummy zeros here to make sure that those
|
substrings, we overwrite with zeros here to make sure that those
|
||||||
substrings will contain zeros at the end instead of uninitialized
|
substrings will contain zeros at the end instead of uninitialized
|
||||||
data.
|
data.
|
||||||
|
|
||||||
|
@ -118,8 +118,8 @@ static uint32_t BrotliTrieAlloc(MemoryManager* m, size_t num, BrotliTrie* trie,
|
|||||||
keep_index = (uint32_t)(*keep - trie->pool);
|
keep_index = (uint32_t)(*keep - trie->pool);
|
||||||
}
|
}
|
||||||
if (trie->pool_size == 0) {
|
if (trie->pool_size == 0) {
|
||||||
/* Have a dummy node in the front. We do not want the result to be 0, it
|
/* Have a placeholder node in the front. We do not want the result to be 0,
|
||||||
must be at least 1, 0 represents "null pointer" */
|
it must be at least 1, 0 represents "null pointer" */
|
||||||
trie->pool_size = 1;
|
trie->pool_size = 1;
|
||||||
}
|
}
|
||||||
BROTLI_ENSURE_CAPACITY(m, BrotliTrieNode, trie->pool, trie->pool_capacity,
|
BROTLI_ENSURE_CAPACITY(m, BrotliTrieNode, trie->pool, trie->pool_capacity,
|
||||||
|
@ -68,7 +68,7 @@ final class BitReader {
|
|||||||
s.halfOffset = 0;
|
s.halfOffset = 0;
|
||||||
while (bytesInBuffer < CAPACITY) {
|
while (bytesInBuffer < CAPACITY) {
|
||||||
final int spaceLeft = CAPACITY - bytesInBuffer;
|
final int spaceLeft = CAPACITY - bytesInBuffer;
|
||||||
final int len = Utils.readInput(s.input, s.byteBuffer, bytesInBuffer, spaceLeft);
|
final int len = Utils.readInput(s, s.byteBuffer, bytesInBuffer, spaceLeft);
|
||||||
// EOF is -1 in Java, but 0 in C#.
|
// EOF is -1 in Java, but 0 in C#.
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
s.endOfStreamReached = 1;
|
s.endOfStreamReached = 1;
|
||||||
@ -255,7 +255,7 @@ final class BitReader {
|
|||||||
|
|
||||||
// Now it is possible to copy bytes directly.
|
// Now it is possible to copy bytes directly.
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
final int len = Utils.readInput(s.input, data, offset, length);
|
final int len = Utils.readInput(s, data, offset, length);
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
throw new BrotliRuntimeException("Unexpected end of input");
|
throw new BrotliRuntimeException("Unexpected end of input");
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,8 @@ public class BitReaderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testReadAfterEos() {
|
public void testReadAfterEos() {
|
||||||
State reader = new State();
|
State reader = new State();
|
||||||
Decode.initState(reader, new ByteArrayInputStream(new byte[1]));
|
reader.input = new ByteArrayInputStream(new byte[1]);
|
||||||
|
Decode.initState(reader);
|
||||||
BitReader.readBits(reader, 9);
|
BitReader.readBits(reader, 9);
|
||||||
try {
|
try {
|
||||||
BitReader.checkHealth(reader, 0);
|
BitReader.checkHealth(reader, 0);
|
||||||
@ -36,7 +37,8 @@ public class BitReaderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testAccumulatorUnderflowDetected() {
|
public void testAccumulatorUnderflowDetected() {
|
||||||
State reader = new State();
|
State reader = new State();
|
||||||
Decode.initState(reader, new ByteArrayInputStream(new byte[8]));
|
reader.input = new ByteArrayInputStream(new byte[8]);
|
||||||
|
Decode.initState(reader);
|
||||||
// 65 bits is enough for both 32 and 64 bit systems.
|
// 65 bits is enough for both 32 and 64 bit systems.
|
||||||
BitReader.readBits(reader, 13);
|
BitReader.readBits(reader, 13);
|
||||||
BitReader.readBits(reader, 13);
|
BitReader.readBits(reader, 13);
|
||||||
|
@ -86,7 +86,8 @@ public class BrotliInputStream extends InputStream {
|
|||||||
this.remainingBufferBytes = 0;
|
this.remainingBufferBytes = 0;
|
||||||
this.bufferOffset = 0;
|
this.bufferOffset = 0;
|
||||||
try {
|
try {
|
||||||
Decode.initState(state, source);
|
state.input = source;
|
||||||
|
Decode.initState(state);
|
||||||
} catch (BrotliRuntimeException ex) {
|
} catch (BrotliRuntimeException ex) {
|
||||||
throw new IOException("Brotli decoder initialization failed", ex);
|
throw new IOException("Brotli decoder initialization failed", ex);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
package org.brotli.dec;
|
package org.brotli.dec;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -290,7 +289,7 @@ final class Decode {
|
|||||||
* @param s uninitialized state without associated input
|
* @param s uninitialized state without associated input
|
||||||
* @param input compressed data source
|
* @param input compressed data source
|
||||||
*/
|
*/
|
||||||
static void initState(State s, InputStream input) {
|
static void initState(State s) {
|
||||||
if (s.runningState != UNINITIALIZED) {
|
if (s.runningState != UNINITIALIZED) {
|
||||||
throw new IllegalStateException("State MUST be uninitialized");
|
throw new IllegalStateException("State MUST be uninitialized");
|
||||||
}
|
}
|
||||||
@ -302,7 +301,6 @@ final class Decode {
|
|||||||
calculateDistanceAlphabetLimit(MAX_ALLOWED_DISTANCE, 3, 15 << 3);
|
calculateDistanceAlphabetLimit(MAX_ALLOWED_DISTANCE, 3, 15 << 3);
|
||||||
s.distExtraBits = new byte[maxDistanceAlphabetLimit];
|
s.distExtraBits = new byte[maxDistanceAlphabetLimit];
|
||||||
s.distOffset = new int[maxDistanceAlphabetLimit];
|
s.distOffset = new int[maxDistanceAlphabetLimit];
|
||||||
s.input = input;
|
|
||||||
BitReader.initBitReader(s);
|
BitReader.initBitReader(s);
|
||||||
s.runningState = INITIALIZED;
|
s.runningState = INITIALIZED;
|
||||||
}
|
}
|
||||||
@ -315,10 +313,7 @@ final class Decode {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
s.runningState = CLOSED;
|
s.runningState = CLOSED;
|
||||||
if (s.input != null) {
|
Utils.closeInput(s);
|
||||||
Utils.closeInput(s.input);
|
|
||||||
s.input = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
package org.brotli.dec;
|
package org.brotli.dec;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.nio.Buffer;
|
import java.nio.Buffer;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@ -67,16 +66,19 @@ final class Utils {
|
|||||||
System.arraycopy(bytes, start, bytes, target, end - start);
|
System.arraycopy(bytes, start, bytes, target, end - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int readInput(InputStream src, byte[] dst, int offset, int length) {
|
static int readInput(State s, byte[] dst, int offset, int length) {
|
||||||
try {
|
try {
|
||||||
return src.read(dst, offset, length);
|
return s.input.read(dst, offset, length);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new BrotliRuntimeException("Failed to read input", e);
|
throw new BrotliRuntimeException("Failed to read input", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void closeInput(InputStream src) throws IOException {
|
static void closeInput(State s) throws IOException {
|
||||||
src.close();
|
if (s.input != null) {
|
||||||
|
s.input.close();
|
||||||
|
s.input = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte[] toUsAsciiBytes(String src) {
|
static byte[] toUsAsciiBytes(String src) {
|
||||||
|
22
js/decode.js
22
js/decode.js
@ -193,10 +193,9 @@ let makeBrotliDecode = () => {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {!State} s
|
* @param {!State} s
|
||||||
* @param {!InputStream} input
|
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
function initState(s, input) {
|
function initState(s) {
|
||||||
if (s.runningState !== 0) {
|
if (s.runningState !== 0) {
|
||||||
throw new Error("State MUST be uninitialized");
|
throw new Error("State MUST be uninitialized");
|
||||||
}
|
}
|
||||||
@ -206,7 +205,6 @@ let makeBrotliDecode = () => {
|
|||||||
const /** @type {number} */ maxDistanceAlphabetLimit = calculateDistanceAlphabetLimit(0x7FFFFFFC, 3, 120);
|
const /** @type {number} */ maxDistanceAlphabetLimit = calculateDistanceAlphabetLimit(0x7FFFFFFC, 3, 120);
|
||||||
s.distExtraBits = new Int8Array(maxDistanceAlphabetLimit);
|
s.distExtraBits = new Int8Array(maxDistanceAlphabetLimit);
|
||||||
s.distOffset = new Int32Array(maxDistanceAlphabetLimit);
|
s.distOffset = new Int32Array(maxDistanceAlphabetLimit);
|
||||||
s.input = input;
|
|
||||||
initBitReader(s);
|
initBitReader(s);
|
||||||
s.runningState = 1;
|
s.runningState = 1;
|
||||||
}
|
}
|
||||||
@ -222,9 +220,7 @@ let makeBrotliDecode = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
s.runningState = 11;
|
s.runningState = 11;
|
||||||
if (s.input !== null) {
|
s.input = null;
|
||||||
s.input = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {!State} s
|
* @param {!State} s
|
||||||
@ -1666,7 +1662,7 @@ let makeBrotliDecode = () => {
|
|||||||
s.halfOffset = 0;
|
s.halfOffset = 0;
|
||||||
while (bytesInBuffer < 4096) {
|
while (bytesInBuffer < 4096) {
|
||||||
const /** @type {number} */ spaceLeft = 4096 - bytesInBuffer;
|
const /** @type {number} */ spaceLeft = 4096 - bytesInBuffer;
|
||||||
const /** @type {number} */ len = readInput(s.input, s.byteBuffer, bytesInBuffer, spaceLeft);
|
const /** @type {number} */ len = readInput(s, s.byteBuffer, bytesInBuffer, spaceLeft);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
s.endOfStreamReached = 1;
|
s.endOfStreamReached = 1;
|
||||||
s.tailBytes = bytesInBuffer;
|
s.tailBytes = bytesInBuffer;
|
||||||
@ -1820,7 +1816,7 @@ let makeBrotliDecode = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
const /** @type {number} */ len = readInput(s.input, data, offset, length);
|
const /** @type {number} */ len = readInput(s, data, offset, length);
|
||||||
if (len === -1) {
|
if (len === -1) {
|
||||||
throw new Error("Unexpected end of input");
|
throw new Error("Unexpected end of input");
|
||||||
}
|
}
|
||||||
@ -2151,16 +2147,17 @@ let makeBrotliDecode = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {?InputStream} src
|
* @param {!State} s
|
||||||
* @param {!Int8Array} dst
|
* @param {!Int8Array} dst
|
||||||
* @param {number} offset
|
* @param {number} offset
|
||||||
* @param {number} length
|
* @param {number} length
|
||||||
* @return {number}
|
* @return {number}
|
||||||
*/
|
*/
|
||||||
function readInput(src, dst, offset, length) {
|
function readInput(s, dst, offset, length) {
|
||||||
if (src === null) {
|
if (s.input === null) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
const /** @type {!InputStream} */ src = s.input;
|
||||||
let /** @type {number} */ end = Math.min(src.offset + length, src.data.length);
|
let /** @type {number} */ end = Math.min(src.offset + length, src.data.length);
|
||||||
let /** @type {number} */ bytesRead = end - src.offset;
|
let /** @type {number} */ bytesRead = end - src.offset;
|
||||||
dst.set(src.data.subarray(src.offset, end), offset);
|
dst.set(src.data.subarray(src.offset, end), offset);
|
||||||
@ -2192,7 +2189,8 @@ let makeBrotliDecode = () => {
|
|||||||
*/
|
*/
|
||||||
function decode(bytes, options) {
|
function decode(bytes, options) {
|
||||||
let /** @type {!State} */ s = new State();
|
let /** @type {!State} */ s = new State();
|
||||||
initState(s, new InputStream(bytes));
|
s.input = new InputStream(bytes);
|
||||||
|
initState(s);
|
||||||
if (options) {
|
if (options) {
|
||||||
let customDictionary =
|
let customDictionary =
|
||||||
/** @type {?Int8Array} */ (options["customDictionary"]);
|
/** @type {?Int8Array} */ (options["customDictionary"]);
|
||||||
|
2
js/decode.min.js
vendored
2
js/decode.min.js
vendored
File diff suppressed because one or more lines are too long
19
js/decode.ts
19
js/decode.ts
@ -136,7 +136,7 @@ function attachDictionaryChunk(s: State, data: Int8Array): void {
|
|||||||
s.cdTotalSize += data.length;
|
s.cdTotalSize += data.length;
|
||||||
s.cdChunkOffsets[s.cdNumChunks] = s.cdTotalSize;
|
s.cdChunkOffsets[s.cdNumChunks] = s.cdTotalSize;
|
||||||
}
|
}
|
||||||
function initState(s: State, input: InputStream): void {
|
function initState(s: State): void {
|
||||||
if (s.runningState !== 0) {
|
if (s.runningState !== 0) {
|
||||||
throw new Error("State MUST be uninitialized");
|
throw new Error("State MUST be uninitialized");
|
||||||
}
|
}
|
||||||
@ -146,7 +146,6 @@ function initState(s: State, input: InputStream): void {
|
|||||||
const maxDistanceAlphabetLimit: number = calculateDistanceAlphabetLimit(0x7FFFFFFC, 3, 120);
|
const maxDistanceAlphabetLimit: number = calculateDistanceAlphabetLimit(0x7FFFFFFC, 3, 120);
|
||||||
s.distExtraBits = new Int8Array(maxDistanceAlphabetLimit);
|
s.distExtraBits = new Int8Array(maxDistanceAlphabetLimit);
|
||||||
s.distOffset = new Int32Array(maxDistanceAlphabetLimit);
|
s.distOffset = new Int32Array(maxDistanceAlphabetLimit);
|
||||||
s.input = input;
|
|
||||||
initBitReader(s);
|
initBitReader(s);
|
||||||
s.runningState = 1;
|
s.runningState = 1;
|
||||||
}
|
}
|
||||||
@ -158,9 +157,7 @@ function close(s: State): void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
s.runningState = 11;
|
s.runningState = 11;
|
||||||
if (s.input !== null) {
|
s.input = null;
|
||||||
s.input = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
function decodeVarLenUnsignedByte(s: State): number {
|
function decodeVarLenUnsignedByte(s: State): number {
|
||||||
if (s.bitOffset >= 16) {
|
if (s.bitOffset >= 16) {
|
||||||
@ -1398,7 +1395,7 @@ function doReadMoreInput(s: State): void {
|
|||||||
s.halfOffset = 0;
|
s.halfOffset = 0;
|
||||||
while (bytesInBuffer < 4096) {
|
while (bytesInBuffer < 4096) {
|
||||||
const spaceLeft: number = 4096 - bytesInBuffer;
|
const spaceLeft: number = 4096 - bytesInBuffer;
|
||||||
const len: number = readInput(s.input, s.byteBuffer, bytesInBuffer, spaceLeft);
|
const len: number = readInput(s, s.byteBuffer, bytesInBuffer, spaceLeft);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
s.endOfStreamReached = 1;
|
s.endOfStreamReached = 1;
|
||||||
s.tailBytes = bytesInBuffer;
|
s.tailBytes = bytesInBuffer;
|
||||||
@ -1510,7 +1507,7 @@ function copyRawBytes(s: State, data: Int8Array, offset: number, length: number)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
const len: number = readInput(s.input, data, offset, length);
|
const len: number = readInput(s, data, offset, length);
|
||||||
if (len === -1) {
|
if (len === -1) {
|
||||||
throw new Error("Unexpected end of input");
|
throw new Error("Unexpected end of input");
|
||||||
}
|
}
|
||||||
@ -1728,10 +1725,11 @@ function valueOf(x: number): string {
|
|||||||
return x.toString();
|
return x.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
function readInput(src: InputStream|null, dst: Int8Array, offset: number, length: number): number {
|
function readInput(s: State, dst: Int8Array, offset: number, length: number): number {
|
||||||
if (src === null) {
|
if (s.input === null) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
const src: InputStream = s.input;
|
||||||
const end: number = Math.min(src.offset + length, src.data.length);
|
const end: number = Math.min(src.offset + length, src.data.length);
|
||||||
const bytesRead: number = end - src.offset;
|
const bytesRead: number = end - src.offset;
|
||||||
dst.set(src.data.subarray(src.offset, end), offset);
|
dst.set(src.data.subarray(src.offset, end), offset);
|
||||||
@ -1757,7 +1755,8 @@ type ByteBuffer = Int8Array;
|
|||||||
export function brotliDecode(
|
export function brotliDecode(
|
||||||
bytes: Int8Array, options?: BrotliDecodeOptions): Int8Array {
|
bytes: Int8Array, options?: BrotliDecodeOptions): Int8Array {
|
||||||
const s = new State();
|
const s = new State();
|
||||||
initState(s, new InputStream(bytes));
|
s.input = new InputStream(bytes);
|
||||||
|
initState(s);
|
||||||
if (options) {
|
if (options) {
|
||||||
const customDictionary: Int8Array|null = options.customDictionary;
|
const customDictionary: Int8Array|null = options.customDictionary;
|
||||||
if (customDictionary) attachDictionaryChunk(s, customDictionary);
|
if (customDictionary) attachDictionaryChunk(s, customDictionary);
|
||||||
|
@ -2240,7 +2240,7 @@ __test__ = {
|
|||||||
|
|
||||||
'file': """
|
'file': """
|
||||||
>>> try: Layout(BitStream(
|
>>> try: Layout(BitStream(
|
||||||
... open("H:/Downloads/brotli-master/tests/testdata/10x10y.compressed",'rb')
|
... open("./tests/testdata/10x10y.compressed",'rb')
|
||||||
... .read())).processStream()
|
... .read())).processStream()
|
||||||
... except NotImplementedError: pass
|
... except NotImplementedError: pass
|
||||||
addr hex binary context explanation
|
addr hex binary context explanation
|
||||||
|
Loading…
Reference in New Issue
Block a user