From da409115fb0bd78113e3f0739ee2e15d92ac80ae Mon Sep 17 00:00:00 2001 From: zyppe <210hcl@gmail.com> Date: Fri, 9 Feb 2024 18:51:09 +0800 Subject: [PATCH] Initialize for brotli --- .brotli.metadata | 1 + .gitignore | 1 + baselibs.conf | 4 + brotli.changes | 114 ++ brotli.spec | 143 ++ ...ure-decompression-consumes-all-input.patch | 74 + brotli_Verbose-CLI+Shared-Brotli.patch | 1375 +++++++++++++++++ fix-cve-2020-8927.patch | 1212 +++++++++++++++ 8 files changed, 2924 insertions(+) create mode 100644 .brotli.metadata create mode 100644 .gitignore create mode 100644 baselibs.conf create mode 100644 brotli.changes create mode 100644 brotli.spec create mode 100644 brotli_Ensure-decompression-consumes-all-input.patch create mode 100644 brotli_Verbose-CLI+Shared-Brotli.patch create mode 100644 fix-cve-2020-8927.patch diff --git a/.brotli.metadata b/.brotli.metadata new file mode 100644 index 0000000..df2ea85 --- /dev/null +++ b/.brotli.metadata @@ -0,0 +1 @@ +9da1ca42a5c375b8998260879f7b53158169cbb45815392db275a4d6f566b08e brotli-1.0.7.tar.gz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..81a81bc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +brotli-1.0.7.tar.gz diff --git a/baselibs.conf b/baselibs.conf new file mode 100644 index 0000000..07ce331 --- /dev/null +++ b/baselibs.conf @@ -0,0 +1,4 @@ +libbrotlicommon1 +libbrotlidec1 +libbrotlienc1 + diff --git a/brotli.changes b/brotli.changes new file mode 100644 index 0000000..792cedc --- /dev/null +++ b/brotli.changes @@ -0,0 +1,114 @@ +* Fri Nov 26 2021 danilo.spinella@suse.com +- Fix CVE-2020-8927, decoder: integer overflow when input chunk + is larger than 2GiB. (CVE-2020-8927, bsc#1175825) + * fix-cve-2020-8927.patch +* Sun Jan 13 2019 bjorn.lie@gmail.com +- Add brotli_Verbose-CLI+Shared-Brotli.patch: Verbose CLI + start + pulling "Shared-Brotli". + * verbose CLI output; fix gh#google/brotlie#666. + * pull `SHIFT` transforms; currently this is semantically dead + code; later it will be used by "Shared-Brotli". +- Add brotli_Ensure-decompression-consumes-all-input.patch: Ensure + decompression consumes all input. If not, it's a corrupt stream. +- Tweak spec slightly. +* Fri Dec 14 2018 jengelh@inai.de +- Avoid bashisms, install manpages without +x bit, get rid of + wrap descriptions, feed through cleaner. +* Fri Dec 14 2018 astieger@suse.com +- brotli 1.0.7: + * faster decoding on ARM + * improved precision of window size calculation in CLI +- includes changes from 1.0.6: + * fix unaligned 64-bit accesses on AArch32 + * add ASAN/MSAN unaligned read specializations + * fix JDK 8<->9 incompatibility +* Wed Jul 25 2018 bjorn.lie@gmail.com +- Add baselibs.conf, build 32bit library support. +* Tue Jul 24 2018 mpluskal@suse.com +- Use cmake macros for building and tests +* Thu Jun 28 2018 mpluskal@suse.com +- Update to version 1.0.5: + * improve q=1 compression on small files + * inverse Bazel workspace tree + * add rolling-composite-hasher for large-window mode + * add tools to download and transform static dictionary data +- Changes for version 1.0.4: + * fix unaligned access for aarch64-cross-armhf build + * fix aarch64 target detection + * allow CLI to compress with enabled "large window" feature + * add NPOSTFIX / NDIRECT encoder parameters + * automatic NDIRECT/NPOSTFIX tuning (better compression) + * fix "memory leak" in python tests + * fix bug in durchschlag + * fix source file lists (add params.h) + * fix Bazel/MSVC compilator options + * fix "fall though" warnings +* Wed May 2 2018 bjorn.lie@gmail.com +- Add missing libbrotlicommon%%%%{sover} and libbrotlidec%%%%{sover} + Requires to devel subpackage. +* Mon Mar 5 2018 jengelh@inai.de +- Update to new upstream release 1.0.3 + * New "Large Window Brotli" feature + * New dictionary generator +* Wed Jan 3 2018 jengelh@inai.de +- Merge devel subpackages as libbrotli-devel +* Sat Dec 30 2017 jengelh@inai.de +- Avoid shipping duplicate files. + Avoid shipping README.md, this just contains the description - + and build instructions. +- Drop duplicate Requires on -devel. +* Wed Dec 20 2017 pgajdos@suse.com +- build for SLE_12 and SLE_12_SP1 +* Thu Nov 30 2017 buschmann23@opensuse.org +- update to Brotli 1.0.2 + + Major chnages + * added Autotools build files + * switched shared library version to libtool scheme + + Minor changes + * BrotliDictionary members are not const now + * ZopfliNode distance could be up to 128MiB + * fixed API documentation typos + * total_out is always set by decoder + * fixed BROTLI_ENSURE_CAPACITY macro; no-op in preprocessed output + + Other changes + * fixed scripts for oss-fuzz, test them with Travis + * made Bazel JNI tests less messy + * fixed linter warnings in JS decoder + * fixed permissions of various files + * added Bazel build to Appveyor matrix + * added Sieve dictionary generator +* Tue Oct 24 2017 buschmann23@opensuse.org +- update to Brotli 1.0.1 + + updated README.md + + fixed parallel exeuction of CMake "compatibility" tests +- update to Brotli 1.0.0 + + new CLI; bro -> brotli; + man page + + remove "custom dictionary" support + + add ability to side-load brotli RFC dictionary + + add decoder API to avoid ringbuffer reallocation + + PY streaming decompression support + + PY wrapper accepts memview +- spec file changes + + improve descriptions + + add man pages +* Wed Sep 20 2017 buschmann23@opensuse.org +- spec file changes + + improve package description +* Fri Jun 23 2017 buschmann23@opensuse.org +- update to Brotli 0.6.0 + + better compression on 1MiB+ files + + update "common" API to make dictionary fetching more flexible + + fix decoder bug #502 + + faster compression on mid-low quality levels + + fix encoder q10-11 slowdown after long copy #468 + + introduce Brotli*TakeOutput API +- now build shared libraries and development files in the following + new packages: + + libbrotlicommon0_6_0 + + libbrotlicommon-devel + + libbrotlidec0_6_0 + + libbrotlidec-devel + + libbrotlienc0_6_0 + + libbrtolienc-devel +* Fri Mar 24 2017 buschmann23@opensuse.org +- initial package diff --git a/brotli.spec b/brotli.spec new file mode 100644 index 0000000..e4dc279 --- /dev/null +++ b/brotli.spec @@ -0,0 +1,143 @@ +# +# spec file for package brotli +# +# Copyright (c) 2022-2023 ZhuningOS +# +# + + +%define sover 1 +Name: brotli +Version: 1.0.7 +Release: 3.3.1 +Summary: Lossless Compression Algorithm +License: MIT +Group: Productivity/Archiving/Compression +URL: https://github.com/google/brotli +Source: %url/archive/v%version.tar.gz#/%name-%version.tar.gz +Source99: baselibs.conf +Patch: brotli_Verbose-CLI+Shared-Brotli.patch +Patch1: brotli_Ensure-decompression-consumes-all-input.patch +# PATCH-FIX-UPSTREAM fix-cve-2020-8927.patch bsc#1175825 +Patch2: fix-cve-2020-8927.patch +BuildRequires: cmake >= 2.8.6 +BuildRequires: gcc-c++ +BuildRequires: gzip +BuildRequires: pkg-config + +%description +This package contains the brotli command line utility to compress and +decompress data with the brotli compression algorithm. + +Brotli is a generic-purpose lossless compression algorithm that +compresses data using a combination of a modern variant of the LZ77 +algorithm, Huffman coding and 2nd order context modeling, with a +compression ratio comparable to the best currently available +general-purpose compression methods. It is similar in speed with +deflate but offers more dense compression. + +The specification of the Brotli Compressed Data Format is defined in +RFC 7932. + +%package -n libbrotlicommon%sover +Summary: Common Library for Brotli Compression +Group: System/Libraries + +%description -n libbrotlicommon%sover +Common library for the Brotli general purpose lossless data +compression algorithm. + +%package -n libbrotlidec%sover +Summary: Library for Brotli Decompression +Group: System/Libraries + +%description -n libbrotlidec%sover +Decompression library for the Brotli general purpose lossless data +compression algorithm. + +The specification of the Brotli Compressed Data Format is defined in +RFC 7932. + +%package -n libbrotlienc%sover +Summary: Library for Brotli Compression +Group: System/Libraries + +%description -n libbrotlienc%sover +Compression library for the Brotli general purpose lossless data +compression algorithm. + +The specification of the Brotli Compressed Data Format is defined in +RFC 7932. + +%package -n libbrotli-devel +Summary: Development and Header Files for Brotli Compression +Group: Development/Libraries/C and C++ +Requires: libbrotlicommon%sover = %version-%release +Requires: libbrotlidec%sover = %version-%release +Requires: libbrotlienc%sover = %version-%release +Provides: libbrotlicommon-devel = %version-%release +Provides: libbrotlidec-devel = %version-%release +Provides: libbrotlienc-devel = %version-%release +Obsoletes: libbrotlicommon-devel < %version-%release +Obsoletes: libbrotlidec-devel < %version-%release +Obsoletes: libbrotlienc-devel < %version-%release + +%description -n libbrotli-devel +Development and headers files for (de)compressing data using the +Brotli general purpose lossless compression algorithm. + +The specification of the Brotli Compressed Data Format is defined in +RFC 7932. + +%prep +%autosetup -p1 + +%build +%cmake +%make_jobs + +%install +%cmake_install +rm %buildroot/%_libdir/libbrotli*-static.a +mkdir -p "%buildroot/%_mandir/man1" "%buildroot/%_mandir/man3" +install -pm0644 docs/*.1 "%buildroot/%_mandir/man1/" +install -pm0644 docs/*.3 "%buildroot/%_mandir/man3/" + +%check +%ctest + +%post -n libbrotlicommon%sover -p /sbin/ldconfig +%postun -n libbrotlicommon%sover -p /sbin/ldconfig +%post -n libbrotlidec%sover -p /sbin/ldconfig +%postun -n libbrotlidec%sover -p /sbin/ldconfig +%post -n libbrotlienc%sover -p /sbin/ldconfig +%postun -n libbrotlienc%sover -p /sbin/ldconfig + +%files +%defattr(-,root,root) +%license LICENSE +%_bindir/brotli +%_mandir/man1/brotli.1* + +%files -n libbrotlicommon%sover +%defattr(-,root,root) +%_libdir/libbrotlicommon.so.* + +%files -n libbrotlidec%sover +%defattr(-,root,root) +%_libdir/libbrotlidec.so.* + +%files -n libbrotlienc%sover +%defattr(-,root,root) +%_libdir/libbrotlienc.so.* + +%files -n libbrotli-devel +%defattr(-,root,root) +%_includedir/brotli/ +%_libdir/libbrotlicommon.so +%_libdir/libbrotlidec.so +%_libdir/libbrotlienc.so +%_libdir/pkgconfig/*.pc +%_mandir/man3/*.3* + +%changelog diff --git a/brotli_Ensure-decompression-consumes-all-input.patch b/brotli_Ensure-decompression-consumes-all-input.patch new file mode 100644 index 0000000..d56ce93 --- /dev/null +++ b/brotli_Ensure-decompression-consumes-all-input.patch @@ -0,0 +1,74 @@ +From 5805f99a533a8f8118699c0100d8c102f3605f65 Mon Sep 17 00:00:00 2001 +From: Justin Ridgewell +Date: Mon, 12 Nov 2018 04:36:00 -0500 +Subject: [PATCH] Ensure decompression consumes all input (#730) + +* Ensure decompression consumes all input + +If not, it's a corrupt stream. + +* Use byte strings +--- + python/_brotli.cc | 4 ++-- + python/tests/decompress_test.py | 4 ++++ + python/tests/decompressor_test.py | 9 +++++++++ + 3 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/python/_brotli.cc b/python/_brotli.cc +index a6f925ef..5e1828e9 100644 +--- a/python/_brotli.cc ++++ b/python/_brotli.cc +@@ -414,7 +414,7 @@ static BROTLI_BOOL decompress_stream(BrotliDecoderState* dec, + (*output).insert((*output).end(), buffer, buffer + buffer_length); + } + } +- ok = result != BROTLI_DECODER_RESULT_ERROR; ++ ok = result != BROTLI_DECODER_RESULT_ERROR && !available_in; + + Py_END_ALLOW_THREADS + return ok; +@@ -672,7 +672,7 @@ static PyObject* brotli_decompress(PyObject *self, PyObject *args, PyObject *key + if (available_out != 0) + output.insert(output.end(), next_out, next_out + available_out); + } +- ok = result == BROTLI_DECODER_RESULT_SUCCESS; ++ ok = result == BROTLI_DECODER_RESULT_SUCCESS && !available_in; + BrotliDecoderDestroyInstance(state); + + Py_END_ALLOW_THREADS +diff --git a/python/tests/decompress_test.py b/python/tests/decompress_test.py +index 7a9e9e30..814e5633 100644 +--- a/python/tests/decompress_test.py ++++ b/python/tests/decompress_test.py +@@ -31,6 +31,10 @@ def _test_decompress(self, test_data): + self._decompress(test_data) + self._check_decompression(test_data) + ++ def test_garbage_appended(self): ++ with self.assertRaises(brotli.error): ++ brotli.decompress(brotli.compress(b'a') + b'a') ++ + + _test_utils.generate_test_methods(TestDecompress, for_decompression=True) + +diff --git a/python/tests/decompressor_test.py b/python/tests/decompressor_test.py +index 99667bcd..05918ada 100644 +--- a/python/tests/decompressor_test.py ++++ b/python/tests/decompressor_test.py +@@ -43,6 +43,15 @@ def _test_decompress(self, test_data): + self._decompress(test_data) + self._check_decompression(test_data) + ++ def test_garbage_appended(self): ++ with self.assertRaises(brotli.error): ++ self.decompressor.process(brotli.compress(b'a') + b'a') ++ ++ def test_already_finished(self): ++ self.decompressor.process(brotli.compress(b'a')) ++ with self.assertRaises(brotli.error): ++ self.decompressor.process(b'a') ++ + + _test_utils.generate_test_methods(TestDecompressor, for_decompression=True) + + diff --git a/brotli_Verbose-CLI+Shared-Brotli.patch b/brotli_Verbose-CLI+Shared-Brotli.patch new file mode 100644 index 0000000..f2d77fa --- /dev/null +++ b/brotli_Verbose-CLI+Shared-Brotli.patch @@ -0,0 +1,1375 @@ +From d0ffe60b87aa5ec302fcb031c8ebf726c1a1692a Mon Sep 17 00:00:00 2001 +From: Eugene Kliuchnikov +Date: Wed, 24 Oct 2018 16:06:09 +0200 +Subject: [PATCH] Verbose CLI + start pulling "Shared-Brotli" (#722) + +* Verbose CLI + start pulling "Shared-Brotli" + + * vesbose CLI output; fix #666 + * pull `SHIFT` transforms; currently this is semantically dead code; + later it will be used by "Shared-Brotli" +--- + c/common/transform.c | 56 +++ + c/common/transform.h | 5 + + c/enc/backward_references.h | 6 +- + c/enc/backward_references_hq.c | 11 +- + c/enc/backward_references_hq.h | 10 +- + c/enc/backward_references_inc.h | 6 +- + c/enc/encode.c | 2 - + c/enc/encoder_dict.c | 1 - + c/tools/brotli.c | 54 ++- + java/org/brotli/dec/BrotliInputStream.java | 12 +- + java/org/brotli/dec/Decode.java | 63 ++- + java/org/brotli/dec/SynthTest.java | 513 ++++++++++++++++++++- + java/org/brotli/dec/Transform.java | 183 ++++++-- + java/org/brotli/dec/TransformTest.java | 14 +- + 14 files changed, 848 insertions(+), 88 deletions(-) + +diff --git a/c/common/transform.c b/c/common/transform.c +index 426e635f..c182053d 100755 +--- a/c/common/transform.c ++++ b/c/common/transform.c +@@ -166,6 +166,7 @@ static BrotliTransforms kBrotliTransforms = { + kPrefixSuffixMap, + sizeof(kTransformsData) / (3 * sizeof(kTransformsData[0])), + kTransformsData, ++ NULL, /* no extra parameters */ + {0, 12, 27, 23, 42, 63, 56, 48, 59, 64} + }; + +@@ -190,6 +191,48 @@ static int ToUpperCase(uint8_t* p) { + return 3; + } + ++static int Shift(uint8_t* word, int word_len, uint16_t parameter) { ++ /* Limited sign extension: scalar < (1 << 24). */ ++ uint32_t scalar = ++ (parameter & 0x7FFFu) + (0x1000000u - (parameter & 0x8000u)); ++ if (word[0] < 0x80) { ++ /* 1-byte rune / 0sssssss / 7 bit scalar (ASCII). */ ++ scalar += (uint32_t)word[0]; ++ word[0] = (uint8_t)(scalar & 0x7Fu); ++ return 1; ++ } else if (word[0] < 0xC0) { ++ /* Continuation / 10AAAAAA. */ ++ return 1; ++ } else if (word[0] < 0xE0) { ++ /* 2-byte rune / 110sssss AAssssss / 11 bit scalar. */ ++ if (word_len < 2) return 1; ++ scalar += (uint32_t)((word[1] & 0x3Fu) | ((word[0] & 0x1Fu) << 6u)); ++ word[0] = (uint8_t)(0xC0 | ((scalar >> 6u) & 0x1F)); ++ word[1] = (uint8_t)((word[1] & 0xC0) | (scalar & 0x3F)); ++ return 2; ++ } else if (word[0] < 0xF0) { ++ /* 3-byte rune / 1110ssss AAssssss BBssssss / 16 bit scalar. */ ++ if (word_len < 3) return word_len; ++ scalar += (uint32_t)((word[2] & 0x3Fu) | ((word[1] & 0x3Fu) << 6u) | ++ ((word[0] & 0x0Fu) << 12u)); ++ word[0] = (uint8_t)(0xE0 | ((scalar >> 12u) & 0x0F)); ++ word[1] = (uint8_t)((word[1] & 0xC0) | ((scalar >> 6u) & 0x3F)); ++ word[2] = (uint8_t)((word[2] & 0xC0) | (scalar & 0x3F)); ++ return 3; ++ } else if (word[0] < 0xF8) { ++ /* 4-byte rune / 11110sss AAssssss BBssssss CCssssss / 21 bit scalar. */ ++ if (word_len < 4) return word_len; ++ scalar += (uint32_t)((word[3] & 0x3Fu) | ((word[2] & 0x3Fu) << 6u) | ++ ((word[1] & 0x3Fu) << 12u) | ((word[0] & 0x07u) << 18u)); ++ word[0] = (uint8_t)(0xF0 | ((scalar >> 18u) & 0x07)); ++ word[1] = (uint8_t)((word[1] & 0xC0) | ((scalar >> 12u) & 0x3F)); ++ word[2] = (uint8_t)((word[2] & 0xC0) | ((scalar >> 6u) & 0x3F)); ++ word[3] = (uint8_t)((word[3] & 0xC0) | (scalar & 0x3F)); ++ return 4; ++ } ++ return 1; ++} ++ + int BrotliTransformDictionaryWord(uint8_t* dst, const uint8_t* word, int len, + const BrotliTransforms* transforms, int transform_idx) { + int idx = 0; +@@ -221,6 +264,19 @@ int BrotliTransformDictionaryWord(uint8_t* dst, const uint8_t* word, int len, + uppercase += step; + len -= step; + } ++ } else if (t == BROTLI_TRANSFORM_SHIFT_FIRST) { ++ uint16_t param = (uint16_t)(transforms->params[transform_idx * 2] ++ + (transforms->params[transform_idx * 2 + 1] << 8u)); ++ Shift(&dst[idx - len], len, param); ++ } else if (t == BROTLI_TRANSFORM_SHIFT_ALL) { ++ uint16_t param = (uint16_t)(transforms->params[transform_idx * 2] ++ + (transforms->params[transform_idx * 2 + 1] << 8u)); ++ uint8_t* shift = &dst[idx - len]; ++ while (len > 0) { ++ int step = Shift(shift, len, param); ++ shift += step; ++ len -= step; ++ } + } + } + { +diff --git a/c/common/transform.h b/c/common/transform.h +index 456c12db..b6f86cc7 100755 +--- a/c/common/transform.h ++++ b/c/common/transform.h +@@ -37,6 +37,8 @@ enum BrotliWordTransformType { + BROTLI_TRANSFORM_OMIT_FIRST_7 = 18, + BROTLI_TRANSFORM_OMIT_FIRST_8 = 19, + BROTLI_TRANSFORM_OMIT_FIRST_9 = 20, ++ BROTLI_TRANSFORM_SHIFT_FIRST = 21, ++ BROTLI_TRANSFORM_SHIFT_ALL = 22, + BROTLI_NUM_TRANSFORM_TYPES /* Counts transforms, not a transform itself. */ + }; + +@@ -50,6 +52,9 @@ typedef struct BrotliTransforms { + uint32_t num_transforms; + /* Each entry is a [prefix_id, transform, suffix_id] triplet. */ + const uint8_t* transforms; ++ /* Shift for BROTLI_TRANSFORM_SHIFT_FIRST and BROTLI_TRANSFORM_SHIFT_ALL, ++ must be NULL if and only if no such transforms are present. */ ++ const uint8_t* params; + /* Indices of transforms like ["", BROTLI_TRANSFORM_OMIT_LAST_#, ""]. + 0-th element corresponds to ["", BROTLI_TRANSFORM_IDENTITY, ""]. + -1, if cut-off transform does not exist. */ +diff --git a/c/enc/backward_references.h b/c/enc/backward_references.h +index 3a414664..f82a80da 100644 +--- a/c/enc/backward_references.h ++++ b/c/enc/backward_references.h +@@ -25,9 +25,9 @@ extern "C" { + initially the total amount of commands output by previous + CreateBackwardReferences calls, and must be incremented by the amount written + by this call. */ +-BROTLI_INTERNAL void BrotliCreateBackwardReferences( +- size_t num_bytes, size_t position, const uint8_t* ringbuffer, +- size_t ringbuffer_mask, const BrotliEncoderParams* params, ++BROTLI_INTERNAL void BrotliCreateBackwardReferences(size_t num_bytes, ++ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, ++ const BrotliEncoderParams* params, + HasherHandle hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals); + +diff --git a/c/enc/backward_references_hq.c b/c/enc/backward_references_hq.c +index 96b0e708..5737f752 100644 +--- a/c/enc/backward_references_hq.c ++++ b/c/enc/backward_references_hq.c +@@ -419,8 +419,8 @@ static size_t UpdateNodes( + size_t k; + size_t gap = 0; + +- EvaluateNode(block_start, pos, max_backward_limit, gap, starting_dist_cache, +- model, queue, nodes); ++ EvaluateNode(block_start, pos, max_backward_limit, gap, ++ starting_dist_cache, model, queue, nodes); + + { + const PosData* posdata = StartPosQueueAt(queue, 0); +@@ -587,9 +587,10 @@ void BrotliZopfliCreateCommands(const size_t num_bytes, + { + size_t distance = ZopfliNodeCopyDistance(next); + size_t len_code = ZopfliNodeLengthCode(next); +- size_t max_distance = +- BROTLI_MIN(size_t, block_start + pos, max_backward_limit); +- BROTLI_BOOL is_dictionary = TO_BROTLI_BOOL(distance > max_distance + gap); ++ size_t max_distance = BROTLI_MIN(size_t, ++ block_start + pos, max_backward_limit); ++ BROTLI_BOOL is_dictionary = ++ TO_BROTLI_BOOL(distance > max_distance + gap); + size_t dist_code = ZopfliNodeDistanceCode(next); + InitCommand(&commands[i], ¶ms->dist, insert_length, + copy_length, (int)len_code - (int)copy_length, dist_code); +diff --git a/c/enc/backward_references_hq.h b/c/enc/backward_references_hq.h +index 1e4275d4..fb1ff3fa 100644 +--- a/c/enc/backward_references_hq.h ++++ b/c/enc/backward_references_hq.h +@@ -23,14 +23,16 @@ extern "C" { + #endif + + BROTLI_INTERNAL void BrotliCreateZopfliBackwardReferences(MemoryManager* m, +- size_t num_bytes, size_t position, const uint8_t* ringbuffer, +- size_t ringbuffer_mask, const BrotliEncoderParams* params, ++ size_t num_bytes, ++ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, ++ const BrotliEncoderParams* params, + HasherHandle hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals); + + BROTLI_INTERNAL void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, +- size_t num_bytes, size_t position, const uint8_t* ringbuffer, +- size_t ringbuffer_mask, const BrotliEncoderParams* params, ++ size_t num_bytes, ++ size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, ++ const BrotliEncoderParams* params, + HasherHandle hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals); + +diff --git a/c/enc/backward_references_inc.h b/c/enc/backward_references_inc.h +index c18cdb00..e29daf33 100644 +--- a/c/enc/backward_references_inc.h ++++ b/c/enc/backward_references_inc.h +@@ -60,7 +60,8 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)( + FN(FindLongestMatch)(hasher, + ¶ms->dictionary, + ringbuffer, ringbuffer_mask, dist_cache, position + 1, max_length, +- max_distance, gap, params->dist.max_distance, &sr2); ++ max_distance, gap, params->dist.max_distance, ++ &sr2); + if (sr2.score >= sr.score + cost_diff_lazy) { + /* Ok, let's just write one byte for now and start a match from the + next byte. */ +@@ -76,7 +77,8 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)( + } + apply_random_heuristics = + position + 2 * sr.len + random_heuristics_window_size; +- max_distance = BROTLI_MIN(size_t, position, max_backward_limit); ++ max_distance = BROTLI_MIN(size_t, ++ position, max_backward_limit); + { + /* The first 16 codes are special short-codes, + and the minimum offset is 1. */ +diff --git a/c/enc/encode.c b/c/enc/encode.c +index 141e70aa..c82f2d3f 100644 +--- a/c/enc/encode.c ++++ b/c/enc/encode.c +@@ -114,8 +114,6 @@ typedef struct BrotliEncoderStateStruct { + BROTLI_BOOL is_initialized_; + } BrotliEncoderStateStruct; + +-static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s); +- + static size_t InputBlockSize(BrotliEncoderState* s) { + return (size_t)1 << s->params.lgblock; + } +diff --git a/c/enc/encoder_dict.c b/c/enc/encoder_dict.c +index 8b2f6ad4..e58ca670 100755 +--- a/c/enc/encoder_dict.c ++++ b/c/enc/encoder_dict.c +@@ -24,7 +24,6 @@ void BrotliInitEncoderDictionary(BrotliEncoderDictionary* dict) { + + dict->cutoffTransformsCount = kCutoffTransformsCount; + dict->cutoffTransforms = kCutoffTransforms; +- + } + + #if defined(__cplusplus) || defined(c_plusplus) +diff --git a/c/tools/brotli.c b/c/tools/brotli.c +index ce05b641..838539ad 100644 +--- a/c/tools/brotli.c ++++ b/c/tools/brotli.c +@@ -86,10 +86,10 @@ typedef struct { + /* Parameters */ + int quality; + int lgwin; ++ int verbosity; + BROTLI_BOOL force_overwrite; + BROTLI_BOOL junk_source; + BROTLI_BOOL copy_stat; +- BROTLI_BOOL verbose; + BROTLI_BOOL write_to_stdout; + BROTLI_BOOL test_integrity; + BROTLI_BOOL decompress; +@@ -121,6 +121,12 @@ typedef struct { + const uint8_t* next_in; + size_t available_out; + uint8_t* next_out; ++ ++ /* Reporting */ ++ /* size_t would be large enough, ++ until 4GiB+ files are compressed / decompressed on 32-bit CPUs. */ ++ size_t total_in; ++ size_t total_out; + } Context; + + /* Parse up to 5 decimal digits. */ +@@ -279,11 +285,11 @@ static Command ParseParams(Context* params) { + command = COMMAND_TEST_INTEGRITY; + continue; + } else if (c == 'v') { +- if (params->verbose) { ++ if (params->verbosity > 0) { + fprintf(stderr, "argument --verbose / -v already set\n"); + return COMMAND_INVALID; + } +- params->verbose = BROTLI_TRUE; ++ params->verbosity = 1; + continue; + } else if (c == 'V') { + /* Don't parse further. */ +@@ -415,11 +421,11 @@ static Command ParseParams(Context* params) { + command_set = BROTLI_TRUE; + command = COMMAND_TEST_INTEGRITY; + } else if (strcmp("verbose", arg) == 0) { +- if (params->verbose) { ++ if (params->verbosity > 0) { + fprintf(stderr, "argument --verbose / -v already set\n"); + return COMMAND_INVALID; + } +- params->verbose = BROTLI_TRUE; ++ params->verbosity = 1; + } else if (strcmp("version", arg) == 0) { + /* Don't parse further. */ + return COMMAND_VERSION; +@@ -787,6 +793,8 @@ static void InitializeBuffers(Context* context) { + context->next_in = NULL; + context->available_out = kFileBufferSize; + context->next_out = context->output; ++ context->total_in = 0; ++ context->total_out = 0; + } + + static BROTLI_BOOL HasMoreInput(Context* context) { +@@ -796,6 +804,7 @@ static BROTLI_BOOL HasMoreInput(Context* context) { + static BROTLI_BOOL ProvideInput(Context* context) { + context->available_in = + fread(context->input, 1, kFileBufferSize, context->fin); ++ context->total_in += context->available_in; + context->next_in = context->input; + if (ferror(context->fin)) { + fprintf(stderr, "failed to read input [%s]: %s\n", +@@ -808,6 +817,7 @@ static BROTLI_BOOL ProvideInput(Context* context) { + /* Internal: should be used only in Provide-/Flush-Output. */ + static BROTLI_BOOL WriteOutput(Context* context) { + size_t out_size = (size_t)(context->next_out - context->output); ++ context->total_out += out_size; + if (out_size == 0) return BROTLI_TRUE; + if (context->test_integrity) return BROTLI_TRUE; + +@@ -833,6 +843,25 @@ static BROTLI_BOOL FlushOutput(Context* context) { + return BROTLI_TRUE; + } + ++static void PrintBytes(size_t value) { ++ if (value < 1024) { ++ fprintf(stderr, "%d B", (int)value); ++ } else if (value < 1048576) { ++ fprintf(stderr, "%0.3f KiB", (double)value / 1024.0); ++ } else if (value < 1073741824) { ++ fprintf(stderr, "%0.3f MiB", (double)value / 1048576.0); ++ } else { ++ fprintf(stderr, "%0.3f GiB", (double)value / 1073741824.0); ++ } ++} ++ ++static void PrintFileProcessingProgress(Context* context) { ++ fprintf(stderr, "[%s]: ", PrintablePath(context->current_input_path)); ++ PrintBytes(context->total_in); ++ fprintf(stderr, " -> "); ++ PrintBytes(context->total_out); ++} ++ + static BROTLI_BOOL DecompressFile(Context* context, BrotliDecoderState* s) { + BrotliDecoderResult result = BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT; + InitializeBuffers(context); +@@ -853,6 +882,11 @@ static BROTLI_BOOL DecompressFile(Context* context, BrotliDecoderState* s) { + PrintablePath(context->current_input_path)); + return BROTLI_FALSE; + } ++ if (context->verbosity > 0) { ++ fprintf(stderr, "Decompressed "); ++ PrintFileProcessingProgress(context); ++ fprintf(stderr, "\n"); ++ } + return BROTLI_TRUE; + } else { + fprintf(stderr, "corrupt input [%s]\n", +@@ -915,7 +949,13 @@ static BROTLI_BOOL CompressFile(Context* context, BrotliEncoderState* s) { + } + + if (BrotliEncoderIsFinished(s)) { +- return FlushOutput(context); ++ if (!FlushOutput(context)) return BROTLI_FALSE; ++ if (context->verbosity > 0) { ++ fprintf(stderr, "Compressed "); ++ PrintFileProcessingProgress(context); ++ fprintf(stderr, "\n"); ++ } ++ return BROTLI_TRUE; + } + } + } +@@ -979,11 +1019,11 @@ int main(int argc, char** argv) { + + context.quality = 11; + context.lgwin = -1; ++ context.verbosity = 0; + context.force_overwrite = BROTLI_FALSE; + context.junk_source = BROTLI_FALSE; + context.copy_stat = BROTLI_TRUE; + context.test_integrity = BROTLI_FALSE; +- context.verbose = BROTLI_FALSE; + context.write_to_stdout = BROTLI_FALSE; + context.decompress = BROTLI_FALSE; + context.large_window = BROTLI_FALSE; +diff --git a/java/org/brotli/dec/BrotliInputStream.java b/java/org/brotli/dec/BrotliInputStream.java +index a27e9284..5cc2e284 100644 +--- a/java/org/brotli/dec/BrotliInputStream.java ++++ b/java/org/brotli/dec/BrotliInputStream.java +@@ -85,7 +85,17 @@ public BrotliInputStream(InputStream source, int byteReadBufferSize) throws IOEx + } + + public void setEager(boolean eager) { +- state.isEager = eager ? 1 : 0; ++ boolean isEager = (state.isEager != 0); ++ if (eager == isEager) { ++ /* Shortcut for no-op change. */ ++ return; ++ } ++ if (eager) { ++ Decode.setEager(state); ++ } else { ++ /* Once decoder is "eager", there is no way back. */ ++ throw new IllegalStateException("Brotli decoder has been already switched to eager mode"); ++ } + } + + /** +diff --git a/java/org/brotli/dec/Decode.java b/java/org/brotli/dec/Decode.java +index 9e3d43b0..60bf9c61 100644 +--- a/java/org/brotli/dec/Decode.java ++++ b/java/org/brotli/dec/Decode.java +@@ -18,18 +18,19 @@ + // RunningState + //---------------------------------------------------------------------------- + private static final int UNINITIALIZED = 0; +- private static final int BLOCK_START = 1; +- private static final int COMPRESSED_BLOCK_START = 2; +- private static final int MAIN_LOOP = 3; +- private static final int READ_METADATA = 4; +- private static final int COPY_UNCOMPRESSED = 5; +- private static final int INSERT_LOOP = 6; +- private static final int COPY_LOOP = 7; +- private static final int TRANSFORM = 8; +- private static final int FINISHED = 9; +- private static final int CLOSED = 10; +- private static final int INIT_WRITE = 11; +- private static final int WRITE = 12; ++ private static final int INITIALIZED = 1; ++ private static final int BLOCK_START = 2; ++ private static final int COMPRESSED_BLOCK_START = 3; ++ private static final int MAIN_LOOP = 4; ++ private static final int READ_METADATA = 5; ++ private static final int COPY_UNCOMPRESSED = 6; ++ private static final int INSERT_LOOP = 7; ++ private static final int COPY_LOOP = 8; ++ private static final int TRANSFORM = 9; ++ private static final int FINISHED = 10; ++ private static final int CLOSED = 11; ++ private static final int INIT_WRITE = 12; ++ private static final int WRITE = 13; + + private static final int DEFAULT_CODE_LENGTH = 8; + private static final int CODE_LENGTH_REPEAT_CODE = 16; +@@ -139,6 +140,20 @@ private static int decodeWindowBits(State s) { + return 17; + } + ++ /** ++ * Switch decoder to "eager" mode. ++ * ++ * In "eager" mode decoder returns as soon as there is enough data to fill output buffer. ++ * ++ * @param s initialized state, before any read is performed. ++ */ ++ static void setEager(State s) { ++ if (s.runningState != INITIALIZED) { ++ throw new IllegalStateException("State MUST be freshly initialized"); ++ } ++ s.isEager = 1; ++ } ++ + /** + * Associate input with decoder state. + * +@@ -152,13 +167,7 @@ static void initState(State s, InputStream input) { + s.blockTrees = new int[6 * HUFFMAN_TABLE_SIZE]; + s.input = input; + BitReader.initBitReader(s); +- int windowBits = decodeWindowBits(s); +- if (windowBits == 9) { /* Reserved case for future expansion. */ +- throw new BrotliRuntimeException("Invalid 'windowBits' code"); +- } +- s.maxRingBufferSize = 1 << windowBits; +- s.maxBackwardDistance = s.maxRingBufferSize - 16; +- s.runningState = BLOCK_START; ++ s.runningState = INITIALIZED; + } + + static void close(State s) throws IOException { +@@ -727,6 +736,16 @@ static void decompress(State s) { + if (s.runningState == CLOSED) { + throw new IllegalStateException("Can't decompress after close"); + } ++ if (s.runningState == INITIALIZED) { ++ int windowBits = decodeWindowBits(s); ++ if (windowBits == 9) { /* Reserved case for future expansion. */ ++ throw new BrotliRuntimeException("Invalid 'windowBits' code"); ++ } ++ s.maxRingBufferSize = 1 << windowBits; ++ s.maxBackwardDistance = s.maxRingBufferSize - 16; ++ s.runningState = BLOCK_START; ++ } ++ + int fence = calculateFence(s); + int ringBufferMask = s.ringBufferSize - 1; + byte[] ringBuffer = s.ringBuffer; +@@ -935,9 +954,9 @@ static void decompress(State s) { + int wordIdx = wordId & mask; + int transformIdx = wordId >>> shift; + offset += wordIdx * s.copyLength; +- if (transformIdx < Transform.NUM_TRANSFORMS) { +- int len = Transform.transformDictionaryWord(ringBuffer, s.pos, +- Dictionary.getData(), offset, s.copyLength, transformIdx); ++ if (transformIdx < Transform.NUM_RFC_TRANSFORMS) { ++ int len = Transform.transformDictionaryWord(ringBuffer, s.pos, Dictionary.getData(), ++ offset, s.copyLength, Transform.RFC_TRANSFORMS, transformIdx); + s.pos += len; + s.metaBlockLength -= len; + if (s.pos >= fence) { +diff --git a/java/org/brotli/dec/SynthTest.java b/java/org/brotli/dec/SynthTest.java +index c95a3c90..de91c377 100644 +--- a/java/org/brotli/dec/SynthTest.java ++++ b/java/org/brotli/dec/SynthTest.java +@@ -64,6 +64,474 @@ private void checkSynth(byte[] compressed, boolean expectSuccess, + + /* GENERATED CODE START */ + ++ @Test ++ public void testAllTransforms10() { ++ byte[] compressed = { ++ (byte) 0x1b, (byte) 0xfc, (byte) 0x05, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80, ++ (byte) 0xe3, (byte) 0xb4, (byte) 0x0d, (byte) 0x00, (byte) 0x00, (byte) 0x07, (byte) 0x5b, ++ (byte) 0x26, (byte) 0x31, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0xe0, (byte) 0x4e, ++ (byte) 0x1b, (byte) 0x13, (byte) 0x7c, (byte) 0x84, (byte) 0x26, (byte) 0xf8, (byte) 0x04, ++ (byte) 0x10, (byte) 0x4c, (byte) 0xf0, (byte) 0x89, (byte) 0x38, (byte) 0x30, (byte) 0xc1, ++ (byte) 0x27, (byte) 0x4e, (byte) 0xc1, (byte) 0x04, (byte) 0x9f, (byte) 0x64, (byte) 0x06, ++ (byte) 0x26, (byte) 0xf8, (byte) 0x24, (byte) 0x3f, (byte) 0x34, (byte) 0xc1, (byte) 0x27, ++ (byte) 0x7d, (byte) 0x82, (byte) 0x09, (byte) 0x3e, (byte) 0xe9, (byte) 0x16, (byte) 0x4d, ++ (byte) 0xf0, (byte) 0xc9, (byte) 0xd2, (byte) 0xc0, (byte) 0x04, (byte) 0x9f, (byte) 0x0c, ++ (byte) 0x8f, (byte) 0x4c, (byte) 0xf0, (byte) 0xc9, (byte) 0x06, (byte) 0xd1, (byte) 0x04, ++ (byte) 0x9f, (byte) 0x6c, (byte) 0x92, (byte) 0x4d, (byte) 0xf0, (byte) 0xc9, (byte) 0x39, ++ (byte) 0xc1, (byte) 0x04, (byte) 0x9f, (byte) 0xdc, (byte) 0x94, (byte) 0x4c, (byte) 0xf0, ++ (byte) 0xc9, (byte) 0x69, (byte) 0xd1, (byte) 0x04, (byte) 0x9f, (byte) 0x3c, (byte) 0x98, ++ (byte) 0x4d, (byte) 0xf0, (byte) 0x29, (byte) 0x9c, (byte) 0x81, (byte) 0x09, (byte) 0x3e, ++ (byte) 0x45, (byte) 0x37, (byte) 0x31, (byte) 0xc1, (byte) 0xa7, (byte) 0x60, (byte) 0x47, ++ (byte) 0x26, (byte) 0xf8, (byte) 0x14, (byte) 0xfa, (byte) 0xcc, (byte) 0x04, (byte) 0x9f, ++ (byte) 0xc2, (byte) 0x20, (byte) 0x9a, (byte) 0xe0, (byte) 0x53, (byte) 0x48, (byte) 0x54, ++ (byte) 0x13, (byte) 0x7c, (byte) 0x8a, (byte) 0x8f, (byte) 0x6c, (byte) 0x82, (byte) 0x4f, ++ (byte) 0xb1, (byte) 0xd2, (byte) 0x4d, (byte) 0xf0, (byte) 0x29, (byte) 0x67, (byte) 0x82, ++ (byte) 0x09, (byte) 0x3e, (byte) 0xe5, (byte) 0x4f, (byte) 0x31, (byte) 0xc1, (byte) 0xa7, ++ (byte) 0x7c, (byte) 0x4a, (byte) 0x26, (byte) 0xf8, (byte) 0x94, (byte) 0x57, (byte) 0xcd, ++ (byte) 0x04, (byte) 0x9f, (byte) 0x12, (byte) 0x2c, (byte) 0x9a, (byte) 0xe0, (byte) 0x53, ++ (byte) 0xba, (byte) 0x55, (byte) 0x13, (byte) 0x7c, (byte) 0xca, (byte) 0xbf, (byte) 0x6c, ++ (byte) 0x82, (byte) 0x4f, (byte) 0xb9, (byte) 0xd8, (byte) 0x4d, (byte) 0xf0, (byte) 0xa9, ++ (byte) 0x30, (byte) 0x03, (byte) 0x13, (byte) 0x7c, (byte) 0x2a, (byte) 0xd2, (byte) 0xc2, ++ (byte) 0x04, (byte) 0x9f, (byte) 0x4a, (byte) 0x36, (byte) 0x31, (byte) 0xc1, (byte) 0xa7, ++ (byte) 0xca, (byte) 0x6d, (byte) 0x4c, (byte) 0xf0, (byte) 0xa9, (byte) 0x94, (byte) 0x23, ++ (byte) 0x13, (byte) 0x7c, (byte) 0x2a, (byte) 0xeb, (byte) 0xca, (byte) 0x04, (byte) 0x9f, ++ (byte) 0xea, (byte) 0x3c, (byte) 0x33, (byte) 0xc1, (byte) 0xa7, (byte) 0xb2, (byte) 0xef, ++ (byte) 0x4c, (byte) 0xf0, (byte) 0xa9, (byte) 0xf8, (byte) 0x43, (byte) 0x13, (byte) 0x7c, ++ (byte) 0xaa, (byte) 0x00, (byte) 0xd3, (byte) 0x04, (byte) 0x9f, (byte) 0x2a, (byte) 0x42, ++ (byte) 0x35, (byte) 0xc1, (byte) 0xa7, (byte) 0xc2, (byte) 0x70, (byte) 0x4d, (byte) 0xf0, ++ (byte) 0xa9, (byte) 0x52, (byte) 0x64, (byte) 0x13, (byte) 0x7c, (byte) 0x2a, (byte) 0x1a, ++ (byte) 0xdb, (byte) 0x04, (byte) 0x9f, (byte) 0x6a, (byte) 0x48, (byte) 0x37, (byte) 0xc1, ++ (byte) 0xa7, (byte) 0x92, (byte) 0xf2, (byte) 0x4d, (byte) 0xf0, (byte) 0xa9, (byte) 0xc3, ++ (byte) 0x04, (byte) 0x13, (byte) 0x7c, (byte) 0xea, (byte) 0x32, (byte) 0xc3, (byte) 0x04, ++ (byte) 0x9f, (byte) 0x7a, (byte) 0x4e, (byte) 0x31, (byte) 0xc1, (byte) 0xa7, (byte) 0x06, ++ (byte) 0x74, (byte) 0x4c, (byte) 0xf0, (byte) 0xa9, (byte) 0x19, (byte) 0x25, (byte) 0x13, ++ (byte) 0x7c, (byte) 0x6a, (byte) 0x4d, (byte) 0xcb, (byte) 0x04, (byte) 0x9f, (byte) 0x1a, ++ (byte) 0x55, (byte) 0x33, (byte) 0xc1, (byte) 0xa7, (byte) 0x56, (byte) 0xf5, (byte) 0x4c, ++ (byte) 0xf0, (byte) 0xa9, (byte) 0x5d, (byte) 0x45, (byte) 0x13, (byte) 0x7c, (byte) 0xea, ++ (byte) 0x59, (byte) 0xd3, (byte) 0x04, (byte) 0x9f, (byte) 0xfa, (byte) 0x57, (byte) 0x35, ++ (byte) 0xc1, (byte) 0xa7, (byte) 0x66, (byte) 0x76, (byte) 0x4d, (byte) 0xf0, (byte) 0xa9, ++ (byte) 0x9f, (byte) 0x65, (byte) 0x13, (byte) 0x7c, (byte) 0x6a, (byte) 0x6f, (byte) 0xdb, ++ (byte) 0x04, (byte) 0x9f, (byte) 0x9a, (byte) 0x5d, (byte) 0x37, (byte) 0xc1, (byte) 0xa7, ++ (byte) 0x06, (byte) 0xf8, (byte) 0x4d, (byte) 0xf0, (byte) 0x69, (byte) 0x0c, (byte) 0x06, ++ (byte) 0x26, (byte) 0xf8, (byte) 0x34, (byte) 0x08, (byte) 0x07, (byte) 0x13, (byte) 0x7c, ++ (byte) 0x1a, (byte) 0x8b, (byte) 0x85, (byte) 0x09, (byte) 0x3e, (byte) 0x8d, (byte) 0xc8, ++ (byte) 0xc3, (byte) 0x04, (byte) 0x9f, (byte) 0xe6, (byte) 0x65, (byte) 0x62, (byte) 0x82, ++ (byte) 0x4f, (byte) 0xb3, (byte) 0x73, (byte) 0x31, (byte) 0xc1, (byte) 0xa7, (byte) 0x41, ++ (byte) 0xda, (byte) 0x98, (byte) 0xe0, (byte) 0xd3, (byte) 0x54, (byte) 0x7d, (byte) 0x4c, ++ (byte) 0xf0, (byte) 0x69, (byte) 0xc4, (byte) 0x46, (byte) 0x26, (byte) 0xf8, (byte) 0x34, ++ (byte) 0x72, (byte) 0x27, (byte) 0x13, (byte) 0x7c, (byte) 0x1a, (byte) 0xc5, (byte) 0x95, ++ (byte) 0x09, (byte) 0x3e, (byte) 0x8d, (byte) 0xe5, (byte) 0xcb, (byte) 0x04, (byte) 0x9f, ++ (byte) 0x06, (byte) 0x75, (byte) 0x66, (byte) 0x82, (byte) 0x4f, (byte) 0x43, (byte) 0x7b, ++ (byte) 0x33, (byte) 0xc1, (byte) 0xa7, (byte) 0x09, (byte) 0xde, (byte) 0x99, (byte) 0xe0, ++ (byte) 0xd3, (byte) 0x34, (byte) 0xff, (byte) 0x4c, (byte) 0xf0, (byte) 0x69, (byte) 0xb2, ++ (byte) 0x87, (byte) 0x26, (byte) 0xf8, (byte) 0x34, (byte) 0xe9, (byte) 0x47, (byte) 0x13, ++ (byte) 0x7c, (byte) 0x9a, (byte) 0xfb, (byte) 0xa5, (byte) 0x09, (byte) 0x3e, (byte) 0x4d, ++ (byte) 0x01, (byte) 0xd4, (byte) 0x04, (byte) 0x9f, (byte) 0x46, (byte) 0x82, (byte) 0x6a, ++ (byte) 0x82, (byte) 0x4f, (byte) 0x03, (byte) 0x82, (byte) 0x35, (byte) 0xc1, (byte) 0xa7, ++ (byte) 0x61, (byte) 0xe1, (byte) 0x9a, (byte) 0xe0, (byte) 0xd3, (byte) 0xe4, (byte) 0x80, ++ (byte) 0x4d, (byte) 0xf0, (byte) 0x69, (byte) 0x8a, (byte) 0xc8, (byte) 0x26, (byte) 0xf8, ++ (byte) 0x34, (byte) 0x52, (byte) 0x68, (byte) 0x13, (byte) 0x7c, (byte) 0x9a, (byte) 0x2f, ++ (byte) 0xb6, (byte) 0x09, (byte) 0x3e, (byte) 0x8d, (byte) 0x1b, (byte) 0xdc, (byte) 0x04, ++ (byte) 0x9f, (byte) 0x86, (byte) 0x8f, (byte) 0x6e, (byte) 0x82, (byte) 0x4f, (byte) 0xb3, ++ (byte) 0x88, (byte) 0x37, (byte) 0xc1, (byte) 0xa7, (byte) 0xd9, (byte) 0xe4, (byte) 0x9b, ++ (byte) 0xe0, (byte) 0xd3, (byte) 0x9e, (byte) 0x02, (byte) 0x4c, (byte) 0xf0, (byte) 0x69, ++ (byte) 0x6d, (byte) 0x09, (byte) 0x26, (byte) 0xf8, (byte) 0xb4, (byte) 0xc3, (byte) 0x08, ++ (byte) 0x13, (byte) 0x7c, (byte) 0x5a, (byte) 0x68, (byte) 0x86, (byte) 0x09, (byte) 0x3e, ++ (byte) 0xad, (byte) 0x37, (byte) 0xc4, (byte) 0x04, (byte) 0x9f, (byte) 0x56, (byte) 0x9d, ++ (byte) 0x62, (byte) 0x82, (byte) 0x4f, (byte) 0x9b, (byte) 0x8f, (byte) 0x31, (byte) 0xc1, ++ (byte) 0xa7, (byte) 0x2d, (byte) 0xe8, (byte) 0x98, (byte) 0xe0, (byte) 0xd3, (byte) 0x4a, ++ (byte) 0x84, (byte) 0x4c, (byte) 0xf0, (byte) 0x69, (byte) 0x3f, (byte) 0x4a, (byte) 0x26, ++ (byte) 0xf8, (byte) 0xb4, (byte) 0x2c, (byte) 0x29, (byte) 0x13, (byte) 0x7c, (byte) 0xda, ++ (byte) 0x9c, (byte) 0x96, (byte) 0x09, (byte) 0x3e, (byte) 0x2d, (byte) 0x52, (byte) 0xcc, ++ (byte) 0x04, (byte) 0x9f, (byte) 0xb6, (byte) 0xaa, (byte) 0x66, (byte) 0x82, (byte) 0x4f, ++ (byte) 0x2b, (byte) 0x96, (byte) 0x33, (byte) 0xc1, (byte) 0xa7, (byte) 0x7d, (byte) 0xeb, ++ (byte) 0x99, (byte) 0xe0, (byte) 0xd3, (byte) 0xf6, (byte) 0x05, (byte) 0x4d, (byte) 0xf0, ++ (byte) 0x69, (byte) 0x17, (byte) 0x8b, (byte) 0x26, (byte) 0xf8, (byte) 0xb4, (byte) 0x97, ++ (byte) 0x49, (byte) 0x13, (byte) 0x7c, (byte) 0xda, (byte) 0xd1, (byte) 0xa6, (byte) 0x09, ++ (byte) 0x3e, (byte) 0x2d, (byte) 0x6c, (byte) 0xd4, (byte) 0x04, (byte) 0x9f, (byte) 0xb6, ++ (byte) 0xb7, (byte) 0x6a, (byte) 0x82, (byte) 0x4f, (byte) 0xab, (byte) 0x9c, (byte) 0x35, ++ (byte) 0xc1, (byte) 0xa7, (byte) 0xc5, (byte) 0xee, (byte) 0x9a, (byte) 0xe0, (byte) 0xd3, ++ (byte) 0x9a, (byte) 0x87, (byte) 0x4d, (byte) 0xf0, (byte) 0x69, (byte) 0xe9, (byte) 0xcb ++ }; ++ checkSynth( ++ /* ++ * // The stream consists of word "time" with all possible transforms. ++ * main_header ++ * metablock_header_easy: 1533, 1 ++ * command_easy: 10, "|", 2 // = 0 << 10 + 1 + 1 ++ * command_easy: 10, "|", 1037 // = 1 << 10 + 1 + 12 ++ * command_easy: 10, "|", 2073 // = 2 << 10 + 1 + 24 ++ * command_easy: 10, "|", 3110 // = 3 << 10 + 1 + 37 ++ * command_easy: 10, "|", 4144 // = 4 << 10 + 1 + 47 ++ * command_easy: 10, "|", 5180 // = 5 << 10 + 1 + 59 ++ * command_easy: 10, "|", 6220 // = 6 << 10 + 1 + 75 ++ * command_easy: 10, "|", 7256 // = 7 << 10 + 1 + 87 ++ * command_easy: 10, "|", 8294 // = 8 << 10 + 1 + 101 ++ * command_easy: 10, "|", 9333 // = 9 << 10 + 1 + 116 ++ * command_easy: 10, "|", 10368 // = 10 << 10 + 1 + 127 ++ * command_easy: 10, "|", 11408 // = 11 << 10 + 1 + 143 ++ * command_easy: 10, "|", 12441 // = 12 << 10 + 1 + 152 ++ * command_easy: 10, "|", 13475 // = 13 << 10 + 1 + 162 ++ * command_easy: 10, "|", 14513 // = 14 << 10 + 1 + 176 ++ * command_easy: 10, "|", 15550 // = 15 << 10 + 1 + 189 ++ * command_easy: 10, "|", 16587 // = 16 << 10 + 1 + 202 ++ * command_easy: 10, "|", 17626 // = 17 << 10 + 1 + 217 ++ * command_easy: 10, "|", 18665 // = 18 << 10 + 1 + 232 ++ * command_easy: 10, "|", 19703 // = 19 << 10 + 1 + 246 ++ * command_easy: 10, "|", 20739 // = 20 << 10 + 1 + 258 ++ * command_easy: 10, "|", 21775 // = 21 << 10 + 1 + 270 ++ * command_easy: 10, "|", 22812 // = 22 << 10 + 1 + 283 ++ * command_easy: 10, "|", 23848 // = 23 << 10 + 1 + 295 ++ * command_easy: 10, "|", 24880 // = 24 << 10 + 1 + 303 ++ * command_easy: 10, "|", 25916 // = 25 << 10 + 1 + 315 ++ * command_easy: 10, "|", 26956 // = 26 << 10 + 1 + 331 ++ * command_easy: 10, "|", 27988 // = 27 << 10 + 1 + 339 ++ * command_easy: 10, "|", 29021 // = 28 << 10 + 1 + 348 ++ * command_easy: 10, "|", 30059 // = 29 << 10 + 1 + 362 ++ * command_easy: 10, "|", 31100 // = 30 << 10 + 1 + 379 ++ * command_easy: 10, "|", 32136 // = 31 << 10 + 1 + 391 ++ * command_easy: 10, "|", 33173 // = 32 << 10 + 1 + 404 ++ * command_easy: 10, "|", 34209 // = 33 << 10 + 1 + 416 ++ * command_easy: 10, "|", 35247 // = 34 << 10 + 1 + 430 ++ * command_easy: 10, "|", 36278 // = 35 << 10 + 1 + 437 ++ * command_easy: 10, "|", 37319 // = 36 << 10 + 1 + 454 ++ * command_easy: 10, "|", 38355 // = 37 << 10 + 1 + 466 ++ * command_easy: 10, "|", 39396 // = 38 << 10 + 1 + 483 ++ * command_easy: 10, "|", 40435 // = 39 << 10 + 1 + 498 ++ * command_easy: 10, "|", 41465 // = 40 << 10 + 1 + 504 ++ * command_easy: 10, "|", 42494 // = 41 << 10 + 1 + 509 ++ * command_easy: 10, "|", 43534 // = 42 << 10 + 1 + 525 ++ * command_easy: 10, "|", 44565 // = 43 << 10 + 1 + 532 ++ * command_easy: 10, "|", 45606 // = 44 << 10 + 1 + 549 ++ * command_easy: 10, "|", 46641 // = 45 << 10 + 1 + 560 ++ * command_easy: 10, "|", 47680 // = 46 << 10 + 1 + 575 ++ * command_easy: 10, "|", 48719 // = 47 << 10 + 1 + 590 ++ * command_easy: 10, "|", 49758 // = 48 << 10 + 1 + 605 ++ * command_easy: 10, "|", 50786 // = 49 << 10 + 1 + 609 ++ * command_easy: 10, "|", 51824 // = 50 << 10 + 1 + 623 ++ * command_easy: 10, "|", 52861 // = 51 << 10 + 1 + 636 ++ * command_easy: 10, "|", 53897 // = 52 << 10 + 1 + 648 ++ * command_easy: 10, "|", 54935 // = 53 << 10 + 1 + 662 ++ * command_easy: 10, "|", 55973 // = 54 << 10 + 1 + 676 ++ * command_easy: 10, "|", 56999 // = 55 << 10 + 1 + 678 ++ * command_easy: 10, "|", 58027 // = 56 << 10 + 1 + 682 ++ * command_easy: 10, "|", 59056 // = 57 << 10 + 1 + 687 ++ * command_easy: 10, "|", 60092 // = 58 << 10 + 1 + 699 ++ * command_easy: 10, "|", 61129 // = 59 << 10 + 1 + 712 ++ * command_easy: 10, "|", 62156 // = 60 << 10 + 1 + 715 ++ * command_easy: 10, "|", 63195 // = 61 << 10 + 1 + 730 ++ * command_easy: 10, "|", 64233 // = 62 << 10 + 1 + 744 ++ * command_easy: 10, "|", 65277 // = 63 << 10 + 1 + 764 ++ * command_easy: 10, "|", 66307 // = 64 << 10 + 1 + 770 ++ * command_easy: 10, "|", 67333 // = 65 << 10 + 1 + 772 ++ * command_easy: 10, "|", 68371 // = 66 << 10 + 1 + 786 ++ * command_easy: 10, "|", 69407 // = 67 << 10 + 1 + 798 ++ * command_easy: 10, "|", 70444 // = 68 << 10 + 1 + 811 ++ * command_easy: 10, "|", 71480 // = 69 << 10 + 1 + 823 ++ * command_easy: 10, "|", 72517 // = 70 << 10 + 1 + 836 ++ * command_easy: 10, "|", 73554 // = 71 << 10 + 1 + 849 ++ * command_easy: 10, "|", 74591 // = 72 << 10 + 1 + 862 ++ * command_easy: 10, "|", 75631 // = 73 << 10 + 1 + 878 ++ * command_easy: 10, "|", 76679 // = 74 << 10 + 1 + 902 ++ * command_easy: 10, "|", 77715 // = 75 << 10 + 1 + 914 ++ * command_easy: 10, "|", 78757 // = 76 << 10 + 1 + 932 ++ * command_easy: 10, "|", 79793 // = 77 << 10 + 1 + 944 ++ * command_easy: 10, "|", 80830 // = 78 << 10 + 1 + 957 ++ * command_easy: 10, "|", 81866 // = 79 << 10 + 1 + 969 ++ * command_easy: 10, "|", 82902 // = 80 << 10 + 1 + 981 ++ * command_easy: 10, "|", 83942 // = 81 << 10 + 1 + 997 ++ * command_easy: 10, "|", 84980 // = 82 << 10 + 1 + 1011 ++ * command_easy: 10, "|", 86018 // = 83 << 10 + 1 + 1025 ++ * command_easy: 10, "|", 87055 // = 84 << 10 + 1 + 1038 ++ * command_easy: 10, "|", 88093 // = 85 << 10 + 1 + 1052 ++ * command_easy: 10, "|", 89129 // = 86 << 10 + 1 + 1064 ++ * command_easy: 10, "|", 90166 // = 87 << 10 + 1 + 1077 ++ * command_easy: 10, "|", 91202 // = 88 << 10 + 1 + 1089 ++ * command_easy: 10, "|", 92239 // = 89 << 10 + 1 + 1102 ++ * command_easy: 10, "|", 93276 // = 90 << 10 + 1 + 1115 ++ * command_easy: 10, "|", 94315 // = 91 << 10 + 1 + 1130 ++ * command_easy: 10, "|", 95353 // = 92 << 10 + 1 + 1144 ++ * command_easy: 10, "|", 96392 // = 93 << 10 + 1 + 1159 ++ * command_easy: 10, "|", 97432 // = 94 << 10 + 1 + 1175 ++ * command_easy: 10, "|", 98468 // = 95 << 10 + 1 + 1187 ++ * command_easy: 10, "|", 99507 // = 96 << 10 + 1 + 1202 ++ * command_easy: 10, "|", 100544 // = 97 << 10 + 1 + 1215 ++ * command_easy: 10, "|", 101581 // = 98 << 10 + 1 + 1228 ++ * command_easy: 10, "|", 102619 // = 99 << 10 + 1 + 1242 ++ * command_easy: 10, "|", 103655 // = 100 << 10 + 1 + 1254 ++ * command_easy: 10, "|", 104694 // = 101 << 10 + 1 + 1269 ++ * command_easy: 10, "|", 105730 // = 102 << 10 + 1 + 1281 ++ * command_easy: 10, "|", 106767 // = 103 << 10 + 1 + 1294 ++ * command_easy: 10, "|", 107804 // = 104 << 10 + 1 + 1307 ++ * command_easy: 10, "|", 108841 // = 105 << 10 + 1 + 1320 ++ * command_easy: 10, "|", 109878 // = 106 << 10 + 1 + 1333 ++ * command_easy: 10, "|", 110917 // = 107 << 10 + 1 + 1348 ++ * command_easy: 10, "|", 111954 // = 108 << 10 + 1 + 1361 ++ * command_easy: 10, "|", 112991 // = 109 << 10 + 1 + 1374 ++ * command_easy: 10, "|", 114028 // = 110 << 10 + 1 + 1387 ++ * command_easy: 10, "|", 115066 // = 111 << 10 + 1 + 1401 ++ * command_easy: 10, "|", 116104 // = 112 << 10 + 1 + 1415 ++ * command_easy: 10, "|", 117140 // = 113 << 10 + 1 + 1427 ++ * command_easy: 10, "|", 118176 // = 114 << 10 + 1 + 1439 ++ * command_easy: 10, "|", 119213 // = 115 << 10 + 1 + 1452 ++ * command_easy: 10, "|", 120250 // = 116 << 10 + 1 + 1465 ++ * command_easy: 10, "|", 121287 // = 117 << 10 + 1 + 1478 ++ * command_easy: 10, "|", 122325 // = 118 << 10 + 1 + 1492 ++ * command_easy: 10, "|", 123363 // = 119 << 10 + 1 + 1506 ++ * command_easy: 10, "|", 124401 // = 120 << 10 + 1 + 1520 ++ */ ++ compressed, ++ true, ++ "|categories|categories | categories |ategories|Categories |categories the | categories|s cat" ++ + "egories |categories of |Categories|categories and |tegories|categorie|, categories |catego" ++ + "ries, | Categories |categories in |categories to |e categories |categories\"|categories.|c" ++ + "ategories\">|categories\n|categor|categories]|categories for |egories|categori|categories " ++ + "a |categories that | Categories|categories. |.categories| categories, |gories|categories w" ++ + "ith |categories'|categories from |categories by |ories|ries| the categories|catego|categor" ++ + "ies. The |CATEGORIES|categories on |categories as |categories is |cat|categorieing |catego" ++ + "ries\n\t|categories:| categories. |categoriesed |s|ies|cate|categories(|Categories, |ca|ca" ++ + "tegories at |categoriesly | the categories of |categ|c| Categories, |Categories\"|.categor" ++ + "ies(|CATEGORIES |Categories\">|categories=\"| categories.|.com/categories| the categories " ++ + "of the |Categories'|categories. This |categories,|.categories |Categories(|Categories.|cat" ++ + "egories not | categories=\"|categorieser | CATEGORIES |categoriesal | CATEGORIES|categorie" ++ + "s='|CATEGORIES\"|Categories. | categories(|categoriesful | Categories. |categoriesive |cat" ++ + "egoriesless |CATEGORIES'|categoriesest | Categories.|CATEGORIES\">| categories='|Categorie" ++ + "s,|categoriesize |CATEGORIES.|\302\240categories| categories,|Categories=\"|CATEGORIES=" ++ + "\"|categoriesous |CATEGORIES, |Categories='| Categories,| CATEGORIES=\"| CATEGORIES, |CATE" ++ + "GORIES,|CATEGORIES(|CATEGORIES. | CATEGORIES.|CATEGORIES='| CATEGORIES. | Categories=\"| C" ++ + "ATEGORIES='| Categories='" ++ ); ++ } ++ ++ @Test ++ public void testAllTransforms4() { ++ byte[] compressed = { ++ (byte) 0x1b, (byte) 0x40, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80, ++ (byte) 0xe3, (byte) 0xb4, (byte) 0x0d, (byte) 0x00, (byte) 0x00, (byte) 0x07, (byte) 0x5b, ++ (byte) 0x26, (byte) 0x31, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0xe0, (byte) 0x4e, ++ (byte) 0x1b, (byte) 0x51, (byte) 0x3e, (byte) 0x42, (byte) 0x51, (byte) 0x3e, (byte) 0x81, ++ (byte) 0x02, (byte) 0x51, (byte) 0x3e, (byte) 0x11, (byte) 0x04, (byte) 0xa2, (byte) 0x7c, ++ (byte) 0xe2, (byte) 0x0b, (byte) 0x44, (byte) 0xf9, (byte) 0x24, (byte) 0x1b, (byte) 0x10, ++ (byte) 0xe5, (byte) 0x93, (byte) 0x84, (byte) 0x50, (byte) 0x94, (byte) 0x4f, (byte) 0xba, ++ (byte) 0x02, (byte) 0x51, (byte) 0x3e, (byte) 0x69, (byte) 0x0c, (byte) 0x45, (byte) 0xf9, ++ (byte) 0x64, (byte) 0x39, (byte) 0x20, (byte) 0xca, (byte) 0x27, (byte) 0x13, (byte) 0x22, ++ (byte) 0x51, (byte) 0x3e, (byte) 0xd9, (byte) 0x11, (byte) 0x8a, (byte) 0xf2, (byte) 0xc9, ++ (byte) 0xa2, (byte) 0x58, (byte) 0x94, (byte) 0x4f, (byte) 0x4e, (byte) 0x05, (byte) 0xa2, ++ (byte) 0x7c, (byte) 0x72, (byte) 0x2c, (byte) 0x12, (byte) 0xe5, (byte) 0x93, (byte) 0x83, ++ (byte) 0xa1, (byte) 0x28, (byte) 0x9f, (byte) 0xfc, (byte) 0x8c, (byte) 0x45, (byte) 0xf9, ++ (byte) 0x14, (byte) 0x6e, (byte) 0x40, (byte) 0x94, (byte) 0x4f, (byte) 0x71, (byte) 0x47, ++ (byte) 0x44, (byte) 0xf9, (byte) 0x14, (byte) 0x80, (byte) 0x48, (byte) 0x94, (byte) 0x4f, ++ (byte) 0x81, (byte) 0xc8, (byte) 0x44, (byte) 0xf9, (byte) 0x14, (byte) 0x8e, (byte) 0x50, ++ (byte) 0x94, (byte) 0x4f, (byte) 0x41, (byte) 0x49, (byte) 0x45, (byte) 0xf9, (byte) 0x14, ++ (byte) 0x9b, (byte) 0x58, (byte) 0x94, (byte) 0x4f, (byte) 0x11, (byte) 0xca, (byte) 0x45, ++ (byte) 0xf9, (byte) 0x94, (byte) 0xa3, (byte) 0x40, (byte) 0x94, (byte) 0x4f, (byte) 0x99, ++ (byte) 0x4a, (byte) 0x44, (byte) 0xf9, (byte) 0x94, (byte) 0xb3, (byte) 0x48, (byte) 0x94, ++ (byte) 0x4f, (byte) 0x59, (byte) 0xcb, (byte) 0x44, (byte) 0xf9, (byte) 0x94, (byte) 0xb8, ++ (byte) 0x50, (byte) 0x94, (byte) 0x4f, (byte) 0x09, (byte) 0x4c, (byte) 0x45, (byte) 0xf9, ++ (byte) 0x94, (byte) 0xcb, (byte) 0x58, (byte) 0x94, (byte) 0x4f, (byte) 0x19, (byte) 0xcd, ++ (byte) 0x45, (byte) 0xf9, (byte) 0x54, (byte) 0xd8, (byte) 0x80, (byte) 0x28, (byte) 0x9f, ++ (byte) 0xca, (byte) 0x9b, (byte) 0x10, (byte) 0xe5, (byte) 0x53, (byte) 0x99, (byte) 0x23, ++ (byte) 0xa2, (byte) 0x7c, (byte) 0xaa, (byte) 0x73, (byte) 0x46, (byte) 0x94, (byte) 0x4f, ++ (byte) 0x25, (byte) 0x0f, (byte) 0x89, (byte) 0xf2, (byte) 0xa9, (byte) 0xf0, (byte) 0x29, ++ (byte) 0x51, (byte) 0x3e, (byte) 0xd5, (byte) 0x40, (byte) 0x26, (byte) 0xca, (byte) 0xa7, ++ (byte) 0x62, (byte) 0xe8, (byte) 0x44, (byte) 0xf9, (byte) 0x54, (byte) 0x0d, (byte) 0xa1, ++ (byte) 0x28, (byte) 0x9f, (byte) 0xca, (byte) 0xa1, (byte) 0x14, (byte) 0xe5, (byte) 0x53, ++ (byte) 0x61, (byte) 0xa4, (byte) 0xa2, (byte) 0x7c, (byte) 0xaa, (byte) 0x8c, (byte) 0x56, ++ (byte) 0x94, (byte) 0x4f, (byte) 0x45, (byte) 0x12, (byte) 0x8b, (byte) 0xf2, (byte) 0xa9, ++ (byte) 0x52, (byte) 0x6a, (byte) 0x51, (byte) 0x3e, (byte) 0x95, (byte) 0x4c, (byte) 0x2e, ++ (byte) 0xca, (byte) 0xa7, (byte) 0xda, (byte) 0xe9, (byte) 0x45, (byte) 0xf9, (byte) 0xd4, ++ (byte) 0x44, (byte) 0x81, (byte) 0x28, (byte) 0x9f, (byte) 0xba, (byte) 0xa8, (byte) 0x10, ++ (byte) 0xe5, (byte) 0x53, (byte) 0x37, (byte) 0x25, (byte) 0xa2, (byte) 0x7c, (byte) 0x6a, ++ (byte) 0xaa, (byte) 0x46, (byte) 0x94, (byte) 0x4f, (byte) 0xad, (byte) 0x15, (byte) 0x89, ++ (byte) 0xf2, (byte) 0xa9, (byte) 0xc5, (byte) 0x2a, (byte) 0x51, (byte) 0x3e, (byte) 0xb5, ++ (byte) 0x5a, (byte) 0x26, (byte) 0xca, (byte) 0xa7, (byte) 0x5e, (byte) 0xeb, (byte) 0x44, ++ (byte) 0xf9, (byte) 0xd4, (byte) 0x6c, (byte) 0xa1, (byte) 0x28, (byte) 0x9f, (byte) 0xba, ++ (byte) 0xad, (byte) 0x14, (byte) 0xe5, (byte) 0x53, (byte) 0xcf, (byte) 0xa5, (byte) 0xa2, ++ (byte) 0x7c, (byte) 0x6a, (byte) 0xbd, (byte) 0x56, (byte) 0x94, (byte) 0x4f, (byte) 0xbd, ++ (byte) 0x17, (byte) 0x8b, (byte) 0xf2, (byte) 0xa9, (byte) 0x09, (byte) 0x6b, (byte) 0x51, ++ (byte) 0x3e, (byte) 0x35, (byte) 0x63, (byte) 0x2e, (byte) 0xca, (byte) 0xa7, (byte) 0xd6, ++ (byte) 0xec, (byte) 0x45, (byte) 0xf9, (byte) 0x34, (byte) 0x9b, (byte) 0x01, (byte) 0x51, ++ (byte) 0x3e, (byte) 0x0d, (byte) 0x67, (byte) 0x41, (byte) 0x94, (byte) 0x4f, (byte) 0x43, ++ (byte) 0x9a, (byte) 0x10, (byte) 0xe5, (byte) 0xd3, (byte) 0xa8, (byte) 0x36, (byte) 0x44, ++ (byte) 0xf9, (byte) 0x34, (byte) 0xb1, (byte) 0x11, (byte) 0x51, (byte) 0x3e, (byte) 0xcd, ++ (byte) 0x6d, (byte) 0x45, (byte) 0x94, (byte) 0x4f, (byte) 0xe3, (byte) 0x9b, (byte) 0x11, ++ (byte) 0xe5, (byte) 0xd3, (byte) 0x14, (byte) 0x77, (byte) 0x44, (byte) 0xf9, (byte) 0x34, ++ (byte) 0xcc, (byte) 0x21, (byte) 0x51, (byte) 0x3e, (byte) 0x8d, (byte) 0x75, (byte) 0x49, ++ (byte) 0x94, (byte) 0x4f, (byte) 0x83, (byte) 0x9e, (byte) 0x12, (byte) 0xe5, (byte) 0xd3, ++ (byte) 0xb8, (byte) 0xb7, (byte) 0x44, (byte) 0xf9, (byte) 0x34, (byte) 0xfa, (byte) 0x31, ++ (byte) 0x51, (byte) 0x3e, (byte) 0x0d, (byte) 0x80, (byte) 0x4d, (byte) 0x94, (byte) 0x4f, ++ (byte) 0x73, (byte) 0xa0, (byte) 0x13, (byte) 0xe5, (byte) 0xd3, (byte) 0x34, (byte) 0xf8, ++ (byte) 0x44, (byte) 0xf9, (byte) 0x34, (byte) 0x13, (byte) 0x42, (byte) 0x51, (byte) 0x3e, ++ (byte) 0x4d, (byte) 0x87, (byte) 0x51, (byte) 0x94, (byte) 0x4f, (byte) 0x53, (byte) 0xa2, ++ (byte) 0x14, (byte) 0xe5, (byte) 0xd3, (byte) 0xb4, (byte) 0x38, (byte) 0x45, (byte) 0xf9, ++ (byte) 0x34, (byte) 0x34, (byte) 0x52, (byte) 0x51, (byte) 0x3e, (byte) 0x0d, (byte) 0x8f, ++ (byte) 0x55, (byte) 0x94, (byte) 0x4f, (byte) 0x23, (byte) 0xa4, (byte) 0x15, (byte) 0xe5, ++ (byte) 0xd3, (byte) 0x24, (byte) 0x79, (byte) 0x45, (byte) 0xf9, (byte) 0x34, (byte) 0x4f, ++ (byte) 0x62, (byte) 0x51, (byte) 0x3e, (byte) 0x8d, (byte) 0x95, (byte) 0x59, (byte) 0x94, ++ (byte) 0x4f, (byte) 0xd3, (byte) 0xa5, (byte) 0x16, (byte) 0xe5, (byte) 0xd3, (byte) 0x98, ++ (byte) 0xb9, (byte) 0x45, (byte) 0xf9, (byte) 0x34, (byte) 0x6e, (byte) 0x72, (byte) 0x51, ++ (byte) 0x3e, (byte) 0xcd, (byte) 0x9d, (byte) 0x5d, (byte) 0x94, (byte) 0x4f, (byte) 0x13, ++ (byte) 0xa8, (byte) 0x17, (byte) 0xe5, (byte) 0xd3, (byte) 0x1c, (byte) 0xfa, (byte) 0x45, ++ (byte) 0xf9, (byte) 0xb4, (byte) 0x90, (byte) 0x02, (byte) 0x51, (byte) 0x3e, (byte) 0xed, ++ (byte) 0xa5, (byte) 0x41, (byte) 0x94, (byte) 0x4f, (byte) 0xeb, (byte) 0xa9, (byte) 0x10, ++ (byte) 0xe5, (byte) 0xd3, (byte) 0x9a, (byte) 0x3a, (byte) 0x44, (byte) 0xf9, (byte) 0xb4, ++ (byte) 0xac, (byte) 0x12, (byte) 0x51, (byte) 0x3e, (byte) 0x6d, (byte) 0xad, (byte) 0x45, ++ (byte) 0x94, (byte) 0x4f, (byte) 0xbb, (byte) 0xab, (byte) 0x11, (byte) 0xe5, (byte) 0xd3, ++ (byte) 0x0a, (byte) 0x7b, (byte) 0x44, (byte) 0xf9, (byte) 0xb4, (byte) 0xc9, (byte) 0x22, ++ (byte) 0x51, (byte) 0x3e, (byte) 0x2d, (byte) 0xb4, (byte) 0x49, (byte) 0x94, (byte) 0x4f, ++ (byte) 0x7b, (byte) 0xad, (byte) 0x12, (byte) 0xe5, (byte) 0xd3, (byte) 0x82, (byte) 0xbb, ++ (byte) 0x44, (byte) 0xf9, (byte) 0xb4, (byte) 0xe7, (byte) 0x32, (byte) 0x51, (byte) 0x3e, ++ (byte) 0xad, (byte) 0xbb, (byte) 0x4d, (byte) 0x94, (byte) 0x4f, (byte) 0x5b, (byte) 0xaf, ++ (byte) 0x13, (byte) 0xe5, (byte) 0xd3, (byte) 0xf6, (byte) 0xfb, (byte) 0x44, (byte) 0xf9, ++ (byte) 0xb4, (byte) 0x05, (byte) 0x43, (byte) 0x51, (byte) 0x3e, (byte) 0xed, (byte) 0xc2, ++ (byte) 0x51, (byte) 0x94, (byte) 0x4f, (byte) 0x1b, (byte) 0xb1, (byte) 0x14, (byte) 0xe5, ++ (byte) 0xd3, (byte) 0x62, (byte) 0x3c, (byte) 0x45, (byte) 0xf9, (byte) 0xb4, (byte) 0x1f, ++ (byte) 0x53, (byte) 0x51, (byte) 0x3e, (byte) 0xad, (byte) 0xc9, (byte) 0x55, (byte) 0x94, ++ (byte) 0x4f, (byte) 0xeb, (byte) 0xb2, (byte) 0x15, (byte) 0xe5, (byte) 0xd3, (byte) 0xda, ++ (byte) 0x7c, (byte) 0x45, (byte) 0xf9, (byte) 0xb4, (byte) 0x3e, (byte) 0x63 ++ }; ++ checkSynth( ++ /* ++ * // The stream consists of word "time" with all possible transforms. ++ * main_header ++ * metablock_header_easy: 833, 1 ++ * command_easy: 4, "|", 2 // = 0 << 10 + 1 + 1 ++ * command_easy: 4, "|", 1031 // = 1 << 10 + 1 + 6 ++ * command_easy: 4, "|", 2061 // = 2 << 10 + 1 + 12 ++ * command_easy: 4, "|", 3092 // = 3 << 10 + 1 + 19 ++ * command_easy: 4, "|", 4120 // = 4 << 10 + 1 + 23 ++ * command_easy: 4, "|", 5150 // = 5 << 10 + 1 + 29 ++ * command_easy: 4, "|", 6184 // = 6 << 10 + 1 + 39 ++ * command_easy: 4, "|", 7214 // = 7 << 10 + 1 + 45 ++ * command_easy: 4, "|", 8246 // = 8 << 10 + 1 + 53 ++ * command_easy: 4, "|", 9279 // = 9 << 10 + 1 + 62 ++ * command_easy: 4, "|", 10308 // = 10 << 10 + 1 + 67 ++ * command_easy: 4, "|", 11342 // = 11 << 10 + 1 + 77 ++ * command_easy: 4, "|", 12369 // = 12 << 10 + 1 + 80 ++ * command_easy: 4, "|", 13397 // = 13 << 10 + 1 + 84 ++ * command_easy: 4, "|", 14429 // = 14 << 10 + 1 + 92 ++ * command_easy: 4, "|", 15460 // = 15 << 10 + 1 + 99 ++ * command_easy: 4, "|", 16491 // = 16 << 10 + 1 + 106 ++ * command_easy: 4, "|", 17524 // = 17 << 10 + 1 + 115 ++ * command_easy: 4, "|", 18557 // = 18 << 10 + 1 + 124 ++ * command_easy: 4, "|", 19589 // = 19 << 10 + 1 + 132 ++ * command_easy: 4, "|", 20619 // = 20 << 10 + 1 + 138 ++ * command_easy: 4, "|", 21649 // = 21 << 10 + 1 + 144 ++ * command_easy: 4, "|", 22680 // = 22 << 10 + 1 + 151 ++ * command_easy: 4, "|", 23710 // = 23 << 10 + 1 + 157 ++ * command_easy: 4, "|", 24736 // = 24 << 10 + 1 + 159 ++ * command_easy: 4, "|", 25766 // = 25 << 10 + 1 + 165 ++ * command_easy: 4, "|", 26800 // = 26 << 10 + 1 + 175 ++ * command_easy: 4, "|", 27826 // = 27 << 10 + 1 + 177 ++ * command_easy: 4, "|", 28853 // = 28 << 10 + 1 + 180 ++ * command_easy: 4, "|", 29885 // = 29 << 10 + 1 + 188 ++ * command_easy: 4, "|", 30920 // = 30 << 10 + 1 + 199 ++ * command_easy: 4, "|", 31950 // = 31 << 10 + 1 + 205 ++ * command_easy: 4, "|", 32981 // = 32 << 10 + 1 + 212 ++ * command_easy: 4, "|", 34011 // = 33 << 10 + 1 + 218 ++ * command_easy: 4, "|", 35043 // = 34 << 10 + 1 + 226 ++ * command_easy: 4, "|", 36068 // = 35 << 10 + 1 + 227 ++ * command_easy: 4, "|", 37103 // = 36 << 10 + 1 + 238 ++ * command_easy: 4, "|", 38133 // = 37 << 10 + 1 + 244 ++ * command_easy: 4, "|", 39168 // = 38 << 10 + 1 + 255 ++ * command_easy: 4, "|", 40201 // = 39 << 10 + 1 + 264 ++ * command_easy: 4, "|", 41226 // = 40 << 10 + 1 + 265 ++ * command_easy: 4, "|", 42251 // = 41 << 10 + 1 + 266 ++ * command_easy: 4, "|", 43285 // = 42 << 10 + 1 + 276 ++ * command_easy: 4, "|", 44310 // = 43 << 10 + 1 + 277 ++ * command_easy: 4, "|", 45345 // = 44 << 10 + 1 + 288 ++ * command_easy: 4, "|", 46374 // = 45 << 10 + 1 + 293 ++ * command_easy: 4, "|", 47407 // = 46 << 10 + 1 + 302 ++ * command_easy: 4, "|", 48440 // = 47 << 10 + 1 + 311 ++ * command_easy: 4, "|", 49473 // = 48 << 10 + 1 + 320 ++ * command_easy: 4, "|", 50498 // = 49 << 10 + 1 + 321 ++ * command_easy: 4, "|", 51530 // = 50 << 10 + 1 + 329 ++ * command_easy: 4, "|", 52561 // = 51 << 10 + 1 + 336 ++ * command_easy: 4, "|", 53591 // = 52 << 10 + 1 + 342 ++ * command_easy: 4, "|", 54623 // = 53 << 10 + 1 + 350 ++ * command_easy: 4, "|", 55655 // = 54 << 10 + 1 + 358 ++ * command_easy: 4, "|", 56680 // = 55 << 10 + 1 + 359 ++ * command_easy: 4, "|", 57705 // = 56 << 10 + 1 + 360 ++ * command_easy: 4, "|", 58730 // = 57 << 10 + 1 + 361 ++ * command_easy: 4, "|", 59760 // = 58 << 10 + 1 + 367 ++ * command_easy: 4, "|", 60791 // = 59 << 10 + 1 + 374 ++ * command_easy: 4, "|", 61816 // = 60 << 10 + 1 + 375 ++ * command_easy: 4, "|", 62849 // = 61 << 10 + 1 + 384 ++ * command_easy: 4, "|", 63881 // = 62 << 10 + 1 + 392 ++ * command_easy: 4, "|", 64919 // = 63 << 10 + 1 + 406 ++ * command_easy: 4, "|", 65944 // = 64 << 10 + 1 + 407 ++ * command_easy: 4, "|", 66969 // = 65 << 10 + 1 + 408 ++ * command_easy: 4, "|", 68001 // = 66 << 10 + 1 + 416 ++ * command_easy: 4, "|", 69031 // = 67 << 10 + 1 + 422 ++ * command_easy: 4, "|", 70062 // = 68 << 10 + 1 + 429 ++ * command_easy: 4, "|", 71092 // = 69 << 10 + 1 + 435 ++ * command_easy: 4, "|", 72123 // = 70 << 10 + 1 + 442 ++ * command_easy: 4, "|", 73154 // = 71 << 10 + 1 + 449 ++ * command_easy: 4, "|", 74185 // = 72 << 10 + 1 + 456 ++ * command_easy: 4, "|", 75219 // = 73 << 10 + 1 + 466 ++ * command_easy: 4, "|", 76261 // = 74 << 10 + 1 + 484 ++ * command_easy: 4, "|", 77291 // = 75 << 10 + 1 + 490 ++ * command_easy: 4, "|", 78327 // = 76 << 10 + 1 + 502 ++ * command_easy: 4, "|", 79357 // = 77 << 10 + 1 + 508 ++ * command_easy: 4, "|", 80388 // = 78 << 10 + 1 + 515 ++ * command_easy: 4, "|", 81418 // = 79 << 10 + 1 + 521 ++ * command_easy: 4, "|", 82448 // = 80 << 10 + 1 + 527 ++ * command_easy: 4, "|", 83482 // = 81 << 10 + 1 + 537 ++ * command_easy: 4, "|", 84514 // = 82 << 10 + 1 + 545 ++ * command_easy: 4, "|", 85546 // = 83 << 10 + 1 + 553 ++ * command_easy: 4, "|", 86577 // = 84 << 10 + 1 + 560 ++ * command_easy: 4, "|", 87609 // = 85 << 10 + 1 + 568 ++ * command_easy: 4, "|", 88639 // = 86 << 10 + 1 + 574 ++ * command_easy: 4, "|", 89670 // = 87 << 10 + 1 + 581 ++ * command_easy: 4, "|", 90700 // = 88 << 10 + 1 + 587 ++ * command_easy: 4, "|", 91731 // = 89 << 10 + 1 + 594 ++ * command_easy: 4, "|", 92762 // = 90 << 10 + 1 + 601 ++ * command_easy: 4, "|", 93795 // = 91 << 10 + 1 + 610 ++ * command_easy: 4, "|", 94827 // = 92 << 10 + 1 + 618 ++ * command_easy: 4, "|", 95860 // = 93 << 10 + 1 + 627 ++ * command_easy: 4, "|", 96894 // = 94 << 10 + 1 + 637 ++ * command_easy: 4, "|", 97924 // = 95 << 10 + 1 + 643 ++ * command_easy: 4, "|", 98957 // = 96 << 10 + 1 + 652 ++ * command_easy: 4, "|", 99988 // = 97 << 10 + 1 + 659 ++ * command_easy: 4, "|", 101019 // = 98 << 10 + 1 + 666 ++ * command_easy: 4, "|", 102051 // = 99 << 10 + 1 + 674 ++ * command_easy: 4, "|", 103081 // = 100 << 10 + 1 + 680 ++ * command_easy: 4, "|", 104114 // = 101 << 10 + 1 + 689 ++ * command_easy: 4, "|", 105144 // = 102 << 10 + 1 + 695 ++ * command_easy: 4, "|", 106175 // = 103 << 10 + 1 + 702 ++ * command_easy: 4, "|", 107206 // = 104 << 10 + 1 + 709 ++ * command_easy: 4, "|", 108237 // = 105 << 10 + 1 + 716 ++ * command_easy: 4, "|", 109268 // = 106 << 10 + 1 + 723 ++ * command_easy: 4, "|", 110301 // = 107 << 10 + 1 + 732 ++ * command_easy: 4, "|", 111332 // = 108 << 10 + 1 + 739 ++ * command_easy: 4, "|", 112363 // = 109 << 10 + 1 + 746 ++ * command_easy: 4, "|", 113394 // = 110 << 10 + 1 + 753 ++ * command_easy: 4, "|", 114426 // = 111 << 10 + 1 + 761 ++ * command_easy: 4, "|", 115458 // = 112 << 10 + 1 + 769 ++ * command_easy: 4, "|", 116488 // = 113 << 10 + 1 + 775 ++ * command_easy: 4, "|", 117518 // = 114 << 10 + 1 + 781 ++ * command_easy: 4, "|", 118549 // = 115 << 10 + 1 + 788 ++ * command_easy: 4, "|", 119580 // = 116 << 10 + 1 + 795 ++ * command_easy: 4, "|", 120611 // = 117 << 10 + 1 + 802 ++ * command_easy: 4, "|", 121643 // = 118 << 10 + 1 + 810 ++ * command_easy: 4, "|", 122675 // = 119 << 10 + 1 + 818 ++ * command_easy: 4, "|", 123707 // = 120 << 10 + 1 + 826 ++ */ ++ compressed, ++ true, ++ "|time|time | time |ime|Time |time the | time|s time |time of |Time|time and |me|tim|, time |" ++ + "time, | Time |time in |time to |e time |time\"|time.|time\">|time\n|t|time]|time for |e|ti" ++ + "|time a |time that | Time|time. |.time| time, ||time with |time'|time from |time by ||| th" ++ + "e time||time. The |TIME|time on |time as |time is ||timing |time\n\t|time:| time. |timeed " ++ + "||||time(|Time, ||time at |timely | the time of ||| Time, |Time\"|.time(|TIME |Time\">|tim" ++ + "e=\"| time.|.com/time| the time of the |Time'|time. This |time,|.time |Time(|Time.|time no" ++ + "t | time=\"|timeer | TIME |timeal | TIME|time='|TIME\"|Time. | time(|timeful | Time. |time" ++ + "ive |timeless |TIME'|timeest | Time.|TIME\">| time='|Time,|timeize |TIME.|\302\240time| ti" ++ + "me,|Time=\"|TIME=\"|timeous |TIME, |Time='| Time,| TIME=\"| TIME, |TIME,|TIME(|TIME. | TIM" ++ + "E.|TIME='| TIME. | Time=\"| TIME='| Time='" ++ ); ++ } ++ + @Test + public void testBaseDictWord() { + byte[] compressed = { +@@ -446,6 +914,28 @@ public void testCopyLengthTooLong() { + ); + } + ++ @Test ++ public void testCopyTooLong() { ++ byte[] compressed = { ++ (byte) 0xa1, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, ++ (byte) 0x1c, (byte) 0xa7, (byte) 0x6d, (byte) 0x00, (byte) 0x00, (byte) 0x38, (byte) 0xd8, ++ (byte) 0x32, (byte) 0x89, (byte) 0x01, (byte) 0x12, (byte) 0x00, (byte) 0x00, (byte) 0x77, ++ (byte) 0xda, (byte) 0x34, (byte) 0xab, (byte) 0xdb, (byte) 0x50, (byte) 0x00 ++ }; ++ checkSynth( ++ /* ++ * // Has a copy length that goes over the end of the meta-block, ++ * // with a ringbuffer wrap. ++ * main_header: 10 ++ * metablock_header_easy: 2, 1 ++ * command_easy: 1024, "a", 1 ++ */ ++ compressed, ++ false, ++ "" ++ ); ++ } ++ + @Test + public void testCustomHuffmanCode() { + byte[] compressed = { +@@ -2199,6 +2689,23 @@ public void testSimplePrefixOutOfRangeSymbols() { + ); + } + ++/* DISABLED: Java decoder does not tolerate extra input after the brotli stream. ++ @Test ++ public void testSimplePrefixPlusExtraData() { ++ byte[] compressed = { ++ (byte) 0x1b, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0xa0, (byte) 0xc3, (byte) 0xc4, ++ (byte) 0xc6, (byte) 0xc8, (byte) 0x02, (byte) 0x00, (byte) 0x70, (byte) 0xb0, (byte) 0x65, ++ (byte) 0x12, (byte) 0x03, (byte) 0x24, (byte) 0x00, (byte) 0x00, (byte) 0xee, (byte) 0xb4, ++ (byte) 0x51, (byte) 0xa0, (byte) 0x1d, (byte) 0x55, (byte) 0xaa ++ }; ++ checkSynth( ++ compressed, ++ true, ++ "abcd" ++ ); ++ } ++*/ ++ + @Test + public void testTooManySymbolsRepeated() { + byte[] compressed = { +@@ -2246,7 +2753,7 @@ public void testTransformedDictWord() { + * main_header + * metablock_header_easy: 9, 1 + * command_inscopy_easy: 0, 4 +- * command_dist_easy: 5121 ++ * command_dist_easy: 5121 // 5 << 10 + 1 + */ + compressed, + true, +@@ -2270,7 +2777,7 @@ public void testTransformedDictWordTooLong() { + * main_header + * metablock_header_easy: 4, 1 + * command_inscopy_easy: 0, 4 +- * command_dist_easy: 5121 ++ * command_dist_easy: 5121 // 5 << 10 + 1 + */ + compressed, + false, +@@ -2280,4 +2787,4 @@ public void testTransformedDictWordTooLong() { + + /* GENERATED CODE END */ + +-} +\ No newline at end of file ++} +diff --git a/java/org/brotli/dec/Transform.java b/java/org/brotli/dec/Transform.java +index b90f2e96..3279ee73 100644 +--- a/java/org/brotli/dec/Transform.java ++++ b/java/org/brotli/dec/Transform.java +@@ -10,13 +10,58 @@ + + /** + * Transformations on dictionary words. ++ * ++ * Transform descriptor is a triplet: {prefix, operator, suffix}. ++ * "prefix" and "suffix" are short strings inserted before and after transformed dictionary word. ++ * "operator" is applied to dictionary word itself. ++ * ++ * Some operators has "built-in" parameters, i.e. parameter is defined by operator ordinal. Other ++ * operators have "external" parameters, supplied via additional table encoded in shared dictionary. ++ * ++ * Operators: ++ * - IDENTITY (0): dictionary word is inserted "as is" ++ * - OMIT_LAST_N (1 - 9): last N octets of dictionary word are not inserted; N == ordinal ++ * - OMIT_FIRST_M (12-20): first M octets of dictionary word are not inserted; M == ordinal - 11 ++ * - UPPERCASE_FIRST (10): first "scalar" is XOR'ed with number 32 ++ * - UPPERCASE_ALL (11): all "scalars" are XOR'ed with number 32 ++ * - SHIFT_FIRST (21): first "scalar" is shifted by number form parameter table ++ * - SHIFT_ALL (22): all "scalar" is shifted by number form parameter table ++ * ++ * Here "scalar" is a variable length character coding similar to UTF-8 encoding. ++ * UPPERCASE_XXX / SHIFT_XXX operators were designed to change the case of UTF-8 encoded characters. ++ * While UPPERCASE_XXX works well only on ASCII charset, SHIFT is much more generic and could be ++ * used for most (all?) alphabets. + */ + final class Transform { + +- static final int NUM_TRANSFORMS = 121; +- private static final int[] TRANSFORMS = new int[NUM_TRANSFORMS * 3]; +- private static final byte[] PREFIX_SUFFIX = new byte[217]; +- private static final int[] PREFIX_SUFFIX_HEADS = new int[51]; ++ static final class Transforms { ++ final int numTransforms; ++ final int[] triplets; ++ final byte[] prefixSuffixStorage; ++ final int[] prefixSuffixHeads; ++ final short[] params; ++ ++ Transforms(int numTransforms, int prefixSuffixLen, int prefixSuffixCount) { ++ this.numTransforms = numTransforms; ++ this.triplets = new int[numTransforms * 3]; ++ this.params = new short[numTransforms]; ++ this.prefixSuffixStorage = new byte[prefixSuffixLen]; ++ this.prefixSuffixHeads = new int[prefixSuffixCount + 1]; ++ } ++ } ++ ++ static final int NUM_RFC_TRANSFORMS = 121; ++ static final Transforms RFC_TRANSFORMS = new Transforms(NUM_RFC_TRANSFORMS, 167, 50); ++ ++ private static final int OMIT_FIRST_LAST_LIMIT = 9; ++ ++ private static final int IDENTITY = 0; ++ private static final int OMIT_LAST_BASE = IDENTITY + 1 - 1; // there is no OMIT_LAST_0. ++ private static final int UPPERCASE_FIRST = OMIT_LAST_BASE + OMIT_FIRST_LAST_LIMIT + 1; ++ private static final int UPPERCASE_ALL = UPPERCASE_FIRST + 1; ++ private static final int OMIT_FIRST_BASE = UPPERCASE_ALL + 1 - 1; // there is no OMIT_FIRST_0. ++ private static final int SHIFT_FIRST = OMIT_FIRST_BASE + OMIT_FIRST_LAST_LIMIT + 1; ++ private static final int SHIFT_ALL = SHIFT_FIRST + 1; + + // Bundle of 0-terminated strings. + private static final String PREFIX_SUFFIX_SRC = "# #s #, #e #.# the #.com/#\u00C2\u00A0# of # and" +@@ -29,71 +74,87 @@ + + " G% ! *A *% H! D I!+! J!+ K +- *4! A L!*4 M N +6 O!*% +.! K *G P +%( ! G *D +D " + + " Q +# *K!*G!+D!+# +G +A +4!+% +K!+4!*D!+K!*K"; + +- private static void unpackTransforms(byte[] prefixSuffix, int[] prefixSuffixHeads, +- int[] transforms, String prefixSuffixSrc, String transformsSrc) { ++ private static void unpackTransforms(byte[] prefixSuffix, ++ int[] prefixSuffixHeads, int[] transforms, String prefixSuffixSrc, String transformsSrc) { + int n = prefixSuffixSrc.length(); + int index = 1; ++ int j = 0; + for (int i = 0; i < n; ++i) { + char c = prefixSuffixSrc.charAt(i); +- prefixSuffix[i] = (byte) c; + if (c == 35) { // == # +- prefixSuffixHeads[index++] = i + 1; +- prefixSuffix[i] = 0; ++ prefixSuffixHeads[index++] = j; ++ } else { ++ prefixSuffix[j++] = (byte) c; + } + } + +- for (int i = 0; i < NUM_TRANSFORMS * 3; ++i) { ++ for (int i = 0; i < NUM_RFC_TRANSFORMS * 3; ++i) { + transforms[i] = transformsSrc.charAt(i) - 32; + } + } + + static { +- unpackTransforms(PREFIX_SUFFIX, PREFIX_SUFFIX_HEADS, TRANSFORMS, PREFIX_SUFFIX_SRC, +- TRANSFORMS_SRC); ++ unpackTransforms(RFC_TRANSFORMS.prefixSuffixStorage, RFC_TRANSFORMS.prefixSuffixHeads, ++ RFC_TRANSFORMS.triplets, PREFIX_SUFFIX_SRC, TRANSFORMS_SRC); + } + +- static int transformDictionaryWord(byte[] dst, int dstOffset, ByteBuffer data, int wordOffset, +- int len, int transformIndex) { ++ static int transformDictionaryWord(byte[] dst, int dstOffset, ByteBuffer src, int srcOffset, ++ int len, Transforms transforms, int transformIndex) { + int offset = dstOffset; ++ int[] triplets = transforms.triplets; ++ byte[] prefixSuffixStorage = transforms.prefixSuffixStorage; ++ int[] prefixSuffixHeads = transforms.prefixSuffixHeads; + int transformOffset = 3 * transformIndex; +- int transformPrefix = PREFIX_SUFFIX_HEADS[TRANSFORMS[transformOffset]]; +- int transformType = TRANSFORMS[transformOffset + 1]; +- int transformSuffix = PREFIX_SUFFIX_HEADS[TRANSFORMS[transformOffset + 2]]; ++ int prefixIdx = triplets[transformOffset]; ++ int transformType = triplets[transformOffset + 1]; ++ int suffixIdx = triplets[transformOffset + 2]; ++ int prefix = prefixSuffixHeads[prefixIdx]; ++ int prefixEnd = prefixSuffixHeads[prefixIdx + 1]; ++ int suffix = prefixSuffixHeads[suffixIdx]; ++ int suffixEnd = prefixSuffixHeads[suffixIdx + 1]; ++ ++ int omitFirst = transformType - OMIT_FIRST_BASE; ++ int omitLast = transformType - OMIT_LAST_BASE; ++ if (omitFirst < 1 || omitFirst > OMIT_FIRST_LAST_LIMIT) { ++ omitFirst = 0; ++ } ++ if (omitLast < 1 || omitLast > OMIT_FIRST_LAST_LIMIT) { ++ omitLast = 0; ++ } + + // Copy prefix. +- while (PREFIX_SUFFIX[transformPrefix] != 0) { +- dst[offset++] = PREFIX_SUFFIX[transformPrefix++]; ++ while (prefix != prefixEnd) { ++ dst[offset++] = prefixSuffixStorage[prefix++]; + } + + // Copy trimmed word. +- int omitFirst = transformType >= 12 ? (transformType - 11) : 0; + if (omitFirst > len) { + omitFirst = len; + } +- wordOffset += omitFirst; ++ srcOffset += omitFirst; + len -= omitFirst; +- len -= transformType <= 9 ? transformType : 0; // Omit last. ++ len -= omitLast; + int i = len; + while (i > 0) { +- dst[offset++] = data.get(wordOffset++); ++ dst[offset++] = src.get(srcOffset++); + i--; + } + + // Ferment. +- if (transformType == 11 || transformType == 10) { ++ if (transformType == UPPERCASE_FIRST || transformType == UPPERCASE_ALL) { + int uppercaseOffset = offset - len; +- if (transformType == 10) { ++ if (transformType == UPPERCASE_FIRST) { + len = 1; + } + while (len > 0) { +- int tmp = dst[uppercaseOffset] & 0xFF; +- if (tmp < 0xc0) { +- if (tmp >= 97 && tmp <= 122) { // in [a..z] range ++ int c0 = dst[uppercaseOffset] & 0xFF; ++ if (c0 < 0xC0) { ++ if (c0 >= 97 && c0 <= 122) { // in [a..z] range + dst[uppercaseOffset] ^= (byte) 32; + } + uppercaseOffset += 1; + len -= 1; +- } else if (tmp < 0xe0) { ++ } else if (c0 < 0xE0) { + dst[uppercaseOffset + 1] ^= (byte) 32; + uppercaseOffset += 2; + len -= 2; +@@ -103,11 +164,71 @@ static int transformDictionaryWord(byte[] dst, int dstOffset, ByteBuffer data, i + len -= 3; + } + } ++ } else if (transformType == SHIFT_FIRST || transformType == SHIFT_ALL) { ++ int shiftOffset = offset - len; ++ short param = transforms.params[transformIndex]; ++ /* Limited sign extension: scalar < (1 << 24). */ ++ int scalar = (param & 0x7FFF) + (0x1000000 - (param & 0x8000)); ++ while (len > 0) { ++ int step = 1; ++ int c0 = dst[shiftOffset] & 0xFF; ++ if (c0 < 0x80) { ++ /* 1-byte rune / 0sssssss / 7 bit scalar (ASCII). */ ++ scalar += c0; ++ dst[shiftOffset] = (byte) (scalar & 0x7F); ++ } else if (c0 < 0xC0) { ++ /* Continuation / 10AAAAAA. */ ++ } else if (c0 < 0xE0) { ++ /* 2-byte rune / 110sssss AAssssss / 11 bit scalar. */ ++ if (len >= 2) { ++ byte c1 = dst[shiftOffset + 1]; ++ scalar += (c1 & 0x3F) | ((c0 & 0x1F) << 6); ++ dst[shiftOffset] = (byte) (0xC0 | ((scalar >> 6) & 0x1F)); ++ dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | (scalar & 0x3F)); ++ step = 2; ++ } else { ++ step = len; ++ } ++ } else if (c0 < 0xF0) { ++ /* 3-byte rune / 1110ssss AAssssss BBssssss / 16 bit scalar. */ ++ if (len >= 3) { ++ byte c1 = dst[shiftOffset + 1]; ++ byte c2 = dst[shiftOffset + 2]; ++ scalar += (c2 & 0x3F) | ((c1 & 0x3F) << 6) | ((c0 & 0x0F) << 12); ++ dst[shiftOffset] = (byte) (0xE0 | ((scalar >> 12) & 0x0F)); ++ dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | ((scalar >> 6) & 0x3F)); ++ dst[shiftOffset + 2] = (byte) ((c2 & 0xC0) | (scalar & 0x3F)); ++ step = 3; ++ } else { ++ step = len; ++ } ++ } else if (c0 < 0xF8) { ++ /* 4-byte rune / 11110sss AAssssss BBssssss CCssssss / 21 bit scalar. */ ++ if (len >= 4) { ++ byte c1 = dst[shiftOffset + 1]; ++ byte c2 = dst[shiftOffset + 2]; ++ byte c3 = dst[shiftOffset + 3]; ++ scalar += (c3 & 0x3F) | ((c2 & 0x3F) << 6) | ((c1 & 0x3F) << 12) | ((c0 & 0x07) << 18); ++ dst[shiftOffset] = (byte) (0xF0 | ((scalar >> 18) & 0x07)); ++ dst[shiftOffset + 1] = (byte) ((c1 & 0xC0) | ((scalar >> 12) & 0x3F)); ++ dst[shiftOffset + 2] = (byte) ((c2 & 0xC0) | ((scalar >> 6) & 0x3F)); ++ dst[shiftOffset + 3] = (byte) ((c3 & 0xC0) | (scalar & 0x3F)); ++ step = 4; ++ } else { ++ step = len; ++ } ++ } ++ shiftOffset += step; ++ len -= step; ++ if (transformType == SHIFT_FIRST) { ++ len = 0; ++ } ++ } + } + + // Copy suffix. +- while (PREFIX_SUFFIX[transformSuffix] != 0) { +- dst[offset++] = PREFIX_SUFFIX[transformSuffix++]; ++ while (suffix != suffixEnd) { ++ dst[offset++] = prefixSuffixStorage[suffix++]; + } + + return offset - dstOffset; +diff --git a/java/org/brotli/dec/TransformTest.java b/java/org/brotli/dec/TransformTest.java +index 616ba351..6e04f0dc 100644 +--- a/java/org/brotli/dec/TransformTest.java ++++ b/java/org/brotli/dec/TransformTest.java +@@ -36,8 +36,8 @@ private static long crc64(byte[] data) { + public void testTrimAll() { + byte[] output = new byte[0]; + byte[] input = {119, 111, 114, 100}; // "word" +- Transform.transformDictionaryWord( +- output, 0, ByteBuffer.wrap(input), 0, input.length, 39); ++ Transform.transformDictionaryWord(output, 0, ++ ByteBuffer.wrap(input), 0, input.length, Transform.RFC_TRANSFORMS, 39); + byte[] expectedOutput = new byte[0]; + assertArrayEquals(expectedOutput, output); + } +@@ -46,8 +46,8 @@ public void testTrimAll() { + public void testCapitalize() { + byte[] output = new byte[6]; + byte[] input = {113, -61, -90, -32, -92, -86}; // "qæप" +- Transform.transformDictionaryWord( +- output, 0, ByteBuffer.wrap(input), 0, input.length, 44); ++ Transform.transformDictionaryWord(output, 0, ++ ByteBuffer.wrap(input), 0, input.length, Transform.RFC_TRANSFORMS, 44); + byte[] expectedOutput = {81, -61, -122, -32, -92, -81}; // "QÆय" + assertArrayEquals(expectedOutput, output); + } +@@ -60,9 +60,9 @@ public void testAllTransforms() { + byte[] testWord = {111, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102}; + byte[] output = new byte[2259]; + int offset = 0; +- for (int i = 0; i < Transform.NUM_TRANSFORMS; ++i) { +- offset += Transform.transformDictionaryWord( +- output, offset, ByteBuffer.wrap(testWord), 0, testWord.length, i); ++ for (int i = 0; i < Transform.NUM_RFC_TRANSFORMS; ++i) { ++ offset += Transform.transformDictionaryWord(output, offset, ++ ByteBuffer.wrap(testWord), 0, testWord.length, Transform.RFC_TRANSFORMS, i); + output[offset++] = -1; + } + assertEquals(output.length, offset); + diff --git a/fix-cve-2020-8927.patch b/fix-cve-2020-8927.patch new file mode 100644 index 0000000..7f23aa1 --- /dev/null +++ b/fix-cve-2020-8927.patch @@ -0,0 +1,1212 @@ +From 4c08c515f3c45abde832ce7421794ae6fc14cd21 Mon Sep 17 00:00:00 2001 +From: Eugene Kliuchnikov +Date: Wed, 26 Aug 2020 10:42:53 +0200 +Subject: [PATCH] Update + + * IMPORTANT: decoder: fix overflow when input chunk is >2GiB + * simplify max Huffman table size calculation + * eliminate symbol duplicates (static arrays in .h files) + * minor combing in research/ code +--- + .travis.yml | 5 +- + c/common/constants.c | 15 ++++ + c/common/constants.h | 16 ++++ + c/common/context.c | 156 +++++++++++++++++++++++++++++++++++++ + c/common/context.h | 156 +------------------------------------ + c/common/platform.c | 22 ++++++ + c/common/platform.h | 11 +-- + c/dec/bit_reader.c | 11 +++ + c/dec/bit_reader.h | 19 ++--- + c/dec/decode.c | 9 ++- + c/dec/huffman.h | 9 +-- + c/dec/prefix.h | 18 ----- + c/dec/state.c | 8 +- + c/enc/brotli_bit_stream.c | 21 +---- + c/enc/command.c | 28 +++++++ + c/enc/command.h | 24 +++--- + c/enc/entropy_encode.c | 2 + + c/enc/entropy_encode.h | 4 +- + c/enc/fast_log.c | 105 +++++++++++++++++++++++++ + c/enc/fast_log.h | 99 ++--------------------- + research/brotli_decoder.c | 1 + + research/draw_histogram.cc | 25 +++--- + scripts/.bintray.json | 2 +- + scripts/sources.lst | 5 ++ + setup.py | 5 ++ + 25 files changed, 431 insertions(+), 345 deletions(-) + create mode 100644 c/common/constants.c + create mode 100644 c/common/context.c + create mode 100644 c/common/platform.c + create mode 100644 c/enc/command.c + create mode 100644 c/enc/fast_log.c + +Index: brotli-1.0.7/.travis.yml +=================================================================== +--- brotli-1.0.7.orig/.travis.yml ++++ brotli-1.0.7/.travis.yml +@@ -92,8 +92,9 @@ matrix: + ### + ## PGI Community Edition on Linux + ### +- - os: linux +- env: BUILD_SYSTEM=cmake C_COMPILER=pgcc CXX_COMPILER=pgc++ ++ # Installer is currently broken ++ #- os: linux ++ # env: BUILD_SYSTEM=cmake C_COMPILER=pgcc CXX_COMPILER=pgc++ + + ### + ## Python 2.7 and 3.6 builds on Linux +Index: brotli-1.0.7/c/common/constants.c +=================================================================== +--- /dev/null ++++ brotli-1.0.7/c/common/constants.c +@@ -0,0 +1,15 @@ ++/* Copyright 2013 Google Inc. All Rights Reserved. ++ ++ Distributed under MIT license. ++ See file LICENSE for detail or copy at https://opensource.org/licenses/MIT ++*/ ++ ++#include "./constants.h" ++ ++const BrotliPrefixCodeRange ++ _kBrotliPrefixCodeRanges[BROTLI_NUM_BLOCK_LEN_SYMBOLS] = { ++ {1, 2}, {5, 2}, {9, 2}, {13, 2}, {17, 3}, {25, 3}, ++ {33, 3}, {41, 3}, {49, 4}, {65, 4}, {81, 4}, {97, 4}, ++ {113, 5}, {145, 5}, {177, 5}, {209, 5}, {241, 6}, {305, 6}, ++ {369, 7}, {497, 8}, {753, 9}, {1265, 10}, {2289, 11}, {4337, 12}, ++ {8433, 13}, {16625, 24}}; +Index: brotli-1.0.7/c/common/constants.h +=================================================================== +--- brotli-1.0.7.orig/c/common/constants.h ++++ brotli-1.0.7/c/common/constants.h +@@ -7,6 +7,8 @@ + #ifndef BROTLI_COMMON_CONSTANTS_H_ + #define BROTLI_COMMON_CONSTANTS_H_ + ++#include ++ + /* Specification: 7.3. Encoding of the context map */ + #define BROTLI_CONTEXT_MAP_MAX_RLE 16 + +@@ -48,6 +50,10 @@ + #define BROTLI_MAX_DISTANCE 0x3FFFFFC + #define BROTLI_MAX_ALLOWED_DISTANCE 0x7FFFFFFC + ++ ++/* Specification: 4. Encoding of Literal Insertion Lengths and Copy Lengths */ ++#define BROTLI_NUM_INS_COPY_CODES 24 ++ + /* 7.1. Context modes and context ID lookup for literals */ + /* "context IDs for literals are in the range of 0..63" */ + #define BROTLI_LITERAL_CONTEXT_BITS 6 +@@ -61,4 +67,16 @@ + #define BROTLI_WINDOW_GAP 16 + #define BROTLI_MAX_BACKWARD_LIMIT(W) (((size_t)1 << (W)) - BROTLI_WINDOW_GAP) + ++#include ++/* Represents the range of values belonging to a prefix code: ++ [offset, offset + 2^nbits) */ ++typedef struct { ++ uint16_t offset; ++ uint8_t nbits; ++} BrotliPrefixCodeRange; ++ ++/* "Soft-private", it is exported, but not "advertised" as API. */ ++BROTLI_COMMON_API extern const BrotliPrefixCodeRange ++ _kBrotliPrefixCodeRanges[BROTLI_NUM_BLOCK_LEN_SYMBOLS]; ++ + #endif /* BROTLI_COMMON_CONSTANTS_H_ */ +Index: brotli-1.0.7/c/common/context.c +=================================================================== +--- /dev/null ++++ brotli-1.0.7/c/common/context.c +@@ -0,0 +1,156 @@ ++#include "./context.h" ++ ++#include ++ ++/* Common context lookup table for all context modes. */ ++const uint8_t _kBrotliContextLookupTable[2048] = { ++ /* CONTEXT_LSB6, last byte. */ ++ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ++ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, ++ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, ++ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, ++ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ++ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, ++ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, ++ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, ++ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ++ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, ++ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, ++ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, ++ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ++ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, ++ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, ++ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, ++ ++ /* CONTEXT_LSB6, second last byte, */ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ ++ /* CONTEXT_MSB6, last byte. */ ++ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, ++ 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, ++ 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, ++ 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, ++ 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, ++ 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, ++ 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, ++ 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, ++ 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, ++ 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, ++ 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, ++ 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, ++ 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, ++ 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, ++ 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, ++ 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63, ++ ++ /* CONTEXT_MSB6, second last byte, */ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ ++ /* CONTEXT_UTF8, last byte. */ ++ /* ASCII range. */ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12, ++ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12, ++ 12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48, ++ 52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12, ++ 12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56, ++ 60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0, ++ /* UTF8 continuation byte range. */ ++ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, ++ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, ++ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, ++ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, ++ /* UTF8 lead byte range. */ ++ 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, ++ 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, ++ 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, ++ 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, ++ ++ /* CONTEXT_UTF8 second last byte. */ ++ /* ASCII range. */ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, ++ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, ++ 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, ++ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0, ++ /* UTF8 continuation byte range. */ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ /* UTF8 lead byte range. */ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ ++ /* CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits. */ ++ 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, ++ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, ++ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, ++ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, ++ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, ++ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, ++ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, ++ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, ++ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, ++ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, ++ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, ++ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, ++ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56, ++ ++ /* CONTEXT_SIGNED, second last byte. */ ++ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ++ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, ++ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, ++ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, ++ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, ++ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, ++ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, ++ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, ++ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, ++ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ++ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ++ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ++ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, ++}; +Index: brotli-1.0.7/c/common/context.h +=================================================================== +--- brotli-1.0.7.orig/c/common/context.h ++++ brotli-1.0.7/c/common/context.h +@@ -88,6 +88,7 @@ + #ifndef BROTLI_COMMON_CONTEXT_H_ + #define BROTLI_COMMON_CONTEXT_H_ + ++#include + #include + + typedef enum ContextType { +@@ -97,163 +98,14 @@ typedef enum ContextType { + CONTEXT_SIGNED = 3 + } ContextType; + ++/* "Soft-private", it is exported, but not "advertised" as API. */ + /* Common context lookup table for all context modes. */ +-static const uint8_t kContextLookup[2048] = { +- /* CONTEXT_LSB6, last byte. */ +- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, +- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, +- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, +- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, +- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, +- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, +- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, +- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, +- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, +- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, +- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, +- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, +- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, +- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, +- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, +- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, +- +- /* CONTEXT_LSB6, second last byte, */ +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- +- /* CONTEXT_MSB6, last byte. */ +- 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, +- 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, +- 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, +- 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, +- 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, +- 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, +- 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, +- 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, +- 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, +- 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, +- 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, +- 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, +- 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, +- 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, +- 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, +- 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63, +- +- /* CONTEXT_MSB6, second last byte, */ +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- +- /* CONTEXT_UTF8, last byte. */ +- /* ASCII range. */ +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12, +- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12, +- 12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48, +- 52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12, +- 12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56, +- 60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0, +- /* UTF8 continuation byte range. */ +- 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, +- 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, +- 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, +- 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, +- /* UTF8 lead byte range. */ +- 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, +- 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, +- 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, +- 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, +- +- /* CONTEXT_UTF8 second last byte. */ +- /* ASCII range. */ +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, +- 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, +- 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0, +- /* UTF8 continuation byte range. */ +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- /* UTF8 lead byte range. */ +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- +- /* CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits. */ +- 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +- 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +- 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +- 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +- 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, +- 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56, +- +- /* CONTEXT_SIGNED, second last byte. */ +- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, +-}; ++BROTLI_COMMON_API extern const uint8_t _kBrotliContextLookupTable[2048]; + + typedef const uint8_t* ContextLut; + + /* typeof(MODE) == ContextType; returns ContextLut */ +-#define BROTLI_CONTEXT_LUT(MODE) (&kContextLookup[(MODE) << 9]) ++#define BROTLI_CONTEXT_LUT(MODE) (&_kBrotliContextLookupTable[(MODE) << 9]) + + /* typeof(LUT) == ContextLut */ + #define BROTLI_CONTEXT(P1, P2, LUT) ((LUT)[P1] | ((LUT) + 256)[P2]) +Index: brotli-1.0.7/c/common/platform.c +=================================================================== +--- /dev/null ++++ brotli-1.0.7/c/common/platform.c +@@ -0,0 +1,22 @@ ++/* Copyright 2016 Google Inc. All Rights Reserved. ++ ++ Distributed under MIT license. ++ See file LICENSE for detail or copy at https://opensource.org/licenses/MIT ++*/ ++ ++#include ++ ++#include "./platform.h" ++#include ++ ++/* Default brotli_alloc_func */ ++void* BrotliDefaultAllocFunc(void* opaque, size_t size) { ++ BROTLI_UNUSED(opaque); ++ return malloc(size); ++} ++ ++/* Default brotli_free_func */ ++void BrotliDefaultFreeFunc(void* opaque, void* address) { ++ BROTLI_UNUSED(opaque); ++ free(address); ++} +Index: brotli-1.0.7/c/common/platform.h +=================================================================== +--- brotli-1.0.7.orig/c/common/platform.h ++++ brotli-1.0.7/c/common/platform.h +@@ -24,7 +24,6 @@ + #define BROTLI_COMMON_PLATFORM_H_ + + #include /* memcpy */ +-#include /* malloc, free */ + + #include + #include +@@ -524,16 +523,10 @@ BROTLI_MIN_MAX(size_t) BROTLI_MIN_MAX(ui + } + + /* Default brotli_alloc_func */ +-static void* BrotliDefaultAllocFunc(void* opaque, size_t size) { +- BROTLI_UNUSED(opaque); +- return malloc(size); +-} ++BROTLI_COMMON_API void* BrotliDefaultAllocFunc(void* opaque, size_t size); + + /* Default brotli_free_func */ +-static void BrotliDefaultFreeFunc(void* opaque, void* address) { +- BROTLI_UNUSED(opaque); +- free(address); +-} ++BROTLI_COMMON_API void BrotliDefaultFreeFunc(void* opaque, void* address); + + BROTLI_UNUSED_FUNCTION void BrotliSuppressUnusedFunctions(void) { + BROTLI_UNUSED(&BrotliSuppressUnusedFunctions); +Index: brotli-1.0.7/c/dec/bit_reader.c +=================================================================== +--- brotli-1.0.7.orig/c/dec/bit_reader.c ++++ brotli-1.0.7/c/dec/bit_reader.c +@@ -15,6 +15,17 @@ + extern "C" { + #endif + ++const uint32_t kBrotliBitMask[33] = { 0x00000000, ++ 0x00000001, 0x00000003, 0x00000007, 0x0000000F, ++ 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, ++ 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, ++ 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, ++ 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, ++ 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF, ++ 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, ++ 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF ++}; ++ + void BrotliInitBitReader(BrotliBitReader* const br) { + br->val_ = 0; + br->bit_pos_ = sizeof(br->val_) << 3; +Index: brotli-1.0.7/c/dec/bit_reader.h +=================================================================== +--- brotli-1.0.7.orig/c/dec/bit_reader.h ++++ brotli-1.0.7/c/dec/bit_reader.h +@@ -11,6 +11,7 @@ + + #include /* memcpy */ + ++#include "../common/constants.h" + #include "../common/platform.h" + #include + +@@ -20,16 +21,7 @@ extern "C" { + + #define BROTLI_SHORT_FILL_BIT_WINDOW_READ (sizeof(brotli_reg_t) >> 1) + +-static const uint32_t kBitMask[33] = { 0x00000000, +- 0x00000001, 0x00000003, 0x00000007, 0x0000000F, +- 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, +- 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, +- 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, +- 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, +- 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF, +- 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, +- 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF +-}; ++BROTLI_INTERNAL extern const uint32_t kBrotliBitMask[33]; + + static BROTLI_INLINE uint32_t BitMask(uint32_t n) { + if (BROTLI_IS_CONSTANT(n) || BROTLI_HAS_UBFX) { +@@ -37,7 +29,7 @@ static BROTLI_INLINE uint32_t BitMask(ui + "Unsigned Bit Field Extract" UBFX instruction on ARM. */ + return ~((0xFFFFFFFFu) << n); + } else { +- return kBitMask[n]; ++ return kBrotliBitMask[n]; + } + } + +@@ -87,8 +79,11 @@ static BROTLI_INLINE uint32_t BrotliGetA + } + + /* Returns amount of unread bytes the bit reader still has buffered from the +- BrotliInput, including whole bytes in br->val_. */ ++ BrotliInput, including whole bytes in br->val_. Result is capped with ++ maximal ring-buffer size (larger number won't be utilized anyway). */ + static BROTLI_INLINE size_t BrotliGetRemainingBytes(BrotliBitReader* br) { ++ static const size_t kCap = (size_t)1 << BROTLI_LARGE_MAX_WBITS; ++ if (br->avail_in > kCap) return kCap; + return br->avail_in + (BrotliGetAvailableBits(br) >> 3); + } + +Index: brotli-1.0.7/c/dec/decode.c +=================================================================== +--- brotli-1.0.7.orig/c/dec/decode.c ++++ brotli-1.0.7/c/dec/decode.c +@@ -867,8 +867,9 @@ static BROTLI_INLINE uint32_t ReadBlockL + uint32_t code; + uint32_t nbits; + code = ReadSymbol(table, br); +- nbits = kBlockLengthPrefixCode[code].nbits; /* nbits == 2..24 */ +- return kBlockLengthPrefixCode[code].offset + BrotliReadBits(br, nbits); ++ nbits = _kBrotliPrefixCodeRanges[code].nbits; /* nbits == 2..24 */ ++ BROTLI_DCHECK(nbits <= 24); ++ return _kBrotliPrefixCodeRanges[code].offset + BrotliReadBits(br, nbits); + } + + /* WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then +@@ -886,13 +886,14 @@ static BROTLI_INLINE BROTLI_BOOL SafeRea + } + { + uint32_t bits; +- uint32_t nbits = kBlockLengthPrefixCode[index].nbits; /* nbits == 2..24 */ ++ uint32_t nbits = _kBrotliPrefixCodeRanges[index].nbits; ++ uint32_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; + return BROTLI_FALSE; + } +- *result = kBlockLengthPrefixCode[index].offset + bits; ++ *result = offset + bits; + s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE; + return BROTLI_TRUE; + } +Index: brotli-1.0.7/c/dec/huffman.h +=================================================================== +--- brotli-1.0.7.orig/c/dec/huffman.h ++++ brotli-1.0.7/c/dec/huffman.h +@@ -18,12 +18,6 @@ extern "C" { + + #define BROTLI_HUFFMAN_MAX_CODE_LENGTH 15 + +-/* Maximum possible Huffman table size for an alphabet size of (index * 32), +- max code length 15 and root table bits 8. */ +-static const uint16_t kMaxHuffmanTableSize[] = { +- 256, 402, 436, 468, 500, 534, 566, 598, 630, 662, 694, 726, 758, 790, 822, +- 854, 886, 920, 952, 984, 1016, 1048, 1080, 1112, 1144, 1176, 1208, 1240, 1272, +- 1304, 1336, 1368, 1400, 1432, 1464, 1496, 1528}; + /* BROTLI_NUM_BLOCK_LEN_SYMBOLS == 26 */ + #define BROTLI_HUFFMAN_MAX_SIZE_26 396 + /* BROTLI_MAX_BLOCK_TYPE_SYMBOLS == 258 */ +@@ -100,7 +94,7 @@ BROTLI_INTERNAL void BrotliBuildCodeLeng + /* Builds Huffman lookup table assuming code lengths are in symbol order. + Returns size of resulting table. */ + BROTLI_INTERNAL uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table, +- int root_bits, const uint16_t* const symbol_lists, uint16_t* count_arg); ++ int root_bits, const uint16_t* const symbol_lists, uint16_t* count); + + /* Builds a simple Huffman table. The |num_symbols| parameter is to be + interpreted as follows: 0 means 1 symbol, 1 means 2 symbols, +Index: brotli-1.0.7/c/dec/prefix.h +=================================================================== +--- brotli-1.0.7.orig/c/dec/prefix.h ++++ brotli-1.0.7/c/dec/prefix.h +@@ -13,24 +13,6 @@ + #include "../common/constants.h" + #include + +-/* Represents the range of values belonging to a prefix code: +- [offset, offset + 2^nbits) */ +-struct PrefixCodeRange { +- uint16_t offset; +- uint8_t nbits; +-}; +- +-static const struct PrefixCodeRange +- kBlockLengthPrefixCode[BROTLI_NUM_BLOCK_LEN_SYMBOLS] = { +- { 1, 2}, { 5, 2}, { 9, 2}, { 13, 2}, +- { 17, 3}, { 25, 3}, { 33, 3}, { 41, 3}, +- { 49, 4}, { 65, 4}, { 81, 4}, { 97, 4}, +- { 113, 5}, { 145, 5}, { 177, 5}, { 209, 5}, +- { 241, 6}, { 305, 6}, { 369, 7}, { 497, 8}, +- { 753, 9}, { 1265, 10}, {2289, 11}, {4337, 12}, +- {8433, 13}, {16625, 24} +-}; +- + typedef struct CmdLutElement { + uint8_t insert_len_extra_bits; + uint8_t copy_len_extra_bits; +Index: brotli-1.0.7/c/dec/state.c +=================================================================== +--- brotli-1.0.7.orig/c/dec/state.c ++++ brotli-1.0.7/c/dec/state.c +@@ -144,8 +144,11 @@ void BrotliDecoderStateCleanup(BrotliDec + BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s, + HuffmanTreeGroup* group, uint32_t alphabet_size, uint32_t max_symbol, + uint32_t ntrees) { +- /* Pack two allocations into one */ +- const size_t max_table_size = kMaxHuffmanTableSize[(alphabet_size + 31) >> 5]; ++ /* 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 ++ less than 16 symbols). */ ++ const size_t max_table_size = max_symbol + 376; + const size_t code_size = sizeof(HuffmanCode) * ntrees * max_table_size; + const size_t htree_size = sizeof(HuffmanCode*) * ntrees; + /* Pointer alignment is, hopefully, wider than sizeof(HuffmanCode). */ +Index: brotli-1.0.7/c/enc/brotli_bit_stream.c +=================================================================== +--- brotli-1.0.7.orig/c/enc/brotli_bit_stream.c ++++ brotli-1.0.7/c/enc/brotli_bit_stream.c +@@ -34,33 +34,18 @@ extern "C" { + BROTLI_DISTANCE_ALPHABET_SIZE(0, 0, BROTLI_LARGE_MAX_DISTANCE_BITS) + /* MAX_SIMPLE_DISTANCE_ALPHABET_SIZE == 140 */ + +-/* Represents the range of values belonging to a prefix code: +- [offset, offset + 2^nbits) */ +-typedef struct PrefixCodeRange { +- uint32_t offset; +- uint32_t nbits; +-} PrefixCodeRange; +- +-static const PrefixCodeRange +- kBlockLengthPrefixCode[BROTLI_NUM_BLOCK_LEN_SYMBOLS] = { +- { 1, 2}, { 5, 2}, { 9, 2}, {13, 2}, {17, 3}, { 25, 3}, { 33, 3}, +- {41, 3}, {49, 4}, {65, 4}, {81, 4}, {97, 4}, {113, 5}, {145, 5}, +- {177, 5}, { 209, 5}, { 241, 6}, { 305, 6}, { 369, 7}, { 497, 8}, +- {753, 9}, {1265, 10}, {2289, 11}, {4337, 12}, {8433, 13}, {16625, 24} +-}; +- + static BROTLI_INLINE uint32_t BlockLengthPrefixCode(uint32_t len) { + uint32_t code = (len >= 177) ? (len >= 753 ? 20 : 14) : (len >= 41 ? 7 : 0); + while (code < (BROTLI_NUM_BLOCK_LEN_SYMBOLS - 1) && +- len >= kBlockLengthPrefixCode[code + 1].offset) ++code; ++ len >= _kBrotliPrefixCodeRanges[code + 1].offset) ++code; + return code; + } + + static BROTLI_INLINE void GetBlockLengthPrefixCode(uint32_t len, size_t* code, + uint32_t* n_extra, uint32_t* extra) { + *code = BlockLengthPrefixCode(len); +- *n_extra = kBlockLengthPrefixCode[*code].nbits; +- *extra = len - kBlockLengthPrefixCode[*code].offset; ++ *n_extra = _kBrotliPrefixCodeRanges[*code].nbits; ++ *extra = len - _kBrotliPrefixCodeRanges[*code].offset; + } + + typedef struct BlockTypeCodeCalculator { +Index: brotli-1.0.7/c/enc/command.c +=================================================================== +--- /dev/null ++++ brotli-1.0.7/c/enc/command.c +@@ -0,0 +1,28 @@ ++/* Copyright 2013 Google Inc. All Rights Reserved. ++ ++ Distributed under MIT license. ++ See file LICENSE for detail or copy at https://opensource.org/licenses/MIT ++*/ ++ ++#include "./command.h" ++ ++#include ++ ++#if defined(__cplusplus) || defined(c_plusplus) ++extern "C" { ++#endif ++ ++const uint32_t kBrotliInsBase[BROTLI_NUM_INS_COPY_CODES] = { ++ 0, 1, 2, 3, 4, 5, 6, 8, 10, 14, 18, 26, ++ 34, 50, 66, 98, 130, 194, 322, 578, 1090, 2114, 6210, 22594}; ++const uint32_t kBrotliInsExtra[BROTLI_NUM_INS_COPY_CODES] = { ++ 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 12, 14, 24}; ++const uint32_t kBrotliCopyBase[BROTLI_NUM_INS_COPY_CODES] = { ++ 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 18, ++ 22, 30, 38, 54, 70, 102, 134, 198, 326, 582, 1094, 2118}; ++const uint32_t kBrotliCopyExtra[BROTLI_NUM_INS_COPY_CODES] = { ++ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 24}; ++ ++#if defined(__cplusplus) || defined(c_plusplus) ++} /* extern "C" */ ++#endif +Index: brotli-1.0.7/c/enc/command.h +=================================================================== +--- brotli-1.0.7.orig/c/enc/command.h ++++ brotli-1.0.7/c/enc/command.h +@@ -20,14 +20,14 @@ + extern "C" { + #endif + +-static uint32_t kInsBase[] = { 0, 1, 2, 3, 4, 5, 6, 8, 10, 14, 18, 26, 34, 50, +- 66, 98, 130, 194, 322, 578, 1090, 2114, 6210, 22594 }; +-static uint32_t kInsExtra[] = { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, +- 5, 5, 6, 7, 8, 9, 10, 12, 14, 24 }; +-static uint32_t kCopyBase[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 18, 22, 30, +- 38, 54, 70, 102, 134, 198, 326, 582, 1094, 2118 }; +-static uint32_t kCopyExtra[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, +- 4, 4, 5, 5, 6, 7, 8, 9, 10, 24 }; ++BROTLI_INTERNAL extern const uint32_t ++ kBrotliInsBase[BROTLI_NUM_INS_COPY_CODES]; ++BROTLI_INTERNAL extern const uint32_t ++ kBrotliInsExtra[BROTLI_NUM_INS_COPY_CODES]; ++BROTLI_INTERNAL extern const uint32_t ++ kBrotliCopyBase[BROTLI_NUM_INS_COPY_CODES]; ++BROTLI_INTERNAL extern const uint32_t ++ kBrotliCopyExtra[BROTLI_NUM_INS_COPY_CODES]; + + static BROTLI_INLINE uint16_t GetInsertLengthCode(size_t insertlen) { + if (insertlen < 6) { +@@ -89,19 +89,19 @@ static BROTLI_INLINE void GetLengthCode( + } + + static BROTLI_INLINE uint32_t GetInsertBase(uint16_t inscode) { +- return kInsBase[inscode]; ++ return kBrotliInsBase[inscode]; + } + + static BROTLI_INLINE uint32_t GetInsertExtra(uint16_t inscode) { +- return kInsExtra[inscode]; ++ return kBrotliInsExtra[inscode]; + } + + static BROTLI_INLINE uint32_t GetCopyBase(uint16_t copycode) { +- return kCopyBase[copycode]; ++ return kBrotliCopyBase[copycode]; + } + + static BROTLI_INLINE uint32_t GetCopyExtra(uint16_t copycode) { +- return kCopyExtra[copycode]; ++ return kBrotliCopyExtra[copycode]; + } + + typedef struct Command { +Index: brotli-1.0.7/c/enc/entropy_encode.c +=================================================================== +--- brotli-1.0.7.orig/c/enc/entropy_encode.c ++++ brotli-1.0.7/c/enc/entropy_encode.c +@@ -18,6 +18,8 @@ + extern "C" { + #endif + ++const size_t kBrotliShellGaps[] = {132, 57, 23, 10, 4, 1}; ++ + BROTLI_BOOL BrotliSetDepth( + int p0, HuffmanTree* pool, uint8_t* depth, int max_depth) { + int stack[16]; +Index: brotli-1.0.7/c/enc/entropy_encode.h +=================================================================== +--- brotli-1.0.7.orig/c/enc/entropy_encode.h ++++ brotli-1.0.7/c/enc/entropy_encode.h +@@ -76,12 +76,12 @@ BROTLI_INTERNAL void BrotliConvertBitDep + size_t len, + uint16_t* bits); + ++BROTLI_INTERNAL extern const size_t kBrotliShellGaps[6]; + /* Input size optimized Shell sort. */ + typedef BROTLI_BOOL (*HuffmanTreeComparator)( + const HuffmanTree*, const HuffmanTree*); + static BROTLI_INLINE void SortHuffmanTreeItems(HuffmanTree* items, + const size_t n, HuffmanTreeComparator comparator) { +- static const size_t gaps[] = {132, 57, 23, 10, 4, 1}; + if (n < 13) { + /* Insertion sort. */ + size_t i; +@@ -101,7 +101,7 @@ static BROTLI_INLINE void SortHuffmanTre + /* Shell sort. */ + int g = n < 57 ? 2 : 0; + for (; g < 6; ++g) { +- size_t gap = gaps[g]; ++ size_t gap = kBrotliShellGaps[g]; + size_t i; + for (i = gap; i < n; ++i) { + size_t j = i; +Index: brotli-1.0.7/c/enc/fast_log.c +=================================================================== +--- /dev/null ++++ brotli-1.0.7/c/enc/fast_log.c +@@ -0,0 +1,105 @@ ++/* Copyright 2013 Google Inc. All Rights Reserved. ++ ++ Distributed under MIT license. ++ See file LICENSE for detail or copy at https://opensource.org/licenses/MIT ++*/ ++ ++#include "./fast_log.h" ++ ++#if defined(__cplusplus) || defined(c_plusplus) ++extern "C" { ++#endif ++ ++/* ", ".join(["%.16ff" % x for x in [0.0]+[log2(x) for x in range(1, 256)]]) */ ++const double kBrotliLog2Table[BROTLI_LOG2_TABLE_SIZE] = { ++ 0.0000000000000000f, 0.0000000000000000f, 1.0000000000000000f, ++ 1.5849625007211563f, 2.0000000000000000f, 2.3219280948873622f, ++ 2.5849625007211561f, 2.8073549220576042f, 3.0000000000000000f, ++ 3.1699250014423126f, 3.3219280948873626f, 3.4594316186372978f, ++ 3.5849625007211565f, 3.7004397181410922f, 3.8073549220576037f, ++ 3.9068905956085187f, 4.0000000000000000f, 4.0874628412503400f, ++ 4.1699250014423122f, 4.2479275134435852f, 4.3219280948873626f, ++ 4.3923174227787607f, 4.4594316186372973f, 4.5235619560570131f, ++ 4.5849625007211570f, 4.6438561897747244f, 4.7004397181410926f, ++ 4.7548875021634691f, 4.8073549220576037f, 4.8579809951275728f, ++ 4.9068905956085187f, 4.9541963103868758f, 5.0000000000000000f, ++ 5.0443941193584534f, 5.0874628412503400f, 5.1292830169449664f, ++ 5.1699250014423122f, 5.2094533656289501f, 5.2479275134435852f, ++ 5.2854022188622487f, 5.3219280948873626f, 5.3575520046180838f, ++ 5.3923174227787607f, 5.4262647547020979f, 5.4594316186372973f, ++ 5.4918530963296748f, 5.5235619560570131f, 5.5545888516776376f, ++ 5.5849625007211570f, 5.6147098441152083f, 5.6438561897747244f, ++ 5.6724253419714961f, 5.7004397181410926f, 5.7279204545631996f, ++ 5.7548875021634691f, 5.7813597135246599f, 5.8073549220576046f, ++ 5.8328900141647422f, 5.8579809951275719f, 5.8826430493618416f, ++ 5.9068905956085187f, 5.9307373375628867f, 5.9541963103868758f, ++ 5.9772799234999168f, 6.0000000000000000f, 6.0223678130284544f, ++ 6.0443941193584534f, 6.0660891904577721f, 6.0874628412503400f, ++ 6.1085244567781700f, 6.1292830169449672f, 6.1497471195046822f, ++ 6.1699250014423122f, 6.1898245588800176f, 6.2094533656289510f, ++ 6.2288186904958804f, 6.2479275134435861f, 6.2667865406949019f, ++ 6.2854022188622487f, 6.3037807481771031f, 6.3219280948873617f, ++ 6.3398500028846252f, 6.3575520046180847f, 6.3750394313469254f, ++ 6.3923174227787598f, 6.4093909361377026f, 6.4262647547020979f, ++ 6.4429434958487288f, 6.4594316186372982f, 6.4757334309663976f, ++ 6.4918530963296748f, 6.5077946401986964f, 6.5235619560570131f, ++ 6.5391588111080319f, 6.5545888516776376f, 6.5698556083309478f, ++ 6.5849625007211561f, 6.5999128421871278f, 6.6147098441152092f, ++ 6.6293566200796095f, 6.6438561897747253f, 6.6582114827517955f, ++ 6.6724253419714952f, 6.6865005271832185f, 6.7004397181410917f, ++ 6.7142455176661224f, 6.7279204545631988f, 6.7414669864011465f, ++ 6.7548875021634691f, 6.7681843247769260f, 6.7813597135246599f, ++ 6.7944158663501062f, 6.8073549220576037f, 6.8201789624151887f, ++ 6.8328900141647422f, 6.8454900509443757f, 6.8579809951275719f, ++ 6.8703647195834048f, 6.8826430493618416f, 6.8948177633079437f, ++ 6.9068905956085187f, 6.9188632372745955f, 6.9307373375628867f, ++ 6.9425145053392399f, 6.9541963103868758f, 6.9657842846620879f, ++ 6.9772799234999168f, 6.9886846867721664f, 7.0000000000000000f, ++ 7.0112272554232540f, 7.0223678130284544f, 7.0334230015374501f, ++ 7.0443941193584534f, 7.0552824355011898f, 7.0660891904577721f, ++ 7.0768155970508317f, 7.0874628412503400f, 7.0980320829605272f, ++ 7.1085244567781700f, 7.1189410727235076f, 7.1292830169449664f, ++ 7.1395513523987937f, 7.1497471195046822f, 7.1598713367783891f, ++ 7.1699250014423130f, 7.1799090900149345f, 7.1898245588800176f, ++ 7.1996723448363644f, 7.2094533656289492f, 7.2191685204621621f, ++ 7.2288186904958804f, 7.2384047393250794f, 7.2479275134435861f, ++ 7.2573878426926521f, 7.2667865406949019f, 7.2761244052742384f, ++ 7.2854022188622487f, 7.2946207488916270f, 7.3037807481771031f, ++ 7.3128829552843557f, 7.3219280948873617f, 7.3309168781146177f, ++ 7.3398500028846243f, 7.3487281542310781f, 7.3575520046180847f, ++ 7.3663222142458151f, 7.3750394313469254f, 7.3837042924740528f, ++ 7.3923174227787607f, 7.4008794362821844f, 7.4093909361377026f, ++ 7.4178525148858991f, 7.4262647547020979f, 7.4346282276367255f, ++ 7.4429434958487288f, 7.4512111118323299f, 7.4594316186372973f, ++ 7.4676055500829976f, 7.4757334309663976f, 7.4838157772642564f, ++ 7.4918530963296748f, 7.4998458870832057f, 7.5077946401986964f, ++ 7.5156998382840436f, 7.5235619560570131f, 7.5313814605163119f, ++ 7.5391588111080319f, 7.5468944598876373f, 7.5545888516776376f, ++ 7.5622424242210728f, 7.5698556083309478f, 7.5774288280357487f, ++ 7.5849625007211561f, 7.5924570372680806f, 7.5999128421871278f, ++ 7.6073303137496113f, 7.6147098441152075f, 7.6220518194563764f, ++ 7.6293566200796095f, 7.6366246205436488f, 7.6438561897747244f, ++ 7.6510516911789290f, 7.6582114827517955f, 7.6653359171851765f, ++ 7.6724253419714952f, 7.6794800995054464f, 7.6865005271832185f, ++ 7.6934869574993252f, 7.7004397181410926f, 7.7073591320808825f, ++ 7.7142455176661224f, 7.7210991887071856f, 7.7279204545631996f, ++ 7.7347096202258392f, 7.7414669864011465f, 7.7481928495894596f, ++ 7.7548875021634691f, 7.7615512324444795f, 7.7681843247769260f, ++ 7.7747870596011737f, 7.7813597135246608f, 7.7879025593914317f, ++ 7.7944158663501062f, 7.8008998999203047f, 7.8073549220576037f, ++ 7.8137811912170374f, 7.8201789624151887f, 7.8265484872909159f, ++ 7.8328900141647422f, 7.8392037880969445f, 7.8454900509443757f, ++ 7.8517490414160571f, 7.8579809951275719f, 7.8641861446542798f, ++ 7.8703647195834048f, 7.8765169465650002f, 7.8826430493618425f, ++ 7.8887432488982601f, 7.8948177633079446f, 7.9008668079807496f, ++ 7.9068905956085187f, 7.9128893362299619f, 7.9188632372745955f, ++ 7.9248125036057813f, 7.9307373375628867f, 7.9366379390025719f, ++ 7.9425145053392399f, 7.9483672315846778f, 7.9541963103868758f, ++ 7.9600019320680806f, 7.9657842846620870f, 7.9715435539507720f, ++ 7.9772799234999168f, 7.9829935746943104f, 7.9886846867721664f, ++ 7.9943534368588578f ++}; ++ ++#if defined(__cplusplus) || defined(c_plusplus) ++} /* extern "C" */ ++#endif +Index: brotli-1.0.7/c/enc/fast_log.h +=================================================================== +--- brotli-1.0.7.orig/c/enc/fast_log.h ++++ brotli-1.0.7/c/enc/fast_log.h +@@ -30,105 +30,18 @@ static BROTLI_INLINE uint32_t Log2FloorN + #endif + } + +-/* A lookup table for small values of log2(int) to be used in entropy +- computation. ++#define BROTLI_LOG2_TABLE_SIZE 256 + +- ", ".join(["%.16ff" % x for x in [0.0]+[log2(x) for x in range(1, 256)]]) */ +-static const float kLog2Table[] = { +- 0.0000000000000000f, 0.0000000000000000f, 1.0000000000000000f, +- 1.5849625007211563f, 2.0000000000000000f, 2.3219280948873622f, +- 2.5849625007211561f, 2.8073549220576042f, 3.0000000000000000f, +- 3.1699250014423126f, 3.3219280948873626f, 3.4594316186372978f, +- 3.5849625007211565f, 3.7004397181410922f, 3.8073549220576037f, +- 3.9068905956085187f, 4.0000000000000000f, 4.0874628412503400f, +- 4.1699250014423122f, 4.2479275134435852f, 4.3219280948873626f, +- 4.3923174227787607f, 4.4594316186372973f, 4.5235619560570131f, +- 4.5849625007211570f, 4.6438561897747244f, 4.7004397181410926f, +- 4.7548875021634691f, 4.8073549220576037f, 4.8579809951275728f, +- 4.9068905956085187f, 4.9541963103868758f, 5.0000000000000000f, +- 5.0443941193584534f, 5.0874628412503400f, 5.1292830169449664f, +- 5.1699250014423122f, 5.2094533656289501f, 5.2479275134435852f, +- 5.2854022188622487f, 5.3219280948873626f, 5.3575520046180838f, +- 5.3923174227787607f, 5.4262647547020979f, 5.4594316186372973f, +- 5.4918530963296748f, 5.5235619560570131f, 5.5545888516776376f, +- 5.5849625007211570f, 5.6147098441152083f, 5.6438561897747244f, +- 5.6724253419714961f, 5.7004397181410926f, 5.7279204545631996f, +- 5.7548875021634691f, 5.7813597135246599f, 5.8073549220576046f, +- 5.8328900141647422f, 5.8579809951275719f, 5.8826430493618416f, +- 5.9068905956085187f, 5.9307373375628867f, 5.9541963103868758f, +- 5.9772799234999168f, 6.0000000000000000f, 6.0223678130284544f, +- 6.0443941193584534f, 6.0660891904577721f, 6.0874628412503400f, +- 6.1085244567781700f, 6.1292830169449672f, 6.1497471195046822f, +- 6.1699250014423122f, 6.1898245588800176f, 6.2094533656289510f, +- 6.2288186904958804f, 6.2479275134435861f, 6.2667865406949019f, +- 6.2854022188622487f, 6.3037807481771031f, 6.3219280948873617f, +- 6.3398500028846252f, 6.3575520046180847f, 6.3750394313469254f, +- 6.3923174227787598f, 6.4093909361377026f, 6.4262647547020979f, +- 6.4429434958487288f, 6.4594316186372982f, 6.4757334309663976f, +- 6.4918530963296748f, 6.5077946401986964f, 6.5235619560570131f, +- 6.5391588111080319f, 6.5545888516776376f, 6.5698556083309478f, +- 6.5849625007211561f, 6.5999128421871278f, 6.6147098441152092f, +- 6.6293566200796095f, 6.6438561897747253f, 6.6582114827517955f, +- 6.6724253419714952f, 6.6865005271832185f, 6.7004397181410917f, +- 6.7142455176661224f, 6.7279204545631988f, 6.7414669864011465f, +- 6.7548875021634691f, 6.7681843247769260f, 6.7813597135246599f, +- 6.7944158663501062f, 6.8073549220576037f, 6.8201789624151887f, +- 6.8328900141647422f, 6.8454900509443757f, 6.8579809951275719f, +- 6.8703647195834048f, 6.8826430493618416f, 6.8948177633079437f, +- 6.9068905956085187f, 6.9188632372745955f, 6.9307373375628867f, +- 6.9425145053392399f, 6.9541963103868758f, 6.9657842846620879f, +- 6.9772799234999168f, 6.9886846867721664f, 7.0000000000000000f, +- 7.0112272554232540f, 7.0223678130284544f, 7.0334230015374501f, +- 7.0443941193584534f, 7.0552824355011898f, 7.0660891904577721f, +- 7.0768155970508317f, 7.0874628412503400f, 7.0980320829605272f, +- 7.1085244567781700f, 7.1189410727235076f, 7.1292830169449664f, +- 7.1395513523987937f, 7.1497471195046822f, 7.1598713367783891f, +- 7.1699250014423130f, 7.1799090900149345f, 7.1898245588800176f, +- 7.1996723448363644f, 7.2094533656289492f, 7.2191685204621621f, +- 7.2288186904958804f, 7.2384047393250794f, 7.2479275134435861f, +- 7.2573878426926521f, 7.2667865406949019f, 7.2761244052742384f, +- 7.2854022188622487f, 7.2946207488916270f, 7.3037807481771031f, +- 7.3128829552843557f, 7.3219280948873617f, 7.3309168781146177f, +- 7.3398500028846243f, 7.3487281542310781f, 7.3575520046180847f, +- 7.3663222142458151f, 7.3750394313469254f, 7.3837042924740528f, +- 7.3923174227787607f, 7.4008794362821844f, 7.4093909361377026f, +- 7.4178525148858991f, 7.4262647547020979f, 7.4346282276367255f, +- 7.4429434958487288f, 7.4512111118323299f, 7.4594316186372973f, +- 7.4676055500829976f, 7.4757334309663976f, 7.4838157772642564f, +- 7.4918530963296748f, 7.4998458870832057f, 7.5077946401986964f, +- 7.5156998382840436f, 7.5235619560570131f, 7.5313814605163119f, +- 7.5391588111080319f, 7.5468944598876373f, 7.5545888516776376f, +- 7.5622424242210728f, 7.5698556083309478f, 7.5774288280357487f, +- 7.5849625007211561f, 7.5924570372680806f, 7.5999128421871278f, +- 7.6073303137496113f, 7.6147098441152075f, 7.6220518194563764f, +- 7.6293566200796095f, 7.6366246205436488f, 7.6438561897747244f, +- 7.6510516911789290f, 7.6582114827517955f, 7.6653359171851765f, +- 7.6724253419714952f, 7.6794800995054464f, 7.6865005271832185f, +- 7.6934869574993252f, 7.7004397181410926f, 7.7073591320808825f, +- 7.7142455176661224f, 7.7210991887071856f, 7.7279204545631996f, +- 7.7347096202258392f, 7.7414669864011465f, 7.7481928495894596f, +- 7.7548875021634691f, 7.7615512324444795f, 7.7681843247769260f, +- 7.7747870596011737f, 7.7813597135246608f, 7.7879025593914317f, +- 7.7944158663501062f, 7.8008998999203047f, 7.8073549220576037f, +- 7.8137811912170374f, 7.8201789624151887f, 7.8265484872909159f, +- 7.8328900141647422f, 7.8392037880969445f, 7.8454900509443757f, +- 7.8517490414160571f, 7.8579809951275719f, 7.8641861446542798f, +- 7.8703647195834048f, 7.8765169465650002f, 7.8826430493618425f, +- 7.8887432488982601f, 7.8948177633079446f, 7.9008668079807496f, +- 7.9068905956085187f, 7.9128893362299619f, 7.9188632372745955f, +- 7.9248125036057813f, 7.9307373375628867f, 7.9366379390025719f, +- 7.9425145053392399f, 7.9483672315846778f, 7.9541963103868758f, +- 7.9600019320680806f, 7.9657842846620870f, 7.9715435539507720f, +- 7.9772799234999168f, 7.9829935746943104f, 7.9886846867721664f, +- 7.9943534368588578f +-}; ++/* A lookup table for small values of log2(int) to be used in entropy ++ computation. */ ++BROTLI_INTERNAL extern const double kBrotliLog2Table[BROTLI_LOG2_TABLE_SIZE]; + + #define LOG_2_INV 1.4426950408889634 + + /* Faster logarithm for small integers, with the property of log2(0) == 0. */ + static BROTLI_INLINE double FastLog2(size_t v) { +- if (v < sizeof(kLog2Table) / sizeof(kLog2Table[0])) { +- return kLog2Table[v]; ++ if (v < BROTLI_LOG2_TABLE_SIZE) { ++ return kBrotliLog2Table[v]; + } + #if (defined(_MSC_VER) && _MSC_VER <= 1700) || \ + (defined(__ANDROID_API__) && __ANDROID_API__ < 18) +Index: brotli-1.0.7/research/brotli_decoder.c +=================================================================== +--- brotli-1.0.7.orig/research/brotli_decoder.c ++++ brotli-1.0.7/research/brotli_decoder.c +@@ -38,6 +38,7 @@ void cleanup(Context* ctx) { + + void fail(Context* ctx, const char* message) { + fprintf(stderr, "%s\n", message); ++ cleanup(ctx); + exit(1); + } + +Index: brotli-1.0.7/research/draw_histogram.cc +=================================================================== +--- brotli-1.0.7.orig/research/draw_histogram.cc ++++ brotli-1.0.7/research/draw_histogram.cc +@@ -178,20 +178,23 @@ int main(int argc, char* argv[]) { + FILE* fin = fopen(argv[1], "r"); + FILE* fout = fopen(argv[2], "wb"); + +- uint8_t** pixel = new uint8_t*[height]; +- int** histo = new int*[height]; +- for (int i = 0; i < height; i++) { +- pixel[i] = new uint8_t[width]; +- histo[i] = new int[width]; +- } ++ if (fin != nullptr && fout != nullptr) { ++ uint8_t** pixel = new uint8_t*[height]; ++ int** histo = new int*[height]; ++ for (int i = 0; i < height; i++) { ++ pixel[i] = new uint8_t[width]; ++ histo[i] = new int[width]; ++ } ++ ++ BuildHistogram(fin, histo); + +- BuildHistogram(fin, histo); +- fclose(fin); ++ ConvertToPixels(histo, pixel); + +- ConvertToPixels(histo, pixel); ++ DrawPixels(pixel, fout); ++ } + +- DrawPixels(pixel, fout); +- fclose(fout); ++ if (fin) fclose(fin); ++ if (fout) fclose(fout); + + return 0; + } +Index: brotli-1.0.7/scripts/.bintray.json +=================================================================== +--- brotli-1.0.7.orig/scripts/.bintray.json ++++ brotli-1.0.7/scripts/.bintray.json +@@ -5,7 +5,7 @@ + "subject": "eustas" + }, + +- "version": {"name": "snapshot"}, ++ "version": {"name": "latest"}, + + "files": [ + { +Index: brotli-1.0.7/scripts/sources.lst +=================================================================== +--- brotli-1.0.7.orig/scripts/sources.lst ++++ brotli-1.0.7/scripts/sources.lst +@@ -5,7 +5,10 @@ BROTLI_CLI_C = \ + c/tools/brotli.c + + BROTLI_COMMON_C = \ ++ c/common/constants.c \ ++ c/common/context.c \ + c/common/dictionary.c \ ++ c/common/platform.c \ + c/common/transform.c + + BROTLI_COMMON_H = \ +@@ -35,12 +38,14 @@ BROTLI_ENC_C = \ + c/enc/block_splitter.c \ + c/enc/brotli_bit_stream.c \ + c/enc/cluster.c \ ++ c/enc/command.c \ + c/enc/compress_fragment.c \ + c/enc/compress_fragment_two_pass.c \ + c/enc/dictionary_hash.c \ + c/enc/encode.c \ + c/enc/encoder_dict.c \ + c/enc/entropy_encode.c \ ++ c/enc/fast_log.c \ + c/enc/histogram.c \ + c/enc/literal_cost.c \ + c/enc/memory.c \ +Index: brotli-1.0.7/setup.py +=================================================================== +--- brotli-1.0.7.orig/setup.py ++++ brotli-1.0.7/setup.py +@@ -181,7 +181,10 @@ EXT_MODULES = [ + '_brotli', + sources=[ + 'python/_brotli.cc', ++ 'c/common/constants.c', ++ 'c/common/context.c', + 'c/common/dictionary.c', ++ 'c/common/platform.c', + 'c/common/transform.c', + 'c/dec/bit_reader.c', + 'c/dec/decode.c', +@@ -193,12 +196,14 @@ EXT_MODULES = [ + 'c/enc/block_splitter.c', + 'c/enc/brotli_bit_stream.c', + 'c/enc/cluster.c', ++ 'c/enc/command.c', + 'c/enc/compress_fragment.c', + 'c/enc/compress_fragment_two_pass.c', + 'c/enc/dictionary_hash.c', + 'c/enc/encode.c', + 'c/enc/encoder_dict.c', + 'c/enc/entropy_encode.c', ++ 'c/enc/fast_log.c', + 'c/enc/histogram.c', + 'c/enc/literal_cost.c', + 'c/enc/memory.c',