mirror of
https://github.com/cuberite/libdeflate.git
synced 2025-09-09 04:05:12 -04:00
lib: optimize decompressing repeated static Huffman blocks
Improve libdeflate's worst-case performance decompressing malicious DEFLATE streams by about 14x, bringing it within a factor of about 2x of zlib, by skipping rebuilding the decode tables for the static Huffman codes when they're already loaded into the decompressor. This improves performance decompressing a stream of all empty static Huffman blocks from about 0.36 MB/s to 175 MB/s, or the original reproducer given on the Github issue from about 3.3 MB/s to 219 MB/s. A regression test is added for these cases as well as the empty dynamic Huffman blocks case to verify worst-case performance comparable to zlib. Resolves https://github.com/ebiggers/libdeflate/issues/33
This commit is contained in:
parent
dd1c157750
commit
57cab078f1
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,5 +16,6 @@
|
||||
/gunzip
|
||||
/run_tests.log
|
||||
/test_checksums
|
||||
/test_slow_decompression
|
||||
tags
|
||||
cscope*
|
||||
|
6
Makefile
6
Makefile
@ -166,8 +166,10 @@ PROG_CFLAGS += $(CFLAGS) \
|
||||
PROG_COMMON_HEADERS := programs/prog_util.h programs/config.h
|
||||
PROG_COMMON_SRC := programs/prog_util.c programs/tgetopt.c
|
||||
NONTEST_PROGRAM_SRC := programs/gzip.c
|
||||
TEST_PROGRAM_SRC := programs/benchmark.c programs/test_checksums.c \
|
||||
programs/checksum.c
|
||||
TEST_PROGRAM_SRC := programs/benchmark.c \
|
||||
programs/checksum.c \
|
||||
programs/test_checksums.c \
|
||||
programs/test_slow_decompression.c
|
||||
|
||||
NONTEST_PROGRAMS := $(NONTEST_PROGRAM_SRC:programs/%.c=%$(PROG_SUFFIX))
|
||||
DEFAULT_TARGETS += $(NONTEST_PROGRAMS)
|
||||
|
@ -89,6 +89,8 @@ next_block:
|
||||
STATIC_ASSERT(DEFLATE_NUM_PRECODE_SYMS == ((1 << 4) - 1) + 4);
|
||||
num_explicit_precode_lens = POP_BITS(4) + 4;
|
||||
|
||||
d->static_codes_loaded = false;
|
||||
|
||||
/* Read the precode codeword lengths. */
|
||||
STATIC_ASSERT(DEFLATE_MAX_PRE_CODEWORD_LEN == (1 << 3) - 1);
|
||||
if (CAN_ENSURE(DEFLATE_NUM_PRECODE_SYMS * 3)) {
|
||||
@ -217,9 +219,20 @@ next_block:
|
||||
} else {
|
||||
SAFETY_CHECK(block_type == DEFLATE_BLOCKTYPE_STATIC_HUFFMAN);
|
||||
|
||||
/* Static Huffman block: set the static Huffman codeword
|
||||
* lengths. Then the remainder is the same as decompressing a
|
||||
* dynamic Huffman block. */
|
||||
/*
|
||||
* Static Huffman block: build the decode tables for the static
|
||||
* codes. Skip doing so if the tables are already set up from
|
||||
* an earlier static block; this speeds up decompression of
|
||||
* degenerate input of many empty or very short static blocks.
|
||||
*
|
||||
* Afterwards, the remainder is the same as decompressing a
|
||||
* dynamic Huffman block.
|
||||
*/
|
||||
|
||||
if (d->static_codes_loaded)
|
||||
goto have_decode_tables;
|
||||
|
||||
d->static_codes_loaded = true;
|
||||
|
||||
STATIC_ASSERT(DEFLATE_NUM_LITLEN_SYMS == 288);
|
||||
STATIC_ASSERT(DEFLATE_NUM_OFFSET_SYMS == 32);
|
||||
@ -238,13 +251,13 @@ next_block:
|
||||
|
||||
num_litlen_syms = 288;
|
||||
num_offset_syms = 32;
|
||||
|
||||
}
|
||||
|
||||
/* Decompressing a Huffman block (either dynamic or static) */
|
||||
|
||||
SAFETY_CHECK(build_offset_decode_table(d, num_litlen_syms, num_offset_syms));
|
||||
SAFETY_CHECK(build_litlen_decode_table(d, num_litlen_syms, num_offset_syms));
|
||||
have_decode_tables:
|
||||
|
||||
/* The main DEFLATE decode loop */
|
||||
for (;;) {
|
||||
|
@ -139,6 +139,8 @@ struct libdeflate_decompressor {
|
||||
|
||||
u16 working_space[2 * (DEFLATE_MAX_CODEWORD_LEN + 1) +
|
||||
DEFLATE_MAX_NUM_SYMS];
|
||||
|
||||
bool static_codes_loaded;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
@ -883,7 +885,15 @@ libdeflate_deflate_decompress(struct libdeflate_decompressor * restrict d,
|
||||
LIBDEFLATEAPI struct libdeflate_decompressor *
|
||||
libdeflate_alloc_decompressor(void)
|
||||
{
|
||||
return malloc(sizeof(struct libdeflate_decompressor));
|
||||
struct libdeflate_decompressor *d;
|
||||
|
||||
d = malloc(sizeof(*d));
|
||||
if (d == NULL)
|
||||
return NULL;
|
||||
|
||||
d->static_codes_loaded = false;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
LIBDEFLATEAPI void
|
||||
|
494
programs/test_slow_decompression.c
Normal file
494
programs/test_slow_decompression.c
Normal file
@ -0,0 +1,494 @@
|
||||
/*
|
||||
* test_slow_decompression.c
|
||||
*
|
||||
* Test how quickly libdeflate decompresses degenerate/malicious compressed data
|
||||
* streams that start new Huffman blocks extremely frequently.
|
||||
*/
|
||||
|
||||
#include <zlib.h> /* for comparison purposes */
|
||||
|
||||
#include "prog_util.h"
|
||||
|
||||
struct output_bitstream {
|
||||
unsigned long bitbuf;
|
||||
int bitcount;
|
||||
u8 *next;
|
||||
u8 *end;
|
||||
};
|
||||
|
||||
static bool
|
||||
put_bits(struct output_bitstream *os, unsigned long bits, int num_bits)
|
||||
{
|
||||
os->bitbuf |= bits << os->bitcount;
|
||||
os->bitcount += num_bits;
|
||||
while (os->bitcount >= 8) {
|
||||
if (os->next == os->end)
|
||||
return false;
|
||||
*os->next++ = os->bitbuf;
|
||||
os->bitcount -= 8;
|
||||
os->bitbuf >>= 8;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a DEFLATE stream containing all empty "static Huffman" blocks.
|
||||
*
|
||||
* libdeflate used to decompress this very slowly (~1000x slower than typical
|
||||
* data), but now it's much faster (only ~2x slower than typical data) because
|
||||
* now it skips rebuilding the decode tables for the static Huffman codes when
|
||||
* they're already loaded into the decompressor.
|
||||
*/
|
||||
static void
|
||||
generate_empty_static_huffman_blocks(u8 *p, size_t len)
|
||||
{
|
||||
struct output_bitstream os = { .next = p, .end = p + len };
|
||||
|
||||
while (put_bits(&os, 0, 1) && /* BFINAL: 0 */
|
||||
put_bits(&os, 1, 2) && /* BTYPE: STATIC_HUFFMAN */
|
||||
put_bits(&os, 0, 7)) /* litlensym_256 (end-of-block) */
|
||||
;
|
||||
}
|
||||
|
||||
static bool
|
||||
generate_empty_dynamic_huffman_block(struct output_bitstream *os)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!put_bits(os, 0, 1)) /* BFINAL: 0 */
|
||||
return false;
|
||||
if (!put_bits(os, 2, 2)) /* BTYPE: DYNAMIC_HUFFMAN */
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Write a minimal Huffman code, then the end-of-block symbol.
|
||||
*
|
||||
* Litlen code:
|
||||
* litlensym_256 (end-of-block) freq=1 len=1 codeword=0
|
||||
* Offset code:
|
||||
* offsetsym_0 (unused) freq=0 len=1 codeword=0
|
||||
*
|
||||
* Litlen and offset codeword lengths:
|
||||
* [0..255] = 0 presym_{18,18}
|
||||
* [256] = 1 presym_1
|
||||
* [257] = 1 presym_1
|
||||
*
|
||||
* Precode:
|
||||
* presym_1 freq=2 len=1 codeword=0
|
||||
* presym_18 freq=2 len=1 codeword=1
|
||||
*/
|
||||
|
||||
if (!put_bits(os, 0, 5)) /* num_litlen_syms: 0 + 257 */
|
||||
return false;
|
||||
if (!put_bits(os, 0, 5)) /* num_offset_syms: 0 + 1 */
|
||||
return false;
|
||||
if (!put_bits(os, 14, 4)) /* num_explicit_precode_lens: 14 + 4 */
|
||||
return false;
|
||||
/*
|
||||
* Precode codeword lengths: order is
|
||||
* [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]
|
||||
*/
|
||||
for (i = 0; i < 2; i++) { /* presym_{16,17}: len=0 */
|
||||
if (!put_bits(os, 0, 3))
|
||||
return false;
|
||||
}
|
||||
if (!put_bits(os, 1, 3)) /* presym_18: len=1 */
|
||||
return false;
|
||||
for (i = 0; i < 14; i++) { /* presym_{0,...,14}: len=0 */
|
||||
if (!put_bits(os, 0, 3))
|
||||
return false;
|
||||
}
|
||||
if (!put_bits(os, 1, 3)) /* presym_1: len=1 */
|
||||
return false;
|
||||
|
||||
/* Litlen and offset codeword lengths */
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (!put_bits(os, 1, 1) || /* presym_18, 128 zeroes */
|
||||
!put_bits(os, 117, 7))
|
||||
return false;
|
||||
}
|
||||
if (!put_bits(os, 0, 1)) /* presym_1 */
|
||||
return false;
|
||||
if (!put_bits(os, 0, 1)) /* presym_1 */
|
||||
return false;
|
||||
/* Done writing the Huffman codes */
|
||||
|
||||
return put_bits(os, 0, 1); /* litlensym_256 (end-of-block) */
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a DEFLATE stream containing all empty "dynamic Huffman" blocks.
|
||||
*
|
||||
* This is the worst known case currently, being ~100x slower to decompress than
|
||||
* typical data.
|
||||
*/
|
||||
static void
|
||||
generate_empty_dynamic_huffman_blocks(u8 *p, size_t len)
|
||||
{
|
||||
struct output_bitstream os = { .next = p, .end = p + len };
|
||||
|
||||
while (generate_empty_dynamic_huffman_block(&os))
|
||||
;
|
||||
}
|
||||
|
||||
#define NUM_ITERATIONS 100
|
||||
|
||||
static u64
|
||||
do_test_libdeflate(const char *input_type, const u8 *in, size_t in_nbytes,
|
||||
u8 *out, size_t out_nbytes_avail)
|
||||
{
|
||||
struct libdeflate_decompressor *d;
|
||||
enum libdeflate_result res;
|
||||
u64 t;
|
||||
int i;
|
||||
|
||||
d = libdeflate_alloc_decompressor();
|
||||
ASSERT(d != NULL);
|
||||
|
||||
t = timer_ticks();
|
||||
for (i = 0; i < NUM_ITERATIONS; i++) {
|
||||
res = libdeflate_deflate_decompress(d, in, in_nbytes, out,
|
||||
out_nbytes_avail, NULL);
|
||||
ASSERT(res == LIBDEFLATE_BAD_DATA ||
|
||||
res == LIBDEFLATE_INSUFFICIENT_SPACE);
|
||||
}
|
||||
t = timer_ticks() - t;
|
||||
|
||||
printf("[%s, libdeflate]: %"PRIu64" KB/s\n", input_type,
|
||||
timer_KB_per_s((u64)in_nbytes * NUM_ITERATIONS, t));
|
||||
|
||||
libdeflate_free_decompressor(d);
|
||||
return t;
|
||||
}
|
||||
|
||||
static u64
|
||||
do_test_zlib(const char *input_type, const u8 *in, size_t in_nbytes,
|
||||
u8 *out, size_t out_nbytes_avail)
|
||||
{
|
||||
z_stream z;
|
||||
int res;
|
||||
u64 t;
|
||||
int i;
|
||||
|
||||
memset(&z, 0, sizeof(z));
|
||||
res = inflateInit2(&z, -15);
|
||||
ASSERT(res == Z_OK);
|
||||
|
||||
t = timer_ticks();
|
||||
for (i = 0; i < NUM_ITERATIONS; i++) {
|
||||
inflateReset(&z);
|
||||
z.next_in = (void *)in;
|
||||
z.avail_in = in_nbytes;
|
||||
z.next_out = out;
|
||||
z.avail_out = out_nbytes_avail;
|
||||
res = inflate(&z, Z_FINISH);
|
||||
ASSERT(res == Z_BUF_ERROR || res == Z_DATA_ERROR);
|
||||
}
|
||||
t = timer_ticks() - t;
|
||||
|
||||
printf("[%s, zlib ]: %"PRIu64" KB/s\n", input_type,
|
||||
timer_KB_per_s((u64)in_nbytes * NUM_ITERATIONS, t));
|
||||
|
||||
inflateEnd(&z);
|
||||
return t;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test case from https://github.com/ebiggers/libdeflate/issues/33
|
||||
* with the gzip header and footer removed to leave just the DEFLATE stream
|
||||
*/
|
||||
static const u8 orig_repro[3962] =
|
||||
"\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a"
|
||||
"\x6a\x6a\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20"
|
||||
"\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80\x28"
|
||||
"\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11"
|
||||
"\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48"
|
||||
"\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80"
|
||||
"\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80\x28\x00"
|
||||
"\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea"
|
||||
"\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea"
|
||||
"\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48"
|
||||
"\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20"
|
||||
"\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00"
|
||||
"\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11"
|
||||
"\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x63"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92"
|
||||
"\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00"
|
||||
"\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48"
|
||||
"\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20"
|
||||
"\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00"
|
||||
"\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x92\x63\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea"
|
||||
"\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48"
|
||||
"\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11"
|
||||
"\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00"
|
||||
"\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x92\x63\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11"
|
||||
"\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63"
|
||||
"\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea"
|
||||
"\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x92\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a"
|
||||
"\x6a\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80"
|
||||
"\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80\x28\x00"
|
||||
"\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00"
|
||||
"\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x92\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a\x6a"
|
||||
"\x6a\x6a\x6a\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00"
|
||||
"\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80"
|
||||
"\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00"
|
||||
"\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04"
|
||||
"\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20"
|
||||
"\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80\x28"
|
||||
"\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00"
|
||||
"\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04"
|
||||
"\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00"
|
||||
"\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28"
|
||||
"\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00"
|
||||
"\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x63\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04"
|
||||
"\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00"
|
||||
"\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28"
|
||||
"\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x92\x63\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00"
|
||||
"\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04"
|
||||
"\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00"
|
||||
"\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28"
|
||||
"\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x92\x63\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00"
|
||||
"\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92"
|
||||
"\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00"
|
||||
"\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x63\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00"
|
||||
"\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80"
|
||||
"\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00"
|
||||
"\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92"
|
||||
"\x63\x00\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00"
|
||||
"\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04"
|
||||
"\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00\x20"
|
||||
"\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x00\xea\x04\x48\x00\x20\x80\x28"
|
||||
"\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1a\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00"
|
||||
"\xea\x04\x48\x00\x20\x80\x28\x00\x00\x11\x00\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b"
|
||||
"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x92\x63\x00\x04\xea\x48\x00\x20"
|
||||
"\x80\x28\x00\x00\x11\x1b\x1b\x1b\x1b\x92\x63\x00\xea\x04\x48\x00"
|
||||
"\x20\x80\x28\x00\x00\x11\x00\x00\x01\x04\x00\x3f\x00\x00\x00\x00"
|
||||
"\x28\xf7\xff\x00\xff\xff\xff\xff\x00\x00";
|
||||
|
||||
int
|
||||
tmain(int argc, tchar *argv[])
|
||||
{
|
||||
u8 in[4096];
|
||||
u8 out[10000];
|
||||
u64 t, tz;
|
||||
|
||||
program_invocation_name = get_filename(argv[0]);
|
||||
|
||||
/* static huffman case */
|
||||
generate_empty_static_huffman_blocks(in, sizeof(in));
|
||||
t = do_test_libdeflate("static huffman", in, sizeof(in),
|
||||
out, sizeof(out));
|
||||
tz = do_test_zlib("static huffman", in, sizeof(in), out, sizeof(out));
|
||||
/*
|
||||
* libdeflate is faster than zlib in this case, e.g.
|
||||
* [static huffman, libdeflate]: 175243 KB/s
|
||||
* [static huffman, zlib ]: 71331 KB/s
|
||||
*/
|
||||
putchar('\n');
|
||||
ASSERT(t < tz);
|
||||
|
||||
/* dynamic huffman case */
|
||||
generate_empty_dynamic_huffman_blocks(in, sizeof(in));
|
||||
t = do_test_libdeflate("dynamic huffman", in, sizeof(in),
|
||||
out, sizeof(out));
|
||||
tz = do_test_zlib("dynamic huffman", in, sizeof(in), out, sizeof(out));
|
||||
/*
|
||||
* libdeflate is slower than zlib in this case, though not super bad.
|
||||
* [dynamic huffman, libdeflate]: 5197 KB/s
|
||||
* [dynamic huffman, zlib ]: 10206 KB/s
|
||||
* FIXME: make it faster.
|
||||
*/
|
||||
putchar('\n');
|
||||
ASSERT(t < 3 * tz);
|
||||
|
||||
/* original reproducer */
|
||||
t = do_test_libdeflate("original repro", orig_repro, sizeof(orig_repro),
|
||||
out, sizeof(out));
|
||||
tz = do_test_zlib("original repro", orig_repro, sizeof(orig_repro),
|
||||
out, sizeof(out));
|
||||
ASSERT(t < tz);
|
||||
|
||||
return 0;
|
||||
}
|
@ -341,6 +341,10 @@ EOF
|
||||
run_cmd ./benchmark -6 "$TMPFILE"
|
||||
run_cmd ./benchmark -12 "$TMPFILE"
|
||||
fi
|
||||
|
||||
# Check worst-case decompression speed
|
||||
run_cmd make -j$NPROC test_slow_decompression
|
||||
run_cmd ./test_slow_decompression
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
Loading…
x
Reference in New Issue
Block a user